UNPKG

543 kBJavaScriptView Raw
1/** @license React v16.8.0
2 * react-art.development.js
3 *
4 * Copyright (c) Facebook, Inc. and its affiliates.
5 *
6 * This source code is licensed under the MIT license found in the
7 * LICENSE file in the root directory of this source tree.
8 */
9
10'use strict';
11
12(function (global, factory) {
13 typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('react')) :
14 typeof define === 'function' && define.amd ? define(['react'], factory) :
15 (global.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.0';
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// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
151// nor polyfill, then a plain number is used for performance.
152var hasSymbol = typeof Symbol === 'function' && Symbol.for;
153
154var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
155var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
156var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
157var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
158var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
159var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
160var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace;
161
162var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
163var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
164var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
165var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
166var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
167
168var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
169var FAUX_ITERATOR_SYMBOL = '@@iterator';
170
171function getIteratorFn(maybeIterable) {
172 if (maybeIterable === null || typeof maybeIterable !== 'object') {
173 return null;
174 }
175 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
176 if (typeof maybeIterator === 'function') {
177 return maybeIterator;
178 }
179 return null;
180}
181
182var Pending = 0;
183var Resolved = 1;
184var Rejected = 2;
185
186function refineResolvedLazyComponent(lazyComponent) {
187 return lazyComponent._status === Resolved ? lazyComponent._result : null;
188}
189
190function getWrappedName(outerType, innerType, wrapperName) {
191 var functionName = innerType.displayName || innerType.name || '';
192 return outerType.displayName || (functionName !== '' ? wrapperName + '(' + functionName + ')' : wrapperName);
193}
194
195function getComponentName(type) {
196 if (type == null) {
197 // Host root, text node or just invalid type.
198 return null;
199 }
200 {
201 if (typeof type.tag === 'number') {
202 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
203 }
204 }
205 if (typeof type === 'function') {
206 return type.displayName || type.name || null;
207 }
208 if (typeof type === 'string') {
209 return type;
210 }
211 switch (type) {
212 case REACT_CONCURRENT_MODE_TYPE:
213 return 'ConcurrentMode';
214 case REACT_FRAGMENT_TYPE:
215 return 'Fragment';
216 case REACT_PORTAL_TYPE:
217 return 'Portal';
218 case REACT_PROFILER_TYPE:
219 return 'Profiler';
220 case REACT_STRICT_MODE_TYPE:
221 return 'StrictMode';
222 case REACT_SUSPENSE_TYPE:
223 return 'Suspense';
224 }
225 if (typeof type === 'object') {
226 switch (type.$$typeof) {
227 case REACT_CONTEXT_TYPE:
228 return 'Context.Consumer';
229 case REACT_PROVIDER_TYPE:
230 return 'Context.Provider';
231 case REACT_FORWARD_REF_TYPE:
232 return getWrappedName(type, type.render, 'ForwardRef');
233 case REACT_MEMO_TYPE:
234 return getComponentName(type.type);
235 case REACT_LAZY_TYPE:
236 {
237 var thenable = type;
238 var resolvedThenable = refineResolvedLazyComponent(thenable);
239 if (resolvedThenable) {
240 return getComponentName(resolvedThenable);
241 }
242 }
243 }
244 }
245 return null;
246}
247
248var FunctionComponent = 0;
249var ClassComponent = 1;
250var IndeterminateComponent = 2; // Before we know whether it is function or class
251var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
252var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
253var HostComponent = 5;
254var HostText = 6;
255var Fragment = 7;
256var Mode = 8;
257var ContextConsumer = 9;
258var ContextProvider = 10;
259var ForwardRef = 11;
260var Profiler = 12;
261var SuspenseComponent = 13;
262var MemoComponent = 14;
263var SimpleMemoComponent = 15;
264var LazyComponent = 16;
265var IncompleteClassComponent = 17;
266
267// Don't change these two values. They're used by React Dev Tools.
268var NoEffect = /* */0;
269var PerformedWork = /* */1;
270
271// You can change the rest (and add more).
272var Placement = /* */2;
273var Update = /* */4;
274var PlacementAndUpdate = /* */6;
275var Deletion = /* */8;
276var ContentReset = /* */16;
277var Callback = /* */32;
278var DidCapture = /* */64;
279var Ref = /* */128;
280var Snapshot = /* */256;
281var Passive = /* */512;
282
283// Passive & Update & Callback & Ref & Snapshot
284var LifecycleEffectMask = /* */932;
285
286// Union of all host effects
287var HostEffectMask = /* */1023;
288
289var Incomplete = /* */1024;
290var ShouldCapture = /* */2048;
291
292var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
293
294var MOUNTING = 1;
295var MOUNTED = 2;
296var UNMOUNTED = 3;
297
298function isFiberMountedImpl(fiber) {
299 var node = fiber;
300 if (!fiber.alternate) {
301 // If there is no alternate, this might be a new tree that isn't inserted
302 // yet. If it is, then it will have a pending insertion effect on it.
303 if ((node.effectTag & Placement) !== NoEffect) {
304 return MOUNTING;
305 }
306 while (node.return) {
307 node = node.return;
308 if ((node.effectTag & Placement) !== NoEffect) {
309 return MOUNTING;
310 }
311 }
312 } else {
313 while (node.return) {
314 node = node.return;
315 }
316 }
317 if (node.tag === HostRoot) {
318 // TODO: Check if this was a nested HostRoot when used with
319 // renderContainerIntoSubtree.
320 return MOUNTED;
321 }
322 // If we didn't hit the root, that means that we're in an disconnected tree
323 // that has been unmounted.
324 return UNMOUNTED;
325}
326
327function isFiberMounted(fiber) {
328 return isFiberMountedImpl(fiber) === MOUNTED;
329}
330
331function isMounted(component) {
332 {
333 var owner = ReactCurrentOwner.current;
334 if (owner !== null && owner.tag === ClassComponent) {
335 var ownerFiber = owner;
336 var instance = ownerFiber.stateNode;
337 !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;
338 instance._warnedAboutRefsInRender = true;
339 }
340 }
341
342 var fiber = get(component);
343 if (!fiber) {
344 return false;
345 }
346 return isFiberMountedImpl(fiber) === MOUNTED;
347}
348
349function assertIsMounted(fiber) {
350 !(isFiberMountedImpl(fiber) === MOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
351}
352
353function findCurrentFiberUsingSlowPath(fiber) {
354 var alternate = fiber.alternate;
355 if (!alternate) {
356 // If there is no alternate, then we only need to check if it is mounted.
357 var state = isFiberMountedImpl(fiber);
358 !(state !== UNMOUNTED) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
359 if (state === MOUNTING) {
360 return null;
361 }
362 return fiber;
363 }
364 // If we have two possible branches, we'll walk backwards up to the root
365 // to see what path the root points to. On the way we may hit one of the
366 // special cases and we'll deal with them.
367 var a = fiber;
368 var b = alternate;
369 while (true) {
370 var parentA = a.return;
371 var parentB = parentA ? parentA.alternate : null;
372 if (!parentA || !parentB) {
373 // We're at the root.
374 break;
375 }
376
377 // If both copies of the parent fiber point to the same child, we can
378 // assume that the child is current. This happens when we bailout on low
379 // priority: the bailed out fiber's child reuses the current child.
380 if (parentA.child === parentB.child) {
381 var child = parentA.child;
382 while (child) {
383 if (child === a) {
384 // We've determined that A is the current branch.
385 assertIsMounted(parentA);
386 return fiber;
387 }
388 if (child === b) {
389 // We've determined that B is the current branch.
390 assertIsMounted(parentA);
391 return alternate;
392 }
393 child = child.sibling;
394 }
395 // We should never have an alternate for any mounting node. So the only
396 // way this could possibly happen is if this was unmounted, if at all.
397 invariant(false, 'Unable to find node on an unmounted component.');
398 }
399
400 if (a.return !== b.return) {
401 // The return pointer of A and the return pointer of B point to different
402 // fibers. We assume that return pointers never criss-cross, so A must
403 // belong to the child set of A.return, and B must belong to the child
404 // set of B.return.
405 a = parentA;
406 b = parentB;
407 } else {
408 // The return pointers point to the same fiber. We'll have to use the
409 // default, slow path: scan the child sets of each parent alternate to see
410 // which child belongs to which set.
411 //
412 // Search parent A's child set
413 var didFindChild = false;
414 var _child = parentA.child;
415 while (_child) {
416 if (_child === a) {
417 didFindChild = true;
418 a = parentA;
419 b = parentB;
420 break;
421 }
422 if (_child === b) {
423 didFindChild = true;
424 b = parentA;
425 a = parentB;
426 break;
427 }
428 _child = _child.sibling;
429 }
430 if (!didFindChild) {
431 // Search parent B's child set
432 _child = parentB.child;
433 while (_child) {
434 if (_child === a) {
435 didFindChild = true;
436 a = parentB;
437 b = parentA;
438 break;
439 }
440 if (_child === b) {
441 didFindChild = true;
442 b = parentB;
443 a = parentA;
444 break;
445 }
446 _child = _child.sibling;
447 }
448 !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;
449 }
450 }
451
452 !(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;
453 }
454 // If the root is not a host container, we're in a disconnected tree. I.e.
455 // unmounted.
456 !(a.tag === HostRoot) ? invariant(false, 'Unable to find node on an unmounted component.') : void 0;
457 if (a.stateNode.current === a) {
458 // We've determined that A is the current branch.
459 return fiber;
460 }
461 // Otherwise B has to be current branch.
462 return alternate;
463}
464
465function findCurrentHostFiber(parent) {
466 var currentParent = findCurrentFiberUsingSlowPath(parent);
467 if (!currentParent) {
468 return null;
469 }
470
471 // Next we'll drill down this component to find the first HostComponent/Text.
472 var node = currentParent;
473 while (true) {
474 if (node.tag === HostComponent || node.tag === HostText) {
475 return node;
476 } else if (node.child) {
477 node.child.return = node;
478 node = node.child;
479 continue;
480 }
481 if (node === currentParent) {
482 return null;
483 }
484 while (!node.sibling) {
485 if (!node.return || node.return === currentParent) {
486 return null;
487 }
488 node = node.return;
489 }
490 node.sibling.return = node.return;
491 node = node.sibling;
492 }
493 // Flow needs the return null here, but ESLint complains about it.
494 // eslint-disable-next-line no-unreachable
495 return null;
496}
497
498var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
499
500var _ReactInternals$Sched = ReactInternals$1.Scheduler;
501var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
502var unstable_now = _ReactInternals$Sched.unstable_now;
503var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
504var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
505var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
506var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
507var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
508
509var _class = function(mixins){
510 var proto = {};
511 for (var i = 0, l = arguments.length; i < l; i++){
512 var mixin = arguments[i];
513 if (typeof mixin == 'function') mixin = mixin.prototype;
514 for (var key in mixin) proto[key] = mixin[key];
515 }
516 if (!proto.initialize) proto.initialize = function(){};
517 proto.constructor = function(a,b,c,d,e,f,g,h){
518 return new proto.initialize(a,b,c,d,e,f,g,h);
519 };
520 proto.constructor.prototype = proto.initialize.prototype = proto;
521 return proto.constructor;
522};
523
524function Transform(xx, yx, xy, yy, x, y){
525 if (xx && typeof xx == 'object'){
526 yx = xx.yx; yy = xx.yy; y = xx.y;
527 xy = xx.xy; x = xx.x; xx = xx.xx;
528 }
529 this.xx = xx == null ? 1 : xx;
530 this.yx = yx || 0;
531 this.xy = xy || 0;
532 this.yy = yy == null ? 1 : yy;
533 this.x = (x == null ? this.x : x) || 0;
534 this.y = (y == null ? this.y : y) || 0;
535 this._transform();
536 return this;
537}
538
539var transform = _class({
540
541 initialize: Transform,
542
543 _transform: function(){},
544
545 xx: 1, yx: 0, x: 0,
546 xy: 0, yy: 1, y: 0,
547
548 transform: function(xx, yx, xy, yy, x, y){
549 var m = this;
550 if (xx && typeof xx == 'object'){
551 yx = xx.yx; yy = xx.yy; y = xx.y;
552 xy = xx.xy; x = xx.x; xx = xx.xx;
553 }
554 if (!x) x = 0;
555 if (!y) y = 0;
556 return this.transformTo(
557 m.xx * xx + m.xy * yx,
558 m.yx * xx + m.yy * yx,
559 m.xx * xy + m.xy * yy,
560 m.yx * xy + m.yy * yy,
561 m.xx * x + m.xy * y + m.x,
562 m.yx * x + m.yy * y + m.y
563 );
564 },
565
566 transformTo: Transform,
567
568 translate: function(x, y){
569 return this.transform(1, 0, 0, 1, x, y);
570 },
571
572 move: function(x, y){
573 this.x += x || 0;
574 this.y += y || 0;
575 this._transform();
576 return this;
577 },
578
579 scale: function(x, y){
580 if (y == null) y = x;
581 return this.transform(x, 0, 0, y, 0, 0);
582 },
583
584 rotate: function(deg, x, y){
585 if (x == null || y == null){
586 x = (this.left || 0) + (this.width || 0) / 2;
587 y = (this.top || 0) + (this.height || 0) / 2;
588 }
589
590 var rad = deg * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
591
592 this.transform(1, 0, 0, 1, x, y);
593 var m = this;
594
595 return this.transformTo(
596 cos * m.xx - sin * m.yx,
597 sin * m.xx + cos * m.yx,
598 cos * m.xy - sin * m.yy,
599 sin * m.xy + cos * m.yy,
600 m.x,
601 m.y
602 ).transform(1, 0, 0, 1, -x, -y);
603 },
604
605 moveTo: function(x, y){
606 var m = this;
607 return this.transformTo(m.xx, m.yx, m.xy, m.yy, x, y);
608 },
609
610 rotateTo: function(deg, x, y){
611 var m = this;
612 var flip = m.yx / m.xx > m.yy / m.xy ? -1 : 1;
613 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = -flip;
614 return this.rotate(deg - Math.atan2(flip * m.yx, flip * m.xx) * 180 / Math.PI, x, y);
615 },
616
617 scaleTo: function(x, y){
618 // Normalize
619 var m = this;
620
621 var h = Math.sqrt(m.xx * m.xx + m.yx * m.yx);
622 m.xx /= h; m.yx /= h;
623
624 h = Math.sqrt(m.yy * m.yy + m.xy * m.xy);
625 m.yy /= h; m.xy /= h;
626
627 return this.scale(x, y);
628 },
629
630 resizeTo: function(width, height){
631 var w = this.width, h = this.height;
632 if (!w || !h) return this;
633 return this.scaleTo(width / w, height / h);
634 },
635
636 /*
637 inverse: function(){
638 var a = this.xx, b = this.yx,
639 c = this.xy, d = this.yy,
640 e = this.x, f = this.y;
641 if (a * d - b * c == 0) return null;
642 return new Transform(
643 d/(a * d-b * c), b/(b * c-a * d),
644 c/(b * c-a * d), a/(a * d-b * c),
645 (d * e-c * f)/(b * c-a * d), (b * e-a * f)/(a * d-b * c)
646 );
647 },
648 */
649
650 inversePoint: function(x, y){
651 var a = this.xx, b = this.yx,
652 c = this.xy, d = this.yy,
653 e = this.x, f = this.y;
654 var det = b * c - a * d;
655 if (det == 0) return null;
656 return {
657 x: (d * (e - x) + c * (y - f)) / det,
658 y: (a * (f - y) + b * (x - e)) / det
659 };
660 },
661
662 point: function(x, y){
663 var m = this;
664 return {
665 x: m.xx * x + m.xy * y + m.x,
666 y: m.yx * x + m.yy * y + m.y
667 };
668 }
669
670});
671
672var commonjsGlobal = typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
673
674
675
676
677
678function createCommonjsModule(fn, module) {
679 return module = { exports: {} }, fn(module, module.exports), module.exports;
680}
681
682var current = createCommonjsModule(function (module, exports) {
683function warning(){
684 throw new Error('You must require a mode before requiring anything else.');
685}
686
687exports.Surface = warning;
688exports.Path = warning;
689exports.Shape = warning;
690exports.Group = warning;
691exports.ClippingRectangle = warning;
692exports.Text = warning;
693
694exports.setCurrent = function(mode){
695 for (var key in mode){
696 exports[key] = mode[key];
697 }
698};
699});
700
701var current_1 = current.Surface;
702var current_2 = current.Path;
703var current_3 = current.Shape;
704var current_4 = current.Group;
705var current_5 = current.ClippingRectangle;
706var current_6 = current.Text;
707var current_7 = current.setCurrent;
708
709var TYPES = {
710 CLIPPING_RECTANGLE: 'ClippingRectangle',
711 GROUP: 'Group',
712 SHAPE: 'Shape',
713 TEXT: 'Text'
714};
715
716var EVENT_TYPES = {
717 onClick: 'click',
718 onMouseMove: 'mousemove',
719 onMouseOver: 'mouseover',
720 onMouseOut: 'mouseout',
721 onMouseUp: 'mouseup',
722 onMouseDown: 'mousedown'
723};
724
725function childrenAsString(children) {
726 if (!children) {
727 return '';
728 } else if (typeof children === 'string') {
729 return children;
730 } else if (children.length) {
731 return children.join('');
732 } else {
733 return '';
734 }
735}
736
737// Renderers that don't support persistence
738// can re-export everything from this module.
739
740function shim() {
741 invariant(false, 'The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.');
742}
743
744// Persistence (when unsupported)
745var supportsPersistence = false;
746var cloneInstance = shim;
747var createContainerChildSet = shim;
748var appendChildToContainerChildSet = shim;
749var finalizeContainerChildren = shim;
750var replaceContainerChildren = shim;
751var cloneHiddenInstance = shim;
752var cloneUnhiddenInstance = shim;
753var createHiddenTextInstance = shim;
754
755// Renderers that don't support hydration
756// can re-export everything from this module.
757
758function shim$1() {
759 invariant(false, 'The current renderer does not support hydration. This error is likely caused by a bug in React. Please file an issue.');
760}
761
762// Hydration (when unsupported)
763var supportsHydration = false;
764var canHydrateInstance = shim$1;
765var canHydrateTextInstance = shim$1;
766var getNextHydratableSibling = shim$1;
767var getFirstHydratableChild = shim$1;
768var hydrateInstance = shim$1;
769var hydrateTextInstance = shim$1;
770var didNotMatchHydratedContainerTextInstance = shim$1;
771var didNotMatchHydratedTextInstance = shim$1;
772var didNotHydrateContainerInstance = shim$1;
773var didNotHydrateInstance = shim$1;
774var didNotFindHydratableContainerInstance = shim$1;
775var didNotFindHydratableContainerTextInstance = shim$1;
776var didNotFindHydratableInstance = shim$1;
777var didNotFindHydratableTextInstance = shim$1;
778
779var pooledTransform = new transform();
780
781var NO_CONTEXT = {};
782var UPDATE_SIGNAL = {};
783{
784 Object.freeze(NO_CONTEXT);
785 Object.freeze(UPDATE_SIGNAL);
786}
787
788/** Helper Methods */
789
790function addEventListeners(instance, type, listener) {
791 // We need to explicitly unregister before unmount.
792 // For this reason we need to track subscriptions.
793 if (!instance._listeners) {
794 instance._listeners = {};
795 instance._subscriptions = {};
796 }
797
798 instance._listeners[type] = listener;
799
800 if (listener) {
801 if (!instance._subscriptions[type]) {
802 instance._subscriptions[type] = instance.subscribe(type, createEventHandler(instance), instance);
803 }
804 } else {
805 if (instance._subscriptions[type]) {
806 instance._subscriptions[type]();
807 delete instance._subscriptions[type];
808 }
809 }
810}
811
812function createEventHandler(instance) {
813 return function handleEvent(event) {
814 var listener = instance._listeners[event.type];
815
816 if (!listener) {
817 // Noop
818 } else if (typeof listener === 'function') {
819 listener.call(instance, event);
820 } else if (listener.handleEvent) {
821 listener.handleEvent(event);
822 }
823 };
824}
825
826function destroyEventListeners(instance) {
827 if (instance._subscriptions) {
828 for (var type in instance._subscriptions) {
829 instance._subscriptions[type]();
830 }
831 }
832
833 instance._subscriptions = null;
834 instance._listeners = null;
835}
836
837function getScaleX(props) {
838 if (props.scaleX != null) {
839 return props.scaleX;
840 } else if (props.scale != null) {
841 return props.scale;
842 } else {
843 return 1;
844 }
845}
846
847function getScaleY(props) {
848 if (props.scaleY != null) {
849 return props.scaleY;
850 } else if (props.scale != null) {
851 return props.scale;
852 } else {
853 return 1;
854 }
855}
856
857function isSameFont(oldFont, newFont) {
858 if (oldFont === newFont) {
859 return true;
860 } else if (typeof newFont === 'string' || typeof oldFont === 'string') {
861 return false;
862 } else {
863 return newFont.fontSize === oldFont.fontSize && newFont.fontStyle === oldFont.fontStyle && newFont.fontVariant === oldFont.fontVariant && newFont.fontWeight === oldFont.fontWeight && newFont.fontFamily === oldFont.fontFamily;
864 }
865}
866
867/** Render Methods */
868
869function applyClippingRectangleProps(instance, props) {
870 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
871
872 applyNodeProps(instance, props, prevProps);
873
874 instance.width = props.width;
875 instance.height = props.height;
876}
877
878function applyGroupProps(instance, props) {
879 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
880
881 applyNodeProps(instance, props, prevProps);
882
883 instance.width = props.width;
884 instance.height = props.height;
885}
886
887function applyNodeProps(instance, props) {
888 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
889
890 var scaleX = getScaleX(props);
891 var scaleY = getScaleY(props);
892
893 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);
894
895 if (props.transform != null) {
896 pooledTransform.transform(props.transform);
897 }
898
899 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) {
900 instance.transformTo(pooledTransform);
901 }
902
903 if (props.cursor !== prevProps.cursor || props.title !== prevProps.title) {
904 instance.indicate(props.cursor, props.title);
905 }
906
907 if (instance.blend && props.opacity !== prevProps.opacity) {
908 instance.blend(props.opacity == null ? 1 : props.opacity);
909 }
910
911 if (props.visible !== prevProps.visible) {
912 if (props.visible == null || props.visible) {
913 instance.show();
914 } else {
915 instance.hide();
916 }
917 }
918
919 for (var type in EVENT_TYPES) {
920 addEventListeners(instance, EVENT_TYPES[type], props[type]);
921 }
922}
923
924function applyRenderableNodeProps(instance, props) {
925 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
926
927 applyNodeProps(instance, props, prevProps);
928
929 if (prevProps.fill !== props.fill) {
930 if (props.fill && props.fill.applyFill) {
931 props.fill.applyFill(instance);
932 } else {
933 instance.fill(props.fill);
934 }
935 }
936 if (prevProps.stroke !== props.stroke || prevProps.strokeWidth !== props.strokeWidth || prevProps.strokeCap !== props.strokeCap || prevProps.strokeJoin !== props.strokeJoin ||
937 // TODO: Consider deep check of stokeDash; may benefit VML in IE.
938 prevProps.strokeDash !== props.strokeDash) {
939 instance.stroke(props.stroke, props.strokeWidth, props.strokeCap, props.strokeJoin, props.strokeDash);
940 }
941}
942
943function applyShapeProps(instance, props) {
944 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
945
946 applyRenderableNodeProps(instance, props, prevProps);
947
948 var path = props.d || childrenAsString(props.children);
949
950 var prevDelta = instance._prevDelta;
951 var prevPath = instance._prevPath;
952
953 if (path !== prevPath || path.delta !== prevDelta || prevProps.height !== props.height || prevProps.width !== props.width) {
954 instance.draw(path, props.width, props.height);
955
956 instance._prevDelta = path.delta;
957 instance._prevPath = path;
958 }
959}
960
961function applyTextProps(instance, props) {
962 var prevProps = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
963
964 applyRenderableNodeProps(instance, props, prevProps);
965
966 var string = props.children;
967
968 if (instance._currentString !== string || !isSameFont(props.font, prevProps.font) || props.alignment !== prevProps.alignment || props.path !== prevProps.path) {
969 instance.draw(string, props.font, props.alignment, props.path);
970
971 instance._currentString = string;
972 }
973}
974
975function appendInitialChild(parentInstance, child) {
976 if (typeof child === 'string') {
977 // Noop for string children of Text (eg <Text>{'foo'}{'bar'}</Text>)
978 invariant(false, 'Text children should already be flattened.');
979 return;
980 }
981
982 child.inject(parentInstance);
983}
984
985function createInstance(type, props, internalInstanceHandle) {
986 var instance = void 0;
987
988 switch (type) {
989 case TYPES.CLIPPING_RECTANGLE:
990 instance = current.ClippingRectangle();
991 instance._applyProps = applyClippingRectangleProps;
992 break;
993 case TYPES.GROUP:
994 instance = current.Group();
995 instance._applyProps = applyGroupProps;
996 break;
997 case TYPES.SHAPE:
998 instance = current.Shape();
999 instance._applyProps = applyShapeProps;
1000 break;
1001 case TYPES.TEXT:
1002 instance = current.Text(props.children, props.font, props.alignment, props.path);
1003 instance._applyProps = applyTextProps;
1004 break;
1005 }
1006
1007 !instance ? invariant(false, 'ReactART does not support the type "%s"', type) : void 0;
1008
1009 instance._applyProps(instance, props);
1010
1011 return instance;
1012}
1013
1014function createTextInstance(text, rootContainerInstance, internalInstanceHandle) {
1015 return text;
1016}
1017
1018function finalizeInitialChildren(domElement, type, props) {
1019 return false;
1020}
1021
1022function getPublicInstance(instance) {
1023 return instance;
1024}
1025
1026function prepareForCommit() {
1027 // Noop
1028}
1029
1030function prepareUpdate(domElement, type, oldProps, newProps) {
1031 return UPDATE_SIGNAL;
1032}
1033
1034function resetAfterCommit() {
1035 // Noop
1036}
1037
1038function resetTextContent(domElement) {
1039 // Noop
1040}
1041
1042function shouldDeprioritizeSubtree(type, props) {
1043 return false;
1044}
1045
1046function getRootHostContext() {
1047 return NO_CONTEXT;
1048}
1049
1050function getChildHostContext() {
1051 return NO_CONTEXT;
1052}
1053
1054var scheduleTimeout = setTimeout;
1055var cancelTimeout = clearTimeout;
1056var noTimeout = -1;
1057var schedulePassiveEffects = unstable_scheduleCallback;
1058var cancelPassiveEffects = unstable_cancelCallback;
1059
1060function shouldSetTextContent(type, props) {
1061 return typeof props.children === 'string' || typeof props.children === 'number';
1062}
1063
1064// The ART renderer is secondary to the React DOM renderer.
1065var isPrimaryRenderer = false;
1066
1067var supportsMutation = true;
1068
1069function appendChild(parentInstance, child) {
1070 if (child.parentNode === parentInstance) {
1071 child.eject();
1072 }
1073 child.inject(parentInstance);
1074}
1075
1076function appendChildToContainer(parentInstance, child) {
1077 if (child.parentNode === parentInstance) {
1078 child.eject();
1079 }
1080 child.inject(parentInstance);
1081}
1082
1083function insertBefore(parentInstance, child, beforeChild) {
1084 !(child !== beforeChild) ? invariant(false, 'ReactART: Can not insert node before itself') : void 0;
1085 child.injectBefore(beforeChild);
1086}
1087
1088function insertInContainerBefore(parentInstance, child, beforeChild) {
1089 !(child !== beforeChild) ? invariant(false, 'ReactART: Can not insert node before itself') : void 0;
1090 child.injectBefore(beforeChild);
1091}
1092
1093function removeChild(parentInstance, child) {
1094 destroyEventListeners(child);
1095 child.eject();
1096}
1097
1098function removeChildFromContainer(parentInstance, child) {
1099 destroyEventListeners(child);
1100 child.eject();
1101}
1102
1103
1104
1105
1106
1107function commitUpdate(instance, updatePayload, type, oldProps, newProps) {
1108 instance._applyProps(instance, newProps, oldProps);
1109}
1110
1111function hideInstance(instance) {
1112 instance.hide();
1113}
1114
1115
1116
1117function unhideInstance(instance, props) {
1118 if (props.visible == null || props.visible) {
1119 instance.show();
1120 }
1121}
1122
1123function unhideTextInstance(textInstance, text) {
1124 // Noop
1125}
1126
1127/**
1128 * Copyright (c) 2013-present, Facebook, Inc.
1129 *
1130 * This source code is licensed under the MIT license found in the
1131 * LICENSE file in the root directory of this source tree.
1132 */
1133
1134
1135
1136var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
1137
1138var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
1139
1140/**
1141 * Copyright (c) 2013-present, Facebook, Inc.
1142 *
1143 * This source code is licensed under the MIT license found in the
1144 * LICENSE file in the root directory of this source tree.
1145 */
1146
1147
1148
1149var printWarning = function() {};
1150
1151{
1152 var ReactPropTypesSecret = ReactPropTypesSecret_1;
1153 var loggedTypeFailures = {};
1154
1155 printWarning = function(text) {
1156 var message = 'Warning: ' + text;
1157 if (typeof console !== 'undefined') {
1158 console.error(message);
1159 }
1160 try {
1161 // --- Welcome to debugging React ---
1162 // This error was thrown as a convenience so that you can use this stack
1163 // to find the callsite that caused this warning to fire.
1164 throw new Error(message);
1165 } catch (x) {}
1166 };
1167}
1168
1169/**
1170 * Assert that the values match with the type specs.
1171 * Error messages are memorized and will only be shown once.
1172 *
1173 * @param {object} typeSpecs Map of name to a ReactPropType
1174 * @param {object} values Runtime values that need to be type-checked
1175 * @param {string} location e.g. "prop", "context", "child context"
1176 * @param {string} componentName Name of the component for error messages.
1177 * @param {?Function} getStack Returns the component stack.
1178 * @private
1179 */
1180function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
1181 {
1182 for (var typeSpecName in typeSpecs) {
1183 if (typeSpecs.hasOwnProperty(typeSpecName)) {
1184 var error;
1185 // Prop type validation may throw. In case they do, we don't want to
1186 // fail the render phase where it didn't fail before. So we log it.
1187 // After these have been cleaned up, we'll let them throw.
1188 try {
1189 // This is intentionally an invariant that gets caught. It's the same
1190 // behavior as without this statement except with a better message.
1191 if (typeof typeSpecs[typeSpecName] !== 'function') {
1192 var err = Error(
1193 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
1194 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
1195 );
1196 err.name = 'Invariant Violation';
1197 throw err;
1198 }
1199 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
1200 } catch (ex) {
1201 error = ex;
1202 }
1203 if (error && !(error instanceof Error)) {
1204 printWarning(
1205 (componentName || 'React class') + ': type specification of ' +
1206 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
1207 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
1208 'You may have forgotten to pass an argument to the type checker ' +
1209 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
1210 'shape all require an argument).'
1211 );
1212
1213 }
1214 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
1215 // Only monitor this failure once because there tends to be a lot of the
1216 // same error.
1217 loggedTypeFailures[error.message] = true;
1218
1219 var stack = getStack ? getStack() : '';
1220
1221 printWarning(
1222 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
1223 );
1224 }
1225 }
1226 }
1227 }
1228}
1229
1230var checkPropTypes_1 = checkPropTypes;
1231
1232var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
1233
1234var describeComponentFrame = function (name, source, ownerName) {
1235 var sourceInfo = '';
1236 if (source) {
1237 var path = source.fileName;
1238 var fileName = path.replace(BEFORE_SLASH_RE, '');
1239 {
1240 // In DEV, include code for a common special case:
1241 // prefer "folder/index.js" instead of just "index.js".
1242 if (/^index\./.test(fileName)) {
1243 var match = path.match(BEFORE_SLASH_RE);
1244 if (match) {
1245 var pathBeforeSlash = match[1];
1246 if (pathBeforeSlash) {
1247 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
1248 fileName = folderName + '/' + fileName;
1249 }
1250 }
1251 }
1252 }
1253 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
1254 } else if (ownerName) {
1255 sourceInfo = ' (created by ' + ownerName + ')';
1256 }
1257 return '\n in ' + (name || 'Unknown') + sourceInfo;
1258};
1259
1260var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1261
1262function describeFiber(fiber) {
1263 switch (fiber.tag) {
1264 case HostRoot:
1265 case HostPortal:
1266 case HostText:
1267 case Fragment:
1268 case ContextProvider:
1269 case ContextConsumer:
1270 return '';
1271 default:
1272 var owner = fiber._debugOwner;
1273 var source = fiber._debugSource;
1274 var name = getComponentName(fiber.type);
1275 var ownerName = null;
1276 if (owner) {
1277 ownerName = getComponentName(owner.type);
1278 }
1279 return describeComponentFrame(name, source, ownerName);
1280 }
1281}
1282
1283function getStackByFiberInDevAndProd(workInProgress) {
1284 var info = '';
1285 var node = workInProgress;
1286 do {
1287 info += describeFiber(node);
1288 node = node.return;
1289 } while (node);
1290 return info;
1291}
1292
1293var current$1 = null;
1294var phase = null;
1295
1296function getCurrentFiberOwnerNameInDevOrNull() {
1297 {
1298 if (current$1 === null) {
1299 return null;
1300 }
1301 var owner = current$1._debugOwner;
1302 if (owner !== null && typeof owner !== 'undefined') {
1303 return getComponentName(owner.type);
1304 }
1305 }
1306 return null;
1307}
1308
1309function getCurrentFiberStackInDev() {
1310 {
1311 if (current$1 === null) {
1312 return '';
1313 }
1314 // Safe because if current fiber exists, we are reconciling,
1315 // and it is guaranteed to be the work-in-progress version.
1316 return getStackByFiberInDevAndProd(current$1);
1317 }
1318 return '';
1319}
1320
1321function resetCurrentFiber() {
1322 {
1323 ReactDebugCurrentFrame.getCurrentStack = null;
1324 current$1 = null;
1325 phase = null;
1326 }
1327}
1328
1329function setCurrentFiber(fiber) {
1330 {
1331 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1332 current$1 = fiber;
1333 phase = null;
1334 }
1335}
1336
1337function setCurrentPhase(lifeCyclePhase) {
1338 {
1339 phase = lifeCyclePhase;
1340 }
1341}
1342
1343var enableUserTimingAPI = true;
1344
1345// Helps identify side effects in begin-phase lifecycle hooks and setState reducers:
1346var debugRenderPhaseSideEffects = false;
1347
1348// In some cases, StrictMode should also double-render lifecycles.
1349// This can be confusing for tests though,
1350// And it can be bad for performance in production.
1351// This feature flag can be used to control the behavior:
1352var debugRenderPhaseSideEffectsForStrictMode = true;
1353
1354// To preserve the "Pause on caught exceptions" behavior of the debugger, we
1355// replay the begin phase of a failed component inside invokeGuardedCallback.
1356var replayFailedUnitOfWorkWithInvokeGuardedCallback = true;
1357
1358// Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
1359var warnAboutDeprecatedLifecycles = false;
1360
1361// Gather advanced timing metrics for Profiler subtrees.
1362var enableProfilerTimer = true;
1363
1364// Trace which interactions trigger each commit.
1365var enableSchedulerTracing = true;
1366
1367// Only used in www builds.
1368 // TODO: true? Here it might just be false.
1369
1370// Only used in www builds.
1371
1372
1373// Only used in www builds.
1374
1375
1376// React Fire: prevent the value and checked attributes from syncing
1377// with their related DOM properties
1378
1379
1380// These APIs will no longer be "unstable" in the upcoming 16.7 release,
1381// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
1382
1383// Prefix measurements so that it's possible to filter them.
1384// Longer prefixes are hard to read in DevTools.
1385var reactEmoji = '\u269B';
1386var warningEmoji = '\u26D4';
1387var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function';
1388
1389// Keep track of current fiber so that we know the path to unwind on pause.
1390// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
1391var currentFiber = null;
1392// If we're in the middle of user code, which fiber and method is it?
1393// Reusing `currentFiber` would be confusing for this because user code fiber
1394// can change during commit phase too, but we don't need to unwind it (since
1395// lifecycles in the commit phase don't resemble a tree).
1396var currentPhase = null;
1397var currentPhaseFiber = null;
1398// Did lifecycle hook schedule an update? This is often a performance problem,
1399// so we will keep track of it, and include it in the report.
1400// Track commits caused by cascading updates.
1401var isCommitting = false;
1402var hasScheduledUpdateInCurrentCommit = false;
1403var hasScheduledUpdateInCurrentPhase = false;
1404var commitCountInCurrentWorkLoop = 0;
1405var effectCountInCurrentCommit = 0;
1406var isWaitingForCallback = false;
1407// During commits, we only show a measurement once per method name
1408// to avoid stretch the commit phase with measurement overhead.
1409var labelsInCurrentCommit = new Set();
1410
1411var formatMarkName = function (markName) {
1412 return reactEmoji + ' ' + markName;
1413};
1414
1415var formatLabel = function (label, warning) {
1416 var prefix = warning ? warningEmoji + ' ' : reactEmoji + ' ';
1417 var suffix = warning ? ' Warning: ' + warning : '';
1418 return '' + prefix + label + suffix;
1419};
1420
1421var beginMark = function (markName) {
1422 performance.mark(formatMarkName(markName));
1423};
1424
1425var clearMark = function (markName) {
1426 performance.clearMarks(formatMarkName(markName));
1427};
1428
1429var endMark = function (label, markName, warning) {
1430 var formattedMarkName = formatMarkName(markName);
1431 var formattedLabel = formatLabel(label, warning);
1432 try {
1433 performance.measure(formattedLabel, formattedMarkName);
1434 } catch (err) {}
1435 // If previous mark was missing for some reason, this will throw.
1436 // This could only happen if React crashed in an unexpected place earlier.
1437 // Don't pile on with more errors.
1438
1439 // Clear marks immediately to avoid growing buffer.
1440 performance.clearMarks(formattedMarkName);
1441 performance.clearMeasures(formattedLabel);
1442};
1443
1444var getFiberMarkName = function (label, debugID) {
1445 return label + ' (#' + debugID + ')';
1446};
1447
1448var getFiberLabel = function (componentName, isMounted, phase) {
1449 if (phase === null) {
1450 // These are composite component total time measurements.
1451 return componentName + ' [' + (isMounted ? 'update' : 'mount') + ']';
1452 } else {
1453 // Composite component methods.
1454 return componentName + '.' + phase;
1455 }
1456};
1457
1458var beginFiberMark = function (fiber, phase) {
1459 var componentName = getComponentName(fiber.type) || 'Unknown';
1460 var debugID = fiber._debugID;
1461 var isMounted = fiber.alternate !== null;
1462 var label = getFiberLabel(componentName, isMounted, phase);
1463
1464 if (isCommitting && labelsInCurrentCommit.has(label)) {
1465 // During the commit phase, we don't show duplicate labels because
1466 // there is a fixed overhead for every measurement, and we don't
1467 // want to stretch the commit phase beyond necessary.
1468 return false;
1469 }
1470 labelsInCurrentCommit.add(label);
1471
1472 var markName = getFiberMarkName(label, debugID);
1473 beginMark(markName);
1474 return true;
1475};
1476
1477var clearFiberMark = function (fiber, phase) {
1478 var componentName = getComponentName(fiber.type) || 'Unknown';
1479 var debugID = fiber._debugID;
1480 var isMounted = fiber.alternate !== null;
1481 var label = getFiberLabel(componentName, isMounted, phase);
1482 var markName = getFiberMarkName(label, debugID);
1483 clearMark(markName);
1484};
1485
1486var endFiberMark = function (fiber, phase, warning) {
1487 var componentName = getComponentName(fiber.type) || 'Unknown';
1488 var debugID = fiber._debugID;
1489 var isMounted = fiber.alternate !== null;
1490 var label = getFiberLabel(componentName, isMounted, phase);
1491 var markName = getFiberMarkName(label, debugID);
1492 endMark(label, markName, warning);
1493};
1494
1495var shouldIgnoreFiber = function (fiber) {
1496 // Host components should be skipped in the timeline.
1497 // We could check typeof fiber.type, but does this work with RN?
1498 switch (fiber.tag) {
1499 case HostRoot:
1500 case HostComponent:
1501 case HostText:
1502 case HostPortal:
1503 case Fragment:
1504 case ContextProvider:
1505 case ContextConsumer:
1506 case Mode:
1507 return true;
1508 default:
1509 return false;
1510 }
1511};
1512
1513var clearPendingPhaseMeasurement = function () {
1514 if (currentPhase !== null && currentPhaseFiber !== null) {
1515 clearFiberMark(currentPhaseFiber, currentPhase);
1516 }
1517 currentPhaseFiber = null;
1518 currentPhase = null;
1519 hasScheduledUpdateInCurrentPhase = false;
1520};
1521
1522var pauseTimers = function () {
1523 // Stops all currently active measurements so that they can be resumed
1524 // if we continue in a later deferred loop from the same unit of work.
1525 var fiber = currentFiber;
1526 while (fiber) {
1527 if (fiber._debugIsCurrentlyTiming) {
1528 endFiberMark(fiber, null, null);
1529 }
1530 fiber = fiber.return;
1531 }
1532};
1533
1534var resumeTimersRecursively = function (fiber) {
1535 if (fiber.return !== null) {
1536 resumeTimersRecursively(fiber.return);
1537 }
1538 if (fiber._debugIsCurrentlyTiming) {
1539 beginFiberMark(fiber, null);
1540 }
1541};
1542
1543var resumeTimers = function () {
1544 // Resumes all measurements that were active during the last deferred loop.
1545 if (currentFiber !== null) {
1546 resumeTimersRecursively(currentFiber);
1547 }
1548};
1549
1550function recordEffect() {
1551 if (enableUserTimingAPI) {
1552 effectCountInCurrentCommit++;
1553 }
1554}
1555
1556function recordScheduleUpdate() {
1557 if (enableUserTimingAPI) {
1558 if (isCommitting) {
1559 hasScheduledUpdateInCurrentCommit = true;
1560 }
1561 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
1562 hasScheduledUpdateInCurrentPhase = true;
1563 }
1564 }
1565}
1566
1567function startRequestCallbackTimer() {
1568 if (enableUserTimingAPI) {
1569 if (supportsUserTiming && !isWaitingForCallback) {
1570 isWaitingForCallback = true;
1571 beginMark('(Waiting for async callback...)');
1572 }
1573 }
1574}
1575
1576function stopRequestCallbackTimer(didExpire, expirationTime) {
1577 if (enableUserTimingAPI) {
1578 if (supportsUserTiming) {
1579 isWaitingForCallback = false;
1580 var warning = didExpire ? 'React was blocked by main thread' : null;
1581 endMark('(Waiting for async callback... will force flush in ' + expirationTime + ' ms)', '(Waiting for async callback...)', warning);
1582 }
1583 }
1584}
1585
1586function startWorkTimer(fiber) {
1587 if (enableUserTimingAPI) {
1588 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1589 return;
1590 }
1591 // If we pause, this is the fiber to unwind from.
1592 currentFiber = fiber;
1593 if (!beginFiberMark(fiber, null)) {
1594 return;
1595 }
1596 fiber._debugIsCurrentlyTiming = true;
1597 }
1598}
1599
1600function cancelWorkTimer(fiber) {
1601 if (enableUserTimingAPI) {
1602 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1603 return;
1604 }
1605 // Remember we shouldn't complete measurement for this fiber.
1606 // Otherwise flamechart will be deep even for small updates.
1607 fiber._debugIsCurrentlyTiming = false;
1608 clearFiberMark(fiber, null);
1609 }
1610}
1611
1612function stopWorkTimer(fiber) {
1613 if (enableUserTimingAPI) {
1614 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1615 return;
1616 }
1617 // If we pause, its parent is the fiber to unwind from.
1618 currentFiber = fiber.return;
1619 if (!fiber._debugIsCurrentlyTiming) {
1620 return;
1621 }
1622 fiber._debugIsCurrentlyTiming = false;
1623 endFiberMark(fiber, null, null);
1624 }
1625}
1626
1627function stopFailedWorkTimer(fiber) {
1628 if (enableUserTimingAPI) {
1629 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
1630 return;
1631 }
1632 // If we pause, its parent is the fiber to unwind from.
1633 currentFiber = fiber.return;
1634 if (!fiber._debugIsCurrentlyTiming) {
1635 return;
1636 }
1637 fiber._debugIsCurrentlyTiming = false;
1638 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
1639 endFiberMark(fiber, null, warning);
1640 }
1641}
1642
1643function startPhaseTimer(fiber, phase) {
1644 if (enableUserTimingAPI) {
1645 if (!supportsUserTiming) {
1646 return;
1647 }
1648 clearPendingPhaseMeasurement();
1649 if (!beginFiberMark(fiber, phase)) {
1650 return;
1651 }
1652 currentPhaseFiber = fiber;
1653 currentPhase = phase;
1654 }
1655}
1656
1657function stopPhaseTimer() {
1658 if (enableUserTimingAPI) {
1659 if (!supportsUserTiming) {
1660 return;
1661 }
1662 if (currentPhase !== null && currentPhaseFiber !== null) {
1663 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
1664 endFiberMark(currentPhaseFiber, currentPhase, warning);
1665 }
1666 currentPhase = null;
1667 currentPhaseFiber = null;
1668 }
1669}
1670
1671function startWorkLoopTimer(nextUnitOfWork) {
1672 if (enableUserTimingAPI) {
1673 currentFiber = nextUnitOfWork;
1674 if (!supportsUserTiming) {
1675 return;
1676 }
1677 commitCountInCurrentWorkLoop = 0;
1678 // This is top level call.
1679 // Any other measurements are performed within.
1680 beginMark('(React Tree Reconciliation)');
1681 // Resume any measurements that were in progress during the last loop.
1682 resumeTimers();
1683 }
1684}
1685
1686function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
1687 if (enableUserTimingAPI) {
1688 if (!supportsUserTiming) {
1689 return;
1690 }
1691 var warning = null;
1692 if (interruptedBy !== null) {
1693 if (interruptedBy.tag === HostRoot) {
1694 warning = 'A top-level update interrupted the previous render';
1695 } else {
1696 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
1697 warning = 'An update to ' + componentName + ' interrupted the previous render';
1698 }
1699 } else if (commitCountInCurrentWorkLoop > 1) {
1700 warning = 'There were cascading updates';
1701 }
1702 commitCountInCurrentWorkLoop = 0;
1703 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)';
1704 // Pause any measurements until the next loop.
1705 pauseTimers();
1706 endMark(label, '(React Tree Reconciliation)', warning);
1707 }
1708}
1709
1710function startCommitTimer() {
1711 if (enableUserTimingAPI) {
1712 if (!supportsUserTiming) {
1713 return;
1714 }
1715 isCommitting = true;
1716 hasScheduledUpdateInCurrentCommit = false;
1717 labelsInCurrentCommit.clear();
1718 beginMark('(Committing Changes)');
1719 }
1720}
1721
1722function stopCommitTimer() {
1723 if (enableUserTimingAPI) {
1724 if (!supportsUserTiming) {
1725 return;
1726 }
1727
1728 var warning = null;
1729 if (hasScheduledUpdateInCurrentCommit) {
1730 warning = 'Lifecycle hook scheduled a cascading update';
1731 } else if (commitCountInCurrentWorkLoop > 0) {
1732 warning = 'Caused by a cascading update in earlier commit';
1733 }
1734 hasScheduledUpdateInCurrentCommit = false;
1735 commitCountInCurrentWorkLoop++;
1736 isCommitting = false;
1737 labelsInCurrentCommit.clear();
1738
1739 endMark('(Committing Changes)', '(Committing Changes)', warning);
1740 }
1741}
1742
1743function startCommitSnapshotEffectsTimer() {
1744 if (enableUserTimingAPI) {
1745 if (!supportsUserTiming) {
1746 return;
1747 }
1748 effectCountInCurrentCommit = 0;
1749 beginMark('(Committing Snapshot Effects)');
1750 }
1751}
1752
1753function stopCommitSnapshotEffectsTimer() {
1754 if (enableUserTimingAPI) {
1755 if (!supportsUserTiming) {
1756 return;
1757 }
1758 var count = effectCountInCurrentCommit;
1759 effectCountInCurrentCommit = 0;
1760 endMark('(Committing Snapshot Effects: ' + count + ' Total)', '(Committing Snapshot Effects)', null);
1761 }
1762}
1763
1764function startCommitHostEffectsTimer() {
1765 if (enableUserTimingAPI) {
1766 if (!supportsUserTiming) {
1767 return;
1768 }
1769 effectCountInCurrentCommit = 0;
1770 beginMark('(Committing Host Effects)');
1771 }
1772}
1773
1774function stopCommitHostEffectsTimer() {
1775 if (enableUserTimingAPI) {
1776 if (!supportsUserTiming) {
1777 return;
1778 }
1779 var count = effectCountInCurrentCommit;
1780 effectCountInCurrentCommit = 0;
1781 endMark('(Committing Host Effects: ' + count + ' Total)', '(Committing Host Effects)', null);
1782 }
1783}
1784
1785function startCommitLifeCyclesTimer() {
1786 if (enableUserTimingAPI) {
1787 if (!supportsUserTiming) {
1788 return;
1789 }
1790 effectCountInCurrentCommit = 0;
1791 beginMark('(Calling Lifecycle Methods)');
1792 }
1793}
1794
1795function stopCommitLifeCyclesTimer() {
1796 if (enableUserTimingAPI) {
1797 if (!supportsUserTiming) {
1798 return;
1799 }
1800 var count = effectCountInCurrentCommit;
1801 effectCountInCurrentCommit = 0;
1802 endMark('(Calling Lifecycle Methods: ' + count + ' Total)', '(Calling Lifecycle Methods)', null);
1803 }
1804}
1805
1806var valueStack = [];
1807
1808var fiberStack = void 0;
1809
1810{
1811 fiberStack = [];
1812}
1813
1814var index = -1;
1815
1816function createCursor(defaultValue) {
1817 return {
1818 current: defaultValue
1819 };
1820}
1821
1822function pop(cursor, fiber) {
1823 if (index < 0) {
1824 {
1825 warningWithoutStack$1(false, 'Unexpected pop.');
1826 }
1827 return;
1828 }
1829
1830 {
1831 if (fiber !== fiberStack[index]) {
1832 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
1833 }
1834 }
1835
1836 cursor.current = valueStack[index];
1837
1838 valueStack[index] = null;
1839
1840 {
1841 fiberStack[index] = null;
1842 }
1843
1844 index--;
1845}
1846
1847function push(cursor, value, fiber) {
1848 index++;
1849
1850 valueStack[index] = cursor.current;
1851
1852 {
1853 fiberStack[index] = fiber;
1854 }
1855
1856 cursor.current = value;
1857}
1858
1859function checkThatStackIsEmpty() {
1860 {
1861 if (index !== -1) {
1862 warningWithoutStack$1(false, 'Expected an empty stack. Something was not reset properly.');
1863 }
1864 }
1865}
1866
1867function resetStackAfterFatalErrorInDev() {
1868 {
1869 index = -1;
1870 valueStack.length = 0;
1871 fiberStack.length = 0;
1872 }
1873}
1874
1875var warnedAboutMissingGetChildContext = void 0;
1876
1877{
1878 warnedAboutMissingGetChildContext = {};
1879}
1880
1881var emptyContextObject = {};
1882{
1883 Object.freeze(emptyContextObject);
1884}
1885
1886// A cursor to the current merged context object on the stack.
1887var contextStackCursor = createCursor(emptyContextObject);
1888// A cursor to a boolean indicating whether the context has changed.
1889var didPerformWorkStackCursor = createCursor(false);
1890// Keep track of the previous context object that was on the stack.
1891// We use this to get access to the parent context after we have already
1892// pushed the next context provider, and now need to merge their contexts.
1893var previousContext = emptyContextObject;
1894
1895function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
1896 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
1897 // If the fiber is a context provider itself, when we read its context
1898 // we may have already pushed its own child context on the stack. A context
1899 // provider should not "see" its own child context. Therefore we read the
1900 // previous (parent) context instead for a context provider.
1901 return previousContext;
1902 }
1903 return contextStackCursor.current;
1904}
1905
1906function cacheContext(workInProgress, unmaskedContext, maskedContext) {
1907 var instance = workInProgress.stateNode;
1908 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
1909 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
1910}
1911
1912function getMaskedContext(workInProgress, unmaskedContext) {
1913 var type = workInProgress.type;
1914 var contextTypes = type.contextTypes;
1915 if (!contextTypes) {
1916 return emptyContextObject;
1917 }
1918
1919 // Avoid recreating masked context unless unmasked context has changed.
1920 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
1921 // This may trigger infinite loops if componentWillReceiveProps calls setState.
1922 var instance = workInProgress.stateNode;
1923 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
1924 return instance.__reactInternalMemoizedMaskedChildContext;
1925 }
1926
1927 var context = {};
1928 for (var key in contextTypes) {
1929 context[key] = unmaskedContext[key];
1930 }
1931
1932 {
1933 var name = getComponentName(type) || 'Unknown';
1934 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
1935 }
1936
1937 // Cache unmasked context so we can avoid recreating masked context unless necessary.
1938 // Context is created before the class component is instantiated so check for instance.
1939 if (instance) {
1940 cacheContext(workInProgress, unmaskedContext, context);
1941 }
1942
1943 return context;
1944}
1945
1946function hasContextChanged() {
1947 return didPerformWorkStackCursor.current;
1948}
1949
1950function isContextProvider(type) {
1951 var childContextTypes = type.childContextTypes;
1952 return childContextTypes !== null && childContextTypes !== undefined;
1953}
1954
1955function popContext(fiber) {
1956 pop(didPerformWorkStackCursor, fiber);
1957 pop(contextStackCursor, fiber);
1958}
1959
1960function popTopLevelContextObject(fiber) {
1961 pop(didPerformWorkStackCursor, fiber);
1962 pop(contextStackCursor, fiber);
1963}
1964
1965function pushTopLevelContextObject(fiber, context, didChange) {
1966 !(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;
1967
1968 push(contextStackCursor, context, fiber);
1969 push(didPerformWorkStackCursor, didChange, fiber);
1970}
1971
1972function processChildContext(fiber, type, parentContext) {
1973 var instance = fiber.stateNode;
1974 var childContextTypes = type.childContextTypes;
1975
1976 // TODO (bvaughn) Replace this behavior with an invariant() in the future.
1977 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
1978 if (typeof instance.getChildContext !== 'function') {
1979 {
1980 var componentName = getComponentName(type) || 'Unknown';
1981
1982 if (!warnedAboutMissingGetChildContext[componentName]) {
1983 warnedAboutMissingGetChildContext[componentName] = true;
1984 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);
1985 }
1986 }
1987 return parentContext;
1988 }
1989
1990 var childContext = void 0;
1991 {
1992 setCurrentPhase('getChildContext');
1993 }
1994 startPhaseTimer(fiber, 'getChildContext');
1995 childContext = instance.getChildContext();
1996 stopPhaseTimer();
1997 {
1998 setCurrentPhase(null);
1999 }
2000 for (var contextKey in childContext) {
2001 !(contextKey in childContextTypes) ? invariant(false, '%s.getChildContext(): key "%s" is not defined in childContextTypes.', getComponentName(type) || 'Unknown', contextKey) : void 0;
2002 }
2003 {
2004 var name = getComponentName(type) || 'Unknown';
2005 checkPropTypes_1(childContextTypes, childContext, 'child context', name,
2006 // In practice, there is one case in which we won't get a stack. It's when
2007 // somebody calls unstable_renderSubtreeIntoContainer() and we process
2008 // context from the parent component instance. The stack will be missing
2009 // because it's outside of the reconciliation, and so the pointer has not
2010 // been set. This is rare and doesn't matter. We'll also remove that API.
2011 getCurrentFiberStackInDev);
2012 }
2013
2014 return _assign({}, parentContext, childContext);
2015}
2016
2017function pushContextProvider(workInProgress) {
2018 var instance = workInProgress.stateNode;
2019 // We push the context as early as possible to ensure stack integrity.
2020 // If the instance does not exist yet, we will push null at first,
2021 // and replace it on the stack later when invalidating the context.
2022 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject;
2023
2024 // Remember the parent context so we can merge with it later.
2025 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
2026 previousContext = contextStackCursor.current;
2027 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
2028 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
2029
2030 return true;
2031}
2032
2033function invalidateContextProvider(workInProgress, type, didChange) {
2034 var instance = workInProgress.stateNode;
2035 !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;
2036
2037 if (didChange) {
2038 // Merge parent and own context.
2039 // Skip this if we're not updating due to sCU.
2040 // This avoids unnecessarily recomputing memoized values.
2041 var mergedContext = processChildContext(workInProgress, type, previousContext);
2042 instance.__reactInternalMemoizedMergedChildContext = mergedContext;
2043
2044 // Replace the old (or empty) context with the new one.
2045 // It is important to unwind the context in the reverse order.
2046 pop(didPerformWorkStackCursor, workInProgress);
2047 pop(contextStackCursor, workInProgress);
2048 // Now push the new context and mark that it has changed.
2049 push(contextStackCursor, mergedContext, workInProgress);
2050 push(didPerformWorkStackCursor, didChange, workInProgress);
2051 } else {
2052 pop(didPerformWorkStackCursor, workInProgress);
2053 push(didPerformWorkStackCursor, didChange, workInProgress);
2054 }
2055}
2056
2057function findCurrentUnmaskedContext(fiber) {
2058 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
2059 // makes sense elsewhere
2060 !(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;
2061
2062 var node = fiber;
2063 do {
2064 switch (node.tag) {
2065 case HostRoot:
2066 return node.stateNode.context;
2067 case ClassComponent:
2068 {
2069 var Component = node.type;
2070 if (isContextProvider(Component)) {
2071 return node.stateNode.__reactInternalMemoizedMergedChildContext;
2072 }
2073 break;
2074 }
2075 }
2076 node = node.return;
2077 } while (node !== null);
2078 invariant(false, 'Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.');
2079}
2080
2081var onCommitFiberRoot = null;
2082var onCommitFiberUnmount = null;
2083var hasLoggedError = false;
2084
2085function catchErrors(fn) {
2086 return function (arg) {
2087 try {
2088 return fn(arg);
2089 } catch (err) {
2090 if (true && !hasLoggedError) {
2091 hasLoggedError = true;
2092 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
2093 }
2094 }
2095 };
2096}
2097
2098var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
2099
2100function injectInternals(internals) {
2101 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
2102 // No DevTools
2103 return false;
2104 }
2105 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
2106 if (hook.isDisabled) {
2107 // This isn't a real property on the hook, but it can be set to opt out
2108 // of DevTools integration and associated warnings and logs.
2109 // https://github.com/facebook/react/issues/3877
2110 return true;
2111 }
2112 if (!hook.supportsFiber) {
2113 {
2114 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');
2115 }
2116 // DevTools exists, even though it doesn't support Fiber.
2117 return true;
2118 }
2119 try {
2120 var rendererID = hook.inject(internals);
2121 // We have successfully injected, so now it is safe to set up hooks.
2122 onCommitFiberRoot = catchErrors(function (root) {
2123 return hook.onCommitFiberRoot(rendererID, root);
2124 });
2125 onCommitFiberUnmount = catchErrors(function (fiber) {
2126 return hook.onCommitFiberUnmount(rendererID, fiber);
2127 });
2128 } catch (err) {
2129 // Catch all errors because it is unsafe to throw during initialization.
2130 {
2131 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
2132 }
2133 }
2134 // DevTools exists
2135 return true;
2136}
2137
2138function onCommitRoot(root) {
2139 if (typeof onCommitFiberRoot === 'function') {
2140 onCommitFiberRoot(root);
2141 }
2142}
2143
2144function onCommitUnmount(fiber) {
2145 if (typeof onCommitFiberUnmount === 'function') {
2146 onCommitFiberUnmount(fiber);
2147 }
2148}
2149
2150// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
2151// Math.pow(2, 30) - 1
2152// 0b111111111111111111111111111111
2153var maxSigned31BitInt = 1073741823;
2154
2155var NoWork = 0;
2156var Never = 1;
2157var Sync = maxSigned31BitInt;
2158
2159var UNIT_SIZE = 10;
2160var MAGIC_NUMBER_OFFSET = maxSigned31BitInt - 1;
2161
2162// 1 unit of expiration time represents 10ms.
2163function msToExpirationTime(ms) {
2164 // Always add an offset so that we don't clash with the magic number for NoWork.
2165 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
2166}
2167
2168function expirationTimeToMs(expirationTime) {
2169 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
2170}
2171
2172function ceiling(num, precision) {
2173 return ((num / precision | 0) + 1) * precision;
2174}
2175
2176function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
2177 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
2178}
2179
2180var LOW_PRIORITY_EXPIRATION = 5000;
2181var LOW_PRIORITY_BATCH_SIZE = 250;
2182
2183function computeAsyncExpiration(currentTime) {
2184 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
2185}
2186
2187// We intentionally set a higher expiration time for interactive updates in
2188// dev than in production.
2189//
2190// If the main thread is being blocked so long that you hit the expiration,
2191// it's a problem that could be solved with better scheduling.
2192//
2193// People will be more likely to notice this and fix it with the long
2194// expiration time in development.
2195//
2196// In production we opt for better UX at the risk of masking scheduling
2197// problems, by expiring fast.
2198var HIGH_PRIORITY_EXPIRATION = 500;
2199var HIGH_PRIORITY_BATCH_SIZE = 100;
2200
2201function computeInteractiveExpiration(currentTime) {
2202 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
2203}
2204
2205var NoContext = 0;
2206var ConcurrentMode = 1;
2207var StrictMode = 2;
2208var ProfileMode = 4;
2209
2210var hasBadMapPolyfill = void 0;
2211
2212{
2213 hasBadMapPolyfill = false;
2214 try {
2215 var nonExtensibleObject = Object.preventExtensions({});
2216 var testMap = new Map([[nonExtensibleObject, null]]);
2217 var testSet = new Set([nonExtensibleObject]);
2218 // This is necessary for Rollup to not consider these unused.
2219 // https://github.com/rollup/rollup/issues/1771
2220 // TODO: we can remove these if Rollup fixes the bug.
2221 testMap.set(0, 0);
2222 testSet.add(0);
2223 } catch (e) {
2224 // TODO: Consider warning about bad polyfills
2225 hasBadMapPolyfill = true;
2226 }
2227}
2228
2229// A Fiber is work on a Component that needs to be done or was done. There can
2230// be more than one per component.
2231
2232
2233var debugCounter = void 0;
2234
2235{
2236 debugCounter = 1;
2237}
2238
2239function FiberNode(tag, pendingProps, key, mode) {
2240 // Instance
2241 this.tag = tag;
2242 this.key = key;
2243 this.elementType = null;
2244 this.type = null;
2245 this.stateNode = null;
2246
2247 // Fiber
2248 this.return = null;
2249 this.child = null;
2250 this.sibling = null;
2251 this.index = 0;
2252
2253 this.ref = null;
2254
2255 this.pendingProps = pendingProps;
2256 this.memoizedProps = null;
2257 this.updateQueue = null;
2258 this.memoizedState = null;
2259 this.contextDependencies = null;
2260
2261 this.mode = mode;
2262
2263 // Effects
2264 this.effectTag = NoEffect;
2265 this.nextEffect = null;
2266
2267 this.firstEffect = null;
2268 this.lastEffect = null;
2269
2270 this.expirationTime = NoWork;
2271 this.childExpirationTime = NoWork;
2272
2273 this.alternate = null;
2274
2275 if (enableProfilerTimer) {
2276 // Note: The following is done to avoid a v8 performance cliff.
2277 //
2278 // Initializing the fields below to smis and later updating them with
2279 // double values will cause Fibers to end up having separate shapes.
2280 // This behavior/bug has something to do with Object.preventExtension().
2281 // Fortunately this only impacts DEV builds.
2282 // Unfortunately it makes React unusably slow for some applications.
2283 // To work around this, initialize the fields below with doubles.
2284 //
2285 // Learn more about this here:
2286 // https://github.com/facebook/react/issues/14365
2287 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
2288 this.actualDuration = Number.NaN;
2289 this.actualStartTime = Number.NaN;
2290 this.selfBaseDuration = Number.NaN;
2291 this.treeBaseDuration = Number.NaN;
2292
2293 // It's okay to replace the initial doubles with smis after initialization.
2294 // This won't trigger the performance cliff mentioned above,
2295 // and it simplifies other profiler code (including DevTools).
2296 this.actualDuration = 0;
2297 this.actualStartTime = -1;
2298 this.selfBaseDuration = 0;
2299 this.treeBaseDuration = 0;
2300 }
2301
2302 {
2303 this._debugID = debugCounter++;
2304 this._debugSource = null;
2305 this._debugOwner = null;
2306 this._debugIsCurrentlyTiming = false;
2307 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
2308 Object.preventExtensions(this);
2309 }
2310 }
2311}
2312
2313// This is a constructor function, rather than a POJO constructor, still
2314// please ensure we do the following:
2315// 1) Nobody should add any instance methods on this. Instance methods can be
2316// more difficult to predict when they get optimized and they are almost
2317// never inlined properly in static compilers.
2318// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
2319// always know when it is a fiber.
2320// 3) We might want to experiment with using numeric keys since they are easier
2321// to optimize in a non-JIT environment.
2322// 4) We can easily go from a constructor to a createFiber object literal if that
2323// is faster.
2324// 5) It should be easy to port this to a C struct and keep a C implementation
2325// compatible.
2326var createFiber = function (tag, pendingProps, key, mode) {
2327 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
2328 return new FiberNode(tag, pendingProps, key, mode);
2329};
2330
2331function shouldConstruct(Component) {
2332 var prototype = Component.prototype;
2333 return !!(prototype && prototype.isReactComponent);
2334}
2335
2336function isSimpleFunctionComponent(type) {
2337 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
2338}
2339
2340function resolveLazyComponentTag(Component) {
2341 if (typeof Component === 'function') {
2342 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
2343 } else if (Component !== undefined && Component !== null) {
2344 var $$typeof = Component.$$typeof;
2345 if ($$typeof === REACT_FORWARD_REF_TYPE) {
2346 return ForwardRef;
2347 }
2348 if ($$typeof === REACT_MEMO_TYPE) {
2349 return MemoComponent;
2350 }
2351 }
2352 return IndeterminateComponent;
2353}
2354
2355// This is used to create an alternate fiber to do work on.
2356function createWorkInProgress(current, pendingProps, expirationTime) {
2357 var workInProgress = current.alternate;
2358 if (workInProgress === null) {
2359 // We use a double buffering pooling technique because we know that we'll
2360 // only ever need at most two versions of a tree. We pool the "other" unused
2361 // node that we're free to reuse. This is lazily created to avoid allocating
2362 // extra objects for things that are never updated. It also allow us to
2363 // reclaim the extra memory if needed.
2364 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
2365 workInProgress.elementType = current.elementType;
2366 workInProgress.type = current.type;
2367 workInProgress.stateNode = current.stateNode;
2368
2369 {
2370 // DEV-only fields
2371 workInProgress._debugID = current._debugID;
2372 workInProgress._debugSource = current._debugSource;
2373 workInProgress._debugOwner = current._debugOwner;
2374 }
2375
2376 workInProgress.alternate = current;
2377 current.alternate = workInProgress;
2378 } else {
2379 workInProgress.pendingProps = pendingProps;
2380
2381 // We already have an alternate.
2382 // Reset the effect tag.
2383 workInProgress.effectTag = NoEffect;
2384
2385 // The effect list is no longer valid.
2386 workInProgress.nextEffect = null;
2387 workInProgress.firstEffect = null;
2388 workInProgress.lastEffect = null;
2389
2390 if (enableProfilerTimer) {
2391 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
2392 // This prevents time from endlessly accumulating in new commits.
2393 // This has the downside of resetting values for different priority renders,
2394 // But works for yielding (the common case) and should support resuming.
2395 workInProgress.actualDuration = 0;
2396 workInProgress.actualStartTime = -1;
2397 }
2398 }
2399
2400 workInProgress.childExpirationTime = current.childExpirationTime;
2401 workInProgress.expirationTime = current.expirationTime;
2402
2403 workInProgress.child = current.child;
2404 workInProgress.memoizedProps = current.memoizedProps;
2405 workInProgress.memoizedState = current.memoizedState;
2406 workInProgress.updateQueue = current.updateQueue;
2407 workInProgress.contextDependencies = current.contextDependencies;
2408
2409 // These will be overridden during the parent's reconciliation
2410 workInProgress.sibling = current.sibling;
2411 workInProgress.index = current.index;
2412 workInProgress.ref = current.ref;
2413
2414 if (enableProfilerTimer) {
2415 workInProgress.selfBaseDuration = current.selfBaseDuration;
2416 workInProgress.treeBaseDuration = current.treeBaseDuration;
2417 }
2418
2419 return workInProgress;
2420}
2421
2422function createHostRootFiber(isConcurrent) {
2423 var mode = isConcurrent ? ConcurrentMode | StrictMode : NoContext;
2424
2425 if (enableProfilerTimer && isDevToolsPresent) {
2426 // Always collect profile timings when DevTools are present.
2427 // This enables DevTools to start capturing timing at any point–
2428 // Without some nodes in the tree having empty base times.
2429 mode |= ProfileMode;
2430 }
2431
2432 return createFiber(HostRoot, null, null, mode);
2433}
2434
2435function createFiberFromTypeAndProps(type, // React$ElementType
2436key, pendingProps, owner, mode, expirationTime) {
2437 var fiber = void 0;
2438
2439 var fiberTag = IndeterminateComponent;
2440 // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
2441 var resolvedType = type;
2442 if (typeof type === 'function') {
2443 if (shouldConstruct(type)) {
2444 fiberTag = ClassComponent;
2445 }
2446 } else if (typeof type === 'string') {
2447 fiberTag = HostComponent;
2448 } else {
2449 getTag: switch (type) {
2450 case REACT_FRAGMENT_TYPE:
2451 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
2452 case REACT_CONCURRENT_MODE_TYPE:
2453 return createFiberFromMode(pendingProps, mode | ConcurrentMode | StrictMode, expirationTime, key);
2454 case REACT_STRICT_MODE_TYPE:
2455 return createFiberFromMode(pendingProps, mode | StrictMode, expirationTime, key);
2456 case REACT_PROFILER_TYPE:
2457 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
2458 case REACT_SUSPENSE_TYPE:
2459 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
2460 default:
2461 {
2462 if (typeof type === 'object' && type !== null) {
2463 switch (type.$$typeof) {
2464 case REACT_PROVIDER_TYPE:
2465 fiberTag = ContextProvider;
2466 break getTag;
2467 case REACT_CONTEXT_TYPE:
2468 // This is a consumer
2469 fiberTag = ContextConsumer;
2470 break getTag;
2471 case REACT_FORWARD_REF_TYPE:
2472 fiberTag = ForwardRef;
2473 break getTag;
2474 case REACT_MEMO_TYPE:
2475 fiberTag = MemoComponent;
2476 break getTag;
2477 case REACT_LAZY_TYPE:
2478 fiberTag = LazyComponent;
2479 resolvedType = null;
2480 break getTag;
2481 }
2482 }
2483 var info = '';
2484 {
2485 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
2486 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.';
2487 }
2488 var ownerName = owner ? getComponentName(owner.type) : null;
2489 if (ownerName) {
2490 info += '\n\nCheck the render method of `' + ownerName + '`.';
2491 }
2492 }
2493 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);
2494 }
2495 }
2496 }
2497
2498 fiber = createFiber(fiberTag, pendingProps, key, mode);
2499 fiber.elementType = type;
2500 fiber.type = resolvedType;
2501 fiber.expirationTime = expirationTime;
2502
2503 return fiber;
2504}
2505
2506function createFiberFromElement(element, mode, expirationTime) {
2507 var owner = null;
2508 {
2509 owner = element._owner;
2510 }
2511 var type = element.type;
2512 var key = element.key;
2513 var pendingProps = element.props;
2514 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
2515 {
2516 fiber._debugSource = element._source;
2517 fiber._debugOwner = element._owner;
2518 }
2519 return fiber;
2520}
2521
2522function createFiberFromFragment(elements, mode, expirationTime, key) {
2523 var fiber = createFiber(Fragment, elements, key, mode);
2524 fiber.expirationTime = expirationTime;
2525 return fiber;
2526}
2527
2528function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
2529 {
2530 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
2531 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
2532 }
2533 }
2534
2535 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
2536 // TODO: The Profiler fiber shouldn't have a type. It has a tag.
2537 fiber.elementType = REACT_PROFILER_TYPE;
2538 fiber.type = REACT_PROFILER_TYPE;
2539 fiber.expirationTime = expirationTime;
2540
2541 return fiber;
2542}
2543
2544function createFiberFromMode(pendingProps, mode, expirationTime, key) {
2545 var fiber = createFiber(Mode, pendingProps, key, mode);
2546
2547 // TODO: The Mode fiber shouldn't have a type. It has a tag.
2548 var type = (mode & ConcurrentMode) === NoContext ? REACT_STRICT_MODE_TYPE : REACT_CONCURRENT_MODE_TYPE;
2549 fiber.elementType = type;
2550 fiber.type = type;
2551
2552 fiber.expirationTime = expirationTime;
2553 return fiber;
2554}
2555
2556function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
2557 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
2558
2559 // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
2560 var type = REACT_SUSPENSE_TYPE;
2561 fiber.elementType = type;
2562 fiber.type = type;
2563
2564 fiber.expirationTime = expirationTime;
2565 return fiber;
2566}
2567
2568function createFiberFromText(content, mode, expirationTime) {
2569 var fiber = createFiber(HostText, content, null, mode);
2570 fiber.expirationTime = expirationTime;
2571 return fiber;
2572}
2573
2574function createFiberFromHostInstanceForDeletion() {
2575 var fiber = createFiber(HostComponent, null, null, NoContext);
2576 // TODO: These should not need a type.
2577 fiber.elementType = 'DELETED';
2578 fiber.type = 'DELETED';
2579 return fiber;
2580}
2581
2582function createFiberFromPortal(portal, mode, expirationTime) {
2583 var pendingProps = portal.children !== null ? portal.children : [];
2584 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
2585 fiber.expirationTime = expirationTime;
2586 fiber.stateNode = {
2587 containerInfo: portal.containerInfo,
2588 pendingChildren: null, // Used by persistent updates
2589 implementation: portal.implementation
2590 };
2591 return fiber;
2592}
2593
2594// Used for stashing WIP properties to replay failed work in DEV.
2595function assignFiberPropertiesInDEV(target, source) {
2596 if (target === null) {
2597 // This Fiber's initial properties will always be overwritten.
2598 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
2599 target = createFiber(IndeterminateComponent, null, null, NoContext);
2600 }
2601
2602 // This is intentionally written as a list of all properties.
2603 // We tried to use Object.assign() instead but this is called in
2604 // the hottest path, and Object.assign() was too slow:
2605 // https://github.com/facebook/react/issues/12502
2606 // This code is DEV-only so size is not a concern.
2607
2608 target.tag = source.tag;
2609 target.key = source.key;
2610 target.elementType = source.elementType;
2611 target.type = source.type;
2612 target.stateNode = source.stateNode;
2613 target.return = source.return;
2614 target.child = source.child;
2615 target.sibling = source.sibling;
2616 target.index = source.index;
2617 target.ref = source.ref;
2618 target.pendingProps = source.pendingProps;
2619 target.memoizedProps = source.memoizedProps;
2620 target.updateQueue = source.updateQueue;
2621 target.memoizedState = source.memoizedState;
2622 target.contextDependencies = source.contextDependencies;
2623 target.mode = source.mode;
2624 target.effectTag = source.effectTag;
2625 target.nextEffect = source.nextEffect;
2626 target.firstEffect = source.firstEffect;
2627 target.lastEffect = source.lastEffect;
2628 target.expirationTime = source.expirationTime;
2629 target.childExpirationTime = source.childExpirationTime;
2630 target.alternate = source.alternate;
2631 if (enableProfilerTimer) {
2632 target.actualDuration = source.actualDuration;
2633 target.actualStartTime = source.actualStartTime;
2634 target.selfBaseDuration = source.selfBaseDuration;
2635 target.treeBaseDuration = source.treeBaseDuration;
2636 }
2637 target._debugID = source._debugID;
2638 target._debugSource = source._debugSource;
2639 target._debugOwner = source._debugOwner;
2640 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
2641 return target;
2642}
2643
2644var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
2645
2646var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
2647var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
2648var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
2649var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
2650var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
2651var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
2652var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
2653var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
2654var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
2655var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
2656
2657// TODO: This should be lifted into the renderer.
2658
2659
2660// The following attributes are only used by interaction tracing builds.
2661// They enable interactions to be associated with their async work,
2662// And expose interaction metadata to the React DevTools Profiler plugin.
2663// Note that these attributes are only defined when the enableSchedulerTracing flag is enabled.
2664
2665
2666// Exported FiberRoot type includes all properties,
2667// To avoid requiring potentially error-prone :any casts throughout the project.
2668// Profiling properties are only safe to access in profiling builds (when enableSchedulerTracing is true).
2669// The types are defined separately within this file to ensure they stay in sync.
2670// (We don't have to use an inline :any cast when enableSchedulerTracing is disabled.)
2671
2672
2673function createFiberRoot(containerInfo, isConcurrent, hydrate) {
2674 // Cyclic construction. This cheats the type system right now because
2675 // stateNode is any.
2676 var uninitializedFiber = createHostRootFiber(isConcurrent);
2677
2678 var root = void 0;
2679 if (enableSchedulerTracing) {
2680 root = {
2681 current: uninitializedFiber,
2682 containerInfo: containerInfo,
2683 pendingChildren: null,
2684
2685 earliestPendingTime: NoWork,
2686 latestPendingTime: NoWork,
2687 earliestSuspendedTime: NoWork,
2688 latestSuspendedTime: NoWork,
2689 latestPingedTime: NoWork,
2690
2691 pingCache: null,
2692
2693 didError: false,
2694
2695 pendingCommitExpirationTime: NoWork,
2696 finishedWork: null,
2697 timeoutHandle: noTimeout,
2698 context: null,
2699 pendingContext: null,
2700 hydrate: hydrate,
2701 nextExpirationTimeToWorkOn: NoWork,
2702 expirationTime: NoWork,
2703 firstBatch: null,
2704 nextScheduledRoot: null,
2705
2706 interactionThreadID: unstable_getThreadID(),
2707 memoizedInteractions: new Set(),
2708 pendingInteractionMap: new Map()
2709 };
2710 } else {
2711 root = {
2712 current: uninitializedFiber,
2713 containerInfo: containerInfo,
2714 pendingChildren: null,
2715
2716 pingCache: null,
2717
2718 earliestPendingTime: NoWork,
2719 latestPendingTime: NoWork,
2720 earliestSuspendedTime: NoWork,
2721 latestSuspendedTime: NoWork,
2722 latestPingedTime: NoWork,
2723
2724 didError: false,
2725
2726 pendingCommitExpirationTime: NoWork,
2727 finishedWork: null,
2728 timeoutHandle: noTimeout,
2729 context: null,
2730 pendingContext: null,
2731 hydrate: hydrate,
2732 nextExpirationTimeToWorkOn: NoWork,
2733 expirationTime: NoWork,
2734 firstBatch: null,
2735 nextScheduledRoot: null
2736 };
2737 }
2738
2739 uninitializedFiber.stateNode = root;
2740
2741 // The reason for the way the Flow types are structured in this file,
2742 // Is to avoid needing :any casts everywhere interaction tracing fields are used.
2743 // Unfortunately that requires an :any cast for non-interaction tracing capable builds.
2744 // $FlowFixMe Remove this :any cast and replace it with something better.
2745 return root;
2746}
2747
2748var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
2749 var funcArgs = Array.prototype.slice.call(arguments, 3);
2750 try {
2751 func.apply(context, funcArgs);
2752 } catch (error) {
2753 this.onError(error);
2754 }
2755};
2756
2757{
2758 // In DEV mode, we swap out invokeGuardedCallback for a special version
2759 // that plays more nicely with the browser's DevTools. The idea is to preserve
2760 // "Pause on exceptions" behavior. Because React wraps all user-provided
2761 // functions in invokeGuardedCallback, and the production version of
2762 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
2763 // like caught exceptions, and the DevTools won't pause unless the developer
2764 // takes the extra step of enabling pause on caught exceptions. This is
2765 // untintuitive, though, because even though React has caught the error, from
2766 // the developer's perspective, the error is uncaught.
2767 //
2768 // To preserve the expected "Pause on exceptions" behavior, we don't use a
2769 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
2770 // DOM node, and call the user-provided callback from inside an event handler
2771 // for that fake event. If the callback throws, the error is "captured" using
2772 // a global event handler. But because the error happens in a different
2773 // event loop context, it does not interrupt the normal program flow.
2774 // Effectively, this gives us try-catch behavior without actually using
2775 // try-catch. Neat!
2776
2777 // Check that the browser supports the APIs we need to implement our special
2778 // DEV version of invokeGuardedCallback
2779 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
2780 var fakeNode = document.createElement('react');
2781
2782 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
2783 // If document doesn't exist we know for sure we will crash in this method
2784 // when we call document.createEvent(). However this can cause confusing
2785 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
2786 // So we preemptively throw with a better message instead.
2787 !(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;
2788 var evt = document.createEvent('Event');
2789
2790 // Keeps track of whether the user-provided callback threw an error. We
2791 // set this to true at the beginning, then set it to false right after
2792 // calling the function. If the function errors, `didError` will never be
2793 // set to false. This strategy works even if the browser is flaky and
2794 // fails to call our global error handler, because it doesn't rely on
2795 // the error event at all.
2796 var didError = true;
2797
2798 // Keeps track of the value of window.event so that we can reset it
2799 // during the callback to let user code access window.event in the
2800 // browsers that support it.
2801 var windowEvent = window.event;
2802
2803 // Keeps track of the descriptor of window.event to restore it after event
2804 // dispatching: https://github.com/facebook/react/issues/13688
2805 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
2806
2807 // Create an event handler for our fake event. We will synchronously
2808 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
2809 // call the user-provided callback.
2810 var funcArgs = Array.prototype.slice.call(arguments, 3);
2811 function callCallback() {
2812 // We immediately remove the callback from event listeners so that
2813 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
2814 // nested call would trigger the fake event handlers of any call higher
2815 // in the stack.
2816 fakeNode.removeEventListener(evtType, callCallback, false);
2817
2818 // We check for window.hasOwnProperty('event') to prevent the
2819 // window.event assignment in both IE <= 10 as they throw an error
2820 // "Member not found" in strict mode, and in Firefox which does not
2821 // support window.event.
2822 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
2823 window.event = windowEvent;
2824 }
2825
2826 func.apply(context, funcArgs);
2827 didError = false;
2828 }
2829
2830 // Create a global error event handler. We use this to capture the value
2831 // that was thrown. It's possible that this error handler will fire more
2832 // than once; for example, if non-React code also calls `dispatchEvent`
2833 // and a handler for that event throws. We should be resilient to most of
2834 // those cases. Even if our error event handler fires more than once, the
2835 // last error event is always used. If the callback actually does error,
2836 // we know that the last error event is the correct one, because it's not
2837 // possible for anything else to have happened in between our callback
2838 // erroring and the code that follows the `dispatchEvent` call below. If
2839 // the callback doesn't error, but the error event was fired, we know to
2840 // ignore it because `didError` will be false, as described above.
2841 var error = void 0;
2842 // Use this to track whether the error event is ever called.
2843 var didSetError = false;
2844 var isCrossOriginError = false;
2845
2846 function handleWindowError(event) {
2847 error = event.error;
2848 didSetError = true;
2849 if (error === null && event.colno === 0 && event.lineno === 0) {
2850 isCrossOriginError = true;
2851 }
2852 if (event.defaultPrevented) {
2853 // Some other error handler has prevented default.
2854 // Browsers silence the error report if this happens.
2855 // We'll remember this to later decide whether to log it or not.
2856 if (error != null && typeof error === 'object') {
2857 try {
2858 error._suppressLogging = true;
2859 } catch (inner) {
2860 // Ignore.
2861 }
2862 }
2863 }
2864 }
2865
2866 // Create a fake event type.
2867 var evtType = 'react-' + (name ? name : 'invokeguardedcallback');
2868
2869 // Attach our event handlers
2870 window.addEventListener('error', handleWindowError);
2871 fakeNode.addEventListener(evtType, callCallback, false);
2872
2873 // Synchronously dispatch our fake event. If the user-provided function
2874 // errors, it will trigger our global error handler.
2875 evt.initEvent(evtType, false, false);
2876 fakeNode.dispatchEvent(evt);
2877
2878 if (windowEventDescriptor) {
2879 Object.defineProperty(window, 'event', windowEventDescriptor);
2880 }
2881
2882 if (didError) {
2883 if (!didSetError) {
2884 // The callback errored, but the error event never fired.
2885 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.');
2886 } else if (isCrossOriginError) {
2887 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.');
2888 }
2889 this.onError(error);
2890 }
2891
2892 // Remove our event listeners
2893 window.removeEventListener('error', handleWindowError);
2894 };
2895
2896 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
2897 }
2898}
2899
2900var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
2901
2902// Used by Fiber to simulate a try-catch.
2903var hasError = false;
2904var caughtError = null;
2905
2906var reporter = {
2907 onError: function (error) {
2908 hasError = true;
2909 caughtError = error;
2910 }
2911};
2912
2913/**
2914 * Call a function while guarding against errors that happens within it.
2915 * Returns an error if it throws, otherwise null.
2916 *
2917 * In production, this is implemented using a try-catch. The reason we don't
2918 * use a try-catch directly is so that we can swap out a different
2919 * implementation in DEV mode.
2920 *
2921 * @param {String} name of the guard to use for logging or debugging
2922 * @param {Function} func The function to invoke
2923 * @param {*} context The context to use when calling the function
2924 * @param {...*} args Arguments for function
2925 */
2926function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
2927 hasError = false;
2928 caughtError = null;
2929 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
2930}
2931
2932/**
2933 * Same as invokeGuardedCallback, but instead of returning an error, it stores
2934 * it in a global so it can be rethrown by `rethrowCaughtError` later.
2935 * TODO: See if caughtError and rethrowError can be unified.
2936 *
2937 * @param {String} name of the guard to use for logging or debugging
2938 * @param {Function} func The function to invoke
2939 * @param {*} context The context to use when calling the function
2940 * @param {...*} args Arguments for function
2941 */
2942
2943
2944/**
2945 * During execution of guarded functions we will capture the first error which
2946 * we will rethrow to be handled by the top level error handler.
2947 */
2948
2949
2950function hasCaughtError() {
2951 return hasError;
2952}
2953
2954function clearCaughtError() {
2955 if (hasError) {
2956 var error = caughtError;
2957 hasError = false;
2958 caughtError = null;
2959 return error;
2960 } else {
2961 invariant(false, 'clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.');
2962 }
2963}
2964
2965/**
2966 * Forked from fbjs/warning:
2967 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
2968 *
2969 * Only change is we use console.warn instead of console.error,
2970 * and do nothing when 'console' is not supported.
2971 * This really simplifies the code.
2972 * ---
2973 * Similar to invariant but only logs a warning if the condition is not met.
2974 * This can be used to log issues in development environments in critical
2975 * paths. Removing the logging code for production environments will keep the
2976 * same logic and follow the same code paths.
2977 */
2978
2979var lowPriorityWarning = function () {};
2980
2981{
2982 var printWarning$1 = function (format) {
2983 for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
2984 args[_key - 1] = arguments[_key];
2985 }
2986
2987 var argIndex = 0;
2988 var message = 'Warning: ' + format.replace(/%s/g, function () {
2989 return args[argIndex++];
2990 });
2991 if (typeof console !== 'undefined') {
2992 console.warn(message);
2993 }
2994 try {
2995 // --- Welcome to debugging React ---
2996 // This error was thrown as a convenience so that you can use this stack
2997 // to find the callsite that caused this warning to fire.
2998 throw new Error(message);
2999 } catch (x) {}
3000 };
3001
3002 lowPriorityWarning = function (condition, format) {
3003 if (format === undefined) {
3004 throw new Error('`lowPriorityWarning(condition, format, ...args)` requires a warning ' + 'message argument');
3005 }
3006 if (!condition) {
3007 for (var _len2 = arguments.length, args = Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
3008 args[_key2 - 2] = arguments[_key2];
3009 }
3010
3011 printWarning$1.apply(undefined, [format].concat(args));
3012 }
3013 };
3014}
3015
3016var lowPriorityWarning$1 = lowPriorityWarning;
3017
3018var ReactStrictModeWarnings = {
3019 discardPendingWarnings: function () {},
3020 flushPendingDeprecationWarnings: function () {},
3021 flushPendingUnsafeLifecycleWarnings: function () {},
3022 recordDeprecationWarnings: function (fiber, instance) {},
3023 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
3024 recordLegacyContextWarning: function (fiber, instance) {},
3025 flushLegacyContextWarning: function () {}
3026};
3027
3028{
3029 var LIFECYCLE_SUGGESTIONS = {
3030 UNSAFE_componentWillMount: 'componentDidMount',
3031 UNSAFE_componentWillReceiveProps: 'static getDerivedStateFromProps',
3032 UNSAFE_componentWillUpdate: 'componentDidUpdate'
3033 };
3034
3035 var pendingComponentWillMountWarnings = [];
3036 var pendingComponentWillReceivePropsWarnings = [];
3037 var pendingComponentWillUpdateWarnings = [];
3038 var pendingUnsafeLifecycleWarnings = new Map();
3039 var pendingLegacyContextWarning = new Map();
3040
3041 // Tracks components we have already warned about.
3042 var didWarnAboutDeprecatedLifecycles = new Set();
3043 var didWarnAboutUnsafeLifecycles = new Set();
3044 var didWarnAboutLegacyContext = new Set();
3045
3046 var setToSortedString = function (set) {
3047 var array = [];
3048 set.forEach(function (value) {
3049 array.push(value);
3050 });
3051 return array.sort().join(', ');
3052 };
3053
3054 ReactStrictModeWarnings.discardPendingWarnings = function () {
3055 pendingComponentWillMountWarnings = [];
3056 pendingComponentWillReceivePropsWarnings = [];
3057 pendingComponentWillUpdateWarnings = [];
3058 pendingUnsafeLifecycleWarnings = new Map();
3059 pendingLegacyContextWarning = new Map();
3060 };
3061
3062 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
3063 pendingUnsafeLifecycleWarnings.forEach(function (lifecycleWarningsMap, strictRoot) {
3064 var lifecyclesWarningMessages = [];
3065
3066 Object.keys(lifecycleWarningsMap).forEach(function (lifecycle) {
3067 var lifecycleWarnings = lifecycleWarningsMap[lifecycle];
3068 if (lifecycleWarnings.length > 0) {
3069 var componentNames = new Set();
3070 lifecycleWarnings.forEach(function (fiber) {
3071 componentNames.add(getComponentName(fiber.type) || 'Component');
3072 didWarnAboutUnsafeLifecycles.add(fiber.type);
3073 });
3074
3075 var formatted = lifecycle.replace('UNSAFE_', '');
3076 var suggestion = LIFECYCLE_SUGGESTIONS[lifecycle];
3077 var sortedComponentNames = setToSortedString(componentNames);
3078
3079 lifecyclesWarningMessages.push(formatted + ': Please update the following components to use ' + (suggestion + ' instead: ' + sortedComponentNames));
3080 }
3081 });
3082
3083 if (lifecyclesWarningMessages.length > 0) {
3084 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3085
3086 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'));
3087 }
3088 });
3089
3090 pendingUnsafeLifecycleWarnings = new Map();
3091 };
3092
3093 var findStrictRoot = function (fiber) {
3094 var maybeStrictRoot = null;
3095
3096 var node = fiber;
3097 while (node !== null) {
3098 if (node.mode & StrictMode) {
3099 maybeStrictRoot = node;
3100 }
3101 node = node.return;
3102 }
3103
3104 return maybeStrictRoot;
3105 };
3106
3107 ReactStrictModeWarnings.flushPendingDeprecationWarnings = function () {
3108 if (pendingComponentWillMountWarnings.length > 0) {
3109 var uniqueNames = new Set();
3110 pendingComponentWillMountWarnings.forEach(function (fiber) {
3111 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3112 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3113 });
3114
3115 var sortedNames = setToSortedString(uniqueNames);
3116
3117 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);
3118
3119 pendingComponentWillMountWarnings = [];
3120 }
3121
3122 if (pendingComponentWillReceivePropsWarnings.length > 0) {
3123 var _uniqueNames = new Set();
3124 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
3125 _uniqueNames.add(getComponentName(fiber.type) || 'Component');
3126 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3127 });
3128
3129 var _sortedNames = setToSortedString(_uniqueNames);
3130
3131 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);
3132
3133 pendingComponentWillReceivePropsWarnings = [];
3134 }
3135
3136 if (pendingComponentWillUpdateWarnings.length > 0) {
3137 var _uniqueNames2 = new Set();
3138 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
3139 _uniqueNames2.add(getComponentName(fiber.type) || 'Component');
3140 didWarnAboutDeprecatedLifecycles.add(fiber.type);
3141 });
3142
3143 var _sortedNames2 = setToSortedString(_uniqueNames2);
3144
3145 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);
3146
3147 pendingComponentWillUpdateWarnings = [];
3148 }
3149 };
3150
3151 ReactStrictModeWarnings.recordDeprecationWarnings = function (fiber, instance) {
3152 // Dedup strategy: Warn once per component.
3153 if (didWarnAboutDeprecatedLifecycles.has(fiber.type)) {
3154 return;
3155 }
3156
3157 // Don't warn about react-lifecycles-compat polyfilled components.
3158 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3159 pendingComponentWillMountWarnings.push(fiber);
3160 }
3161 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3162 pendingComponentWillReceivePropsWarnings.push(fiber);
3163 }
3164 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3165 pendingComponentWillUpdateWarnings.push(fiber);
3166 }
3167 };
3168
3169 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
3170 var strictRoot = findStrictRoot(fiber);
3171 if (strictRoot === null) {
3172 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.');
3173 return;
3174 }
3175
3176 // Dedup strategy: Warn once per component.
3177 // This is difficult to track any other way since component names
3178 // are often vague and are likely to collide between 3rd party libraries.
3179 // An expand property is probably okay to use here since it's DEV-only,
3180 // and will only be set in the event of serious warnings.
3181 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
3182 return;
3183 }
3184
3185 var warningsForRoot = void 0;
3186 if (!pendingUnsafeLifecycleWarnings.has(strictRoot)) {
3187 warningsForRoot = {
3188 UNSAFE_componentWillMount: [],
3189 UNSAFE_componentWillReceiveProps: [],
3190 UNSAFE_componentWillUpdate: []
3191 };
3192
3193 pendingUnsafeLifecycleWarnings.set(strictRoot, warningsForRoot);
3194 } else {
3195 warningsForRoot = pendingUnsafeLifecycleWarnings.get(strictRoot);
3196 }
3197
3198 var unsafeLifecycles = [];
3199 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillMount === 'function') {
3200 unsafeLifecycles.push('UNSAFE_componentWillMount');
3201 }
3202 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3203 unsafeLifecycles.push('UNSAFE_componentWillReceiveProps');
3204 }
3205 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true || typeof instance.UNSAFE_componentWillUpdate === 'function') {
3206 unsafeLifecycles.push('UNSAFE_componentWillUpdate');
3207 }
3208
3209 if (unsafeLifecycles.length > 0) {
3210 unsafeLifecycles.forEach(function (lifecycle) {
3211 warningsForRoot[lifecycle].push(fiber);
3212 });
3213 }
3214 };
3215
3216 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
3217 var strictRoot = findStrictRoot(fiber);
3218 if (strictRoot === null) {
3219 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.');
3220 return;
3221 }
3222
3223 // Dedup strategy: Warn once per component.
3224 if (didWarnAboutLegacyContext.has(fiber.type)) {
3225 return;
3226 }
3227
3228 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
3229
3230 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
3231 if (warningsForRoot === undefined) {
3232 warningsForRoot = [];
3233 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
3234 }
3235 warningsForRoot.push(fiber);
3236 }
3237 };
3238
3239 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
3240 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
3241 var uniqueNames = new Set();
3242 fiberArray.forEach(function (fiber) {
3243 uniqueNames.add(getComponentName(fiber.type) || 'Component');
3244 didWarnAboutLegacyContext.add(fiber.type);
3245 });
3246
3247 var sortedNames = setToSortedString(uniqueNames);
3248 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
3249
3250 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);
3251 });
3252 };
3253}
3254
3255// This lets us hook into Fiber to debug what it's doing.
3256// See https://github.com/facebook/react/pull/8033.
3257// This is not part of the public API, not even for React DevTools.
3258// You may only inject a debugTool if you work on React Fiber itself.
3259var ReactFiberInstrumentation = {
3260 debugTool: null
3261};
3262
3263var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
3264
3265// TODO: Offscreen updates should never suspend. However, a promise that
3266// suspended inside an offscreen subtree should be able to ping at the priority
3267// of the outer render.
3268
3269function markPendingPriorityLevel(root, expirationTime) {
3270 // If there's a gap between completing a failed root and retrying it,
3271 // additional updates may be scheduled. Clear `didError`, in case the update
3272 // is sufficient to fix the error.
3273 root.didError = false;
3274
3275 // Update the latest and earliest pending times
3276 var earliestPendingTime = root.earliestPendingTime;
3277 if (earliestPendingTime === NoWork) {
3278 // No other pending updates.
3279 root.earliestPendingTime = root.latestPendingTime = expirationTime;
3280 } else {
3281 if (earliestPendingTime < expirationTime) {
3282 // This is the earliest pending update.
3283 root.earliestPendingTime = expirationTime;
3284 } else {
3285 var latestPendingTime = root.latestPendingTime;
3286 if (latestPendingTime > expirationTime) {
3287 // This is the latest pending update
3288 root.latestPendingTime = expirationTime;
3289 }
3290 }
3291 }
3292 findNextExpirationTimeToWorkOn(expirationTime, root);
3293}
3294
3295function markCommittedPriorityLevels(root, earliestRemainingTime) {
3296 root.didError = false;
3297
3298 if (earliestRemainingTime === NoWork) {
3299 // Fast path. There's no remaining work. Clear everything.
3300 root.earliestPendingTime = NoWork;
3301 root.latestPendingTime = NoWork;
3302 root.earliestSuspendedTime = NoWork;
3303 root.latestSuspendedTime = NoWork;
3304 root.latestPingedTime = NoWork;
3305 findNextExpirationTimeToWorkOn(NoWork, root);
3306 return;
3307 }
3308
3309 if (earliestRemainingTime < root.latestPingedTime) {
3310 root.latestPingedTime = NoWork;
3311 }
3312
3313 // Let's see if the previous latest known pending level was just flushed.
3314 var latestPendingTime = root.latestPendingTime;
3315 if (latestPendingTime !== NoWork) {
3316 if (latestPendingTime > earliestRemainingTime) {
3317 // We've flushed all the known pending levels.
3318 root.earliestPendingTime = root.latestPendingTime = NoWork;
3319 } else {
3320 var earliestPendingTime = root.earliestPendingTime;
3321 if (earliestPendingTime > earliestRemainingTime) {
3322 // We've flushed the earliest known pending level. Set this to the
3323 // latest pending time.
3324 root.earliestPendingTime = root.latestPendingTime;
3325 }
3326 }
3327 }
3328
3329 // Now let's handle the earliest remaining level in the whole tree. We need to
3330 // decide whether to treat it as a pending level or as suspended. Check
3331 // it falls within the range of known suspended levels.
3332
3333 var earliestSuspendedTime = root.earliestSuspendedTime;
3334 if (earliestSuspendedTime === NoWork) {
3335 // There's no suspended work. Treat the earliest remaining level as a
3336 // pending level.
3337 markPendingPriorityLevel(root, earliestRemainingTime);
3338 findNextExpirationTimeToWorkOn(NoWork, root);
3339 return;
3340 }
3341
3342 var latestSuspendedTime = root.latestSuspendedTime;
3343 if (earliestRemainingTime < latestSuspendedTime) {
3344 // The earliest remaining level is later than all the suspended work. That
3345 // means we've flushed all the suspended work.
3346 root.earliestSuspendedTime = NoWork;
3347 root.latestSuspendedTime = NoWork;
3348 root.latestPingedTime = NoWork;
3349
3350 // There's no suspended work. Treat the earliest remaining level as a
3351 // pending level.
3352 markPendingPriorityLevel(root, earliestRemainingTime);
3353 findNextExpirationTimeToWorkOn(NoWork, root);
3354 return;
3355 }
3356
3357 if (earliestRemainingTime > earliestSuspendedTime) {
3358 // The earliest remaining time is earlier than all the suspended work.
3359 // Treat it as a pending update.
3360 markPendingPriorityLevel(root, earliestRemainingTime);
3361 findNextExpirationTimeToWorkOn(NoWork, root);
3362 return;
3363 }
3364
3365 // The earliest remaining time falls within the range of known suspended
3366 // levels. We should treat this as suspended work.
3367 findNextExpirationTimeToWorkOn(NoWork, root);
3368}
3369
3370function hasLowerPriorityWork(root, erroredExpirationTime) {
3371 var latestPendingTime = root.latestPendingTime;
3372 var latestSuspendedTime = root.latestSuspendedTime;
3373 var latestPingedTime = root.latestPingedTime;
3374 return latestPendingTime !== NoWork && latestPendingTime < erroredExpirationTime || latestSuspendedTime !== NoWork && latestSuspendedTime < erroredExpirationTime || latestPingedTime !== NoWork && latestPingedTime < erroredExpirationTime;
3375}
3376
3377function isPriorityLevelSuspended(root, expirationTime) {
3378 var earliestSuspendedTime = root.earliestSuspendedTime;
3379 var latestSuspendedTime = root.latestSuspendedTime;
3380 return earliestSuspendedTime !== NoWork && expirationTime <= earliestSuspendedTime && expirationTime >= latestSuspendedTime;
3381}
3382
3383function markSuspendedPriorityLevel(root, suspendedTime) {
3384 root.didError = false;
3385 clearPing(root, suspendedTime);
3386
3387 // First, check the known pending levels and update them if needed.
3388 var earliestPendingTime = root.earliestPendingTime;
3389 var latestPendingTime = root.latestPendingTime;
3390 if (earliestPendingTime === suspendedTime) {
3391 if (latestPendingTime === suspendedTime) {
3392 // Both known pending levels were suspended. Clear them.
3393 root.earliestPendingTime = root.latestPendingTime = NoWork;
3394 } else {
3395 // The earliest pending level was suspended. Clear by setting it to the
3396 // latest pending level.
3397 root.earliestPendingTime = latestPendingTime;
3398 }
3399 } else if (latestPendingTime === suspendedTime) {
3400 // The latest pending level was suspended. Clear by setting it to the
3401 // latest pending level.
3402 root.latestPendingTime = earliestPendingTime;
3403 }
3404
3405 // Finally, update the known suspended levels.
3406 var earliestSuspendedTime = root.earliestSuspendedTime;
3407 var latestSuspendedTime = root.latestSuspendedTime;
3408 if (earliestSuspendedTime === NoWork) {
3409 // No other suspended levels.
3410 root.earliestSuspendedTime = root.latestSuspendedTime = suspendedTime;
3411 } else {
3412 if (earliestSuspendedTime < suspendedTime) {
3413 // This is the earliest suspended level.
3414 root.earliestSuspendedTime = suspendedTime;
3415 } else if (latestSuspendedTime > suspendedTime) {
3416 // This is the latest suspended level
3417 root.latestSuspendedTime = suspendedTime;
3418 }
3419 }
3420
3421 findNextExpirationTimeToWorkOn(suspendedTime, root);
3422}
3423
3424function markPingedPriorityLevel(root, pingedTime) {
3425 root.didError = false;
3426
3427 // TODO: When we add back resuming, we need to ensure the progressed work
3428 // is thrown out and not reused during the restarted render. One way to
3429 // invalidate the progressed work is to restart at expirationTime + 1.
3430 var latestPingedTime = root.latestPingedTime;
3431 if (latestPingedTime === NoWork || latestPingedTime > pingedTime) {
3432 root.latestPingedTime = pingedTime;
3433 }
3434 findNextExpirationTimeToWorkOn(pingedTime, root);
3435}
3436
3437function clearPing(root, completedTime) {
3438 var latestPingedTime = root.latestPingedTime;
3439 if (latestPingedTime >= completedTime) {
3440 root.latestPingedTime = NoWork;
3441 }
3442}
3443
3444function findEarliestOutstandingPriorityLevel(root, renderExpirationTime) {
3445 var earliestExpirationTime = renderExpirationTime;
3446
3447 var earliestPendingTime = root.earliestPendingTime;
3448 var earliestSuspendedTime = root.earliestSuspendedTime;
3449 if (earliestPendingTime > earliestExpirationTime) {
3450 earliestExpirationTime = earliestPendingTime;
3451 }
3452 if (earliestSuspendedTime > earliestExpirationTime) {
3453 earliestExpirationTime = earliestSuspendedTime;
3454 }
3455 return earliestExpirationTime;
3456}
3457
3458function didExpireAtExpirationTime(root, currentTime) {
3459 var expirationTime = root.expirationTime;
3460 if (expirationTime !== NoWork && currentTime <= expirationTime) {
3461 // The root has expired. Flush all work up to the current time.
3462 root.nextExpirationTimeToWorkOn = currentTime;
3463 }
3464}
3465
3466function findNextExpirationTimeToWorkOn(completedExpirationTime, root) {
3467 var earliestSuspendedTime = root.earliestSuspendedTime;
3468 var latestSuspendedTime = root.latestSuspendedTime;
3469 var earliestPendingTime = root.earliestPendingTime;
3470 var latestPingedTime = root.latestPingedTime;
3471
3472 // Work on the earliest pending time. Failing that, work on the latest
3473 // pinged time.
3474 var nextExpirationTimeToWorkOn = earliestPendingTime !== NoWork ? earliestPendingTime : latestPingedTime;
3475
3476 // If there is no pending or pinged work, check if there's suspended work
3477 // that's lower priority than what we just completed.
3478 if (nextExpirationTimeToWorkOn === NoWork && (completedExpirationTime === NoWork || latestSuspendedTime < completedExpirationTime)) {
3479 // The lowest priority suspended work is the work most likely to be
3480 // committed next. Let's start rendering it again, so that if it times out,
3481 // it's ready to commit.
3482 nextExpirationTimeToWorkOn = latestSuspendedTime;
3483 }
3484
3485 var expirationTime = nextExpirationTimeToWorkOn;
3486 if (expirationTime !== NoWork && earliestSuspendedTime > expirationTime) {
3487 // Expire using the earliest known expiration time.
3488 expirationTime = earliestSuspendedTime;
3489 }
3490
3491 root.nextExpirationTimeToWorkOn = nextExpirationTimeToWorkOn;
3492 root.expirationTime = expirationTime;
3493}
3494
3495/**
3496 * Similar to invariant but only logs a warning if the condition is not met.
3497 * This can be used to log issues in development environments in critical
3498 * paths. Removing the logging code for production environments will keep the
3499 * same logic and follow the same code paths.
3500 */
3501
3502var warning = warningWithoutStack$1;
3503
3504{
3505 warning = function (condition, format) {
3506 if (condition) {
3507 return;
3508 }
3509 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
3510 var stack = ReactDebugCurrentFrame.getStackAddendum();
3511 // eslint-disable-next-line react-internal/warning-and-invariant-args
3512
3513 for (var _len = arguments.length, args = Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
3514 args[_key - 2] = arguments[_key];
3515 }
3516
3517 warningWithoutStack$1.apply(undefined, [false, format + '%s'].concat(args, [stack]));
3518 };
3519}
3520
3521var warning$1 = warning;
3522
3523/**
3524 * inlined Object.is polyfill to avoid requiring consumers ship their own
3525 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
3526 */
3527function is(x, y) {
3528 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
3529 ;
3530}
3531
3532var hasOwnProperty = Object.prototype.hasOwnProperty;
3533
3534/**
3535 * Performs equality by iterating through keys on an object and returning false
3536 * when any key has values which are not strictly equal between the arguments.
3537 * Returns true when the values of all keys are strictly equal.
3538 */
3539function shallowEqual(objA, objB) {
3540 if (is(objA, objB)) {
3541 return true;
3542 }
3543
3544 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
3545 return false;
3546 }
3547
3548 var keysA = Object.keys(objA);
3549 var keysB = Object.keys(objB);
3550
3551 if (keysA.length !== keysB.length) {
3552 return false;
3553 }
3554
3555 // Test for A's keys different from B.
3556 for (var i = 0; i < keysA.length; i++) {
3557 if (!hasOwnProperty.call(objB, keysA[i]) || !is(objA[keysA[i]], objB[keysA[i]])) {
3558 return false;
3559 }
3560 }
3561
3562 return true;
3563}
3564
3565function resolveDefaultProps(Component, baseProps) {
3566 if (Component && Component.defaultProps) {
3567 // Resolve default props. Taken from ReactElement
3568 var props = _assign({}, baseProps);
3569 var defaultProps = Component.defaultProps;
3570 for (var propName in defaultProps) {
3571 if (props[propName] === undefined) {
3572 props[propName] = defaultProps[propName];
3573 }
3574 }
3575 return props;
3576 }
3577 return baseProps;
3578}
3579
3580function readLazyComponentType(lazyComponent) {
3581 var status = lazyComponent._status;
3582 var result = lazyComponent._result;
3583 switch (status) {
3584 case Resolved:
3585 {
3586 var Component = result;
3587 return Component;
3588 }
3589 case Rejected:
3590 {
3591 var error = result;
3592 throw error;
3593 }
3594 case Pending:
3595 {
3596 var thenable = result;
3597 throw thenable;
3598 }
3599 default:
3600 {
3601 lazyComponent._status = Pending;
3602 var ctor = lazyComponent._ctor;
3603 var _thenable = ctor();
3604 _thenable.then(function (moduleObject) {
3605 if (lazyComponent._status === Pending) {
3606 var defaultExport = moduleObject.default;
3607 {
3608 if (defaultExport === undefined) {
3609 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);
3610 }
3611 }
3612 lazyComponent._status = Resolved;
3613 lazyComponent._result = defaultExport;
3614 }
3615 }, function (error) {
3616 if (lazyComponent._status === Pending) {
3617 lazyComponent._status = Rejected;
3618 lazyComponent._result = error;
3619 }
3620 });
3621 // Handle synchronous thenables.
3622 switch (lazyComponent._status) {
3623 case Resolved:
3624 return lazyComponent._result;
3625 case Rejected:
3626 throw lazyComponent._result;
3627 }
3628 lazyComponent._result = _thenable;
3629 throw _thenable;
3630 }
3631 }
3632}
3633
3634var fakeInternalInstance = {};
3635var isArray$1 = Array.isArray;
3636
3637// React.Component uses a shared frozen object by default.
3638// We'll use it to determine whether we need to initialize legacy refs.
3639var emptyRefsObject = new React.Component().refs;
3640
3641var didWarnAboutStateAssignmentForComponent = void 0;
3642var didWarnAboutUninitializedState = void 0;
3643var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = void 0;
3644var didWarnAboutLegacyLifecyclesAndDerivedState = void 0;
3645var didWarnAboutUndefinedDerivedState = void 0;
3646var warnOnUndefinedDerivedState = void 0;
3647var warnOnInvalidCallback = void 0;
3648var didWarnAboutDirectlyAssigningPropsToState = void 0;
3649var didWarnAboutContextTypeAndContextTypes = void 0;
3650var didWarnAboutInvalidateContextType = void 0;
3651
3652{
3653 didWarnAboutStateAssignmentForComponent = new Set();
3654 didWarnAboutUninitializedState = new Set();
3655 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
3656 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
3657 didWarnAboutDirectlyAssigningPropsToState = new Set();
3658 didWarnAboutUndefinedDerivedState = new Set();
3659 didWarnAboutContextTypeAndContextTypes = new Set();
3660 didWarnAboutInvalidateContextType = new Set();
3661
3662 var didWarnOnInvalidCallback = new Set();
3663
3664 warnOnInvalidCallback = function (callback, callerName) {
3665 if (callback === null || typeof callback === 'function') {
3666 return;
3667 }
3668 var key = callerName + '_' + callback;
3669 if (!didWarnOnInvalidCallback.has(key)) {
3670 didWarnOnInvalidCallback.add(key);
3671 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
3672 }
3673 };
3674
3675 warnOnUndefinedDerivedState = function (type, partialState) {
3676 if (partialState === undefined) {
3677 var componentName = getComponentName(type) || 'Component';
3678 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
3679 didWarnAboutUndefinedDerivedState.add(componentName);
3680 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
3681 }
3682 }
3683 };
3684
3685 // This is so gross but it's at least non-critical and can be removed if
3686 // it causes problems. This is meant to give a nicer error message for
3687 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
3688 // ...)) which otherwise throws a "_processChildContext is not a function"
3689 // exception.
3690 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
3691 enumerable: false,
3692 value: function () {
3693 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).');
3694 }
3695 });
3696 Object.freeze(fakeInternalInstance);
3697}
3698
3699function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
3700 var prevState = workInProgress.memoizedState;
3701
3702 {
3703 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3704 // Invoke the function an extra time to help detect side-effects.
3705 getDerivedStateFromProps(nextProps, prevState);
3706 }
3707 }
3708
3709 var partialState = getDerivedStateFromProps(nextProps, prevState);
3710
3711 {
3712 warnOnUndefinedDerivedState(ctor, partialState);
3713 }
3714 // Merge the partial state and the previous state.
3715 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
3716 workInProgress.memoizedState = memoizedState;
3717
3718 // Once the update queue is empty, persist the derived state onto the
3719 // base state.
3720 var updateQueue = workInProgress.updateQueue;
3721 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
3722 updateQueue.baseState = memoizedState;
3723 }
3724}
3725
3726var classComponentUpdater = {
3727 isMounted: isMounted,
3728 enqueueSetState: function (inst, payload, callback) {
3729 var fiber = get(inst);
3730 var currentTime = requestCurrentTime();
3731 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3732
3733 var update = createUpdate(expirationTime);
3734 update.payload = payload;
3735 if (callback !== undefined && callback !== null) {
3736 {
3737 warnOnInvalidCallback(callback, 'setState');
3738 }
3739 update.callback = callback;
3740 }
3741
3742 flushPassiveEffects();
3743 enqueueUpdate(fiber, update);
3744 scheduleWork(fiber, expirationTime);
3745 },
3746 enqueueReplaceState: function (inst, payload, callback) {
3747 var fiber = get(inst);
3748 var currentTime = requestCurrentTime();
3749 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3750
3751 var update = createUpdate(expirationTime);
3752 update.tag = ReplaceState;
3753 update.payload = payload;
3754
3755 if (callback !== undefined && callback !== null) {
3756 {
3757 warnOnInvalidCallback(callback, 'replaceState');
3758 }
3759 update.callback = callback;
3760 }
3761
3762 flushPassiveEffects();
3763 enqueueUpdate(fiber, update);
3764 scheduleWork(fiber, expirationTime);
3765 },
3766 enqueueForceUpdate: function (inst, callback) {
3767 var fiber = get(inst);
3768 var currentTime = requestCurrentTime();
3769 var expirationTime = computeExpirationForFiber(currentTime, fiber);
3770
3771 var update = createUpdate(expirationTime);
3772 update.tag = ForceUpdate;
3773
3774 if (callback !== undefined && callback !== null) {
3775 {
3776 warnOnInvalidCallback(callback, 'forceUpdate');
3777 }
3778 update.callback = callback;
3779 }
3780
3781 flushPassiveEffects();
3782 enqueueUpdate(fiber, update);
3783 scheduleWork(fiber, expirationTime);
3784 }
3785};
3786
3787function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
3788 var instance = workInProgress.stateNode;
3789 if (typeof instance.shouldComponentUpdate === 'function') {
3790 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
3791 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
3792 stopPhaseTimer();
3793
3794 {
3795 !(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;
3796 }
3797
3798 return shouldUpdate;
3799 }
3800
3801 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
3802 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
3803 }
3804
3805 return true;
3806}
3807
3808function checkClassInstance(workInProgress, ctor, newProps) {
3809 var instance = workInProgress.stateNode;
3810 {
3811 var name = getComponentName(ctor) || 'Component';
3812 var renderPresent = instance.render;
3813
3814 if (!renderPresent) {
3815 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
3816 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
3817 } else {
3818 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
3819 }
3820 }
3821
3822 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
3823 !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;
3824 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
3825 !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;
3826 var noInstancePropTypes = !instance.propTypes;
3827 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
3828 var noInstanceContextType = !instance.contextType;
3829 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
3830 var noInstanceContextTypes = !instance.contextTypes;
3831 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
3832
3833 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
3834 didWarnAboutContextTypeAndContextTypes.add(ctor);
3835 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
3836 }
3837
3838 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
3839 !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;
3840 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
3841 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');
3842 }
3843 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
3844 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
3845 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
3846 !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;
3847 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
3848 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
3849 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
3850 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
3851 var hasMutatedProps = instance.props !== newProps;
3852 !(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;
3853 var noInstanceDefaultProps = !instance.defaultProps;
3854 !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;
3855
3856 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
3857 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
3858 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
3859 }
3860
3861 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
3862 !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;
3863 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
3864 !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;
3865 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
3866 !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;
3867 var _state = instance.state;
3868 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
3869 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
3870 }
3871 if (typeof instance.getChildContext === 'function') {
3872 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
3873 }
3874 }
3875}
3876
3877function adoptClassInstance(workInProgress, instance) {
3878 instance.updater = classComponentUpdater;
3879 workInProgress.stateNode = instance;
3880 // The instance needs access to the fiber so that it can schedule updates
3881 set(instance, workInProgress);
3882 {
3883 instance._reactInternalInstance = fakeInternalInstance;
3884 }
3885}
3886
3887function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
3888 var isLegacyContextConsumer = false;
3889 var unmaskedContext = emptyContextObject;
3890 var context = null;
3891 var contextType = ctor.contextType;
3892 if (typeof contextType === 'object' && contextType !== null) {
3893 {
3894 if (contextType.$$typeof !== REACT_CONTEXT_TYPE && !didWarnAboutInvalidateContextType.has(ctor)) {
3895 didWarnAboutInvalidateContextType.add(ctor);
3896 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');
3897 }
3898 }
3899
3900 context = readContext(contextType);
3901 } else {
3902 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
3903 var contextTypes = ctor.contextTypes;
3904 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
3905 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
3906 }
3907
3908 // Instantiate twice to help detect side-effects.
3909 {
3910 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
3911 new ctor(props, context); // eslint-disable-line no-new
3912 }
3913 }
3914
3915 var instance = new ctor(props, context);
3916 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
3917 adoptClassInstance(workInProgress, instance);
3918
3919 {
3920 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
3921 var componentName = getComponentName(ctor) || 'Component';
3922 if (!didWarnAboutUninitializedState.has(componentName)) {
3923 didWarnAboutUninitializedState.add(componentName);
3924 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);
3925 }
3926 }
3927
3928 // If new component APIs are defined, "unsafe" lifecycles won't be called.
3929 // Warn about these lifecycles if they are present.
3930 // Don't warn about react-lifecycles-compat polyfilled methods though.
3931 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
3932 var foundWillMountName = null;
3933 var foundWillReceivePropsName = null;
3934 var foundWillUpdateName = null;
3935 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
3936 foundWillMountName = 'componentWillMount';
3937 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
3938 foundWillMountName = 'UNSAFE_componentWillMount';
3939 }
3940 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
3941 foundWillReceivePropsName = 'componentWillReceiveProps';
3942 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3943 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
3944 }
3945 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
3946 foundWillUpdateName = 'componentWillUpdate';
3947 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
3948 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
3949 }
3950 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
3951 var _componentName = getComponentName(ctor) || 'Component';
3952 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
3953 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
3954 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
3955 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 : '');
3956 }
3957 }
3958 }
3959 }
3960
3961 // Cache unmasked context so we can avoid recreating masked context unless necessary.
3962 // ReactFiberContext usually updates this cache but can't for newly-created instances.
3963 if (isLegacyContextConsumer) {
3964 cacheContext(workInProgress, unmaskedContext, context);
3965 }
3966
3967 return instance;
3968}
3969
3970function callComponentWillMount(workInProgress, instance) {
3971 startPhaseTimer(workInProgress, 'componentWillMount');
3972 var oldState = instance.state;
3973
3974 if (typeof instance.componentWillMount === 'function') {
3975 instance.componentWillMount();
3976 }
3977 if (typeof instance.UNSAFE_componentWillMount === 'function') {
3978 instance.UNSAFE_componentWillMount();
3979 }
3980
3981 stopPhaseTimer();
3982
3983 if (oldState !== instance.state) {
3984 {
3985 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');
3986 }
3987 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
3988 }
3989}
3990
3991function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
3992 var oldState = instance.state;
3993 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
3994 if (typeof instance.componentWillReceiveProps === 'function') {
3995 instance.componentWillReceiveProps(newProps, nextContext);
3996 }
3997 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
3998 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
3999 }
4000 stopPhaseTimer();
4001
4002 if (instance.state !== oldState) {
4003 {
4004 var componentName = getComponentName(workInProgress.type) || 'Component';
4005 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
4006 didWarnAboutStateAssignmentForComponent.add(componentName);
4007 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
4008 }
4009 }
4010 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
4011 }
4012}
4013
4014// Invokes the mount life-cycles on a previously never rendered instance.
4015function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4016 {
4017 checkClassInstance(workInProgress, ctor, newProps);
4018 }
4019
4020 var instance = workInProgress.stateNode;
4021 instance.props = newProps;
4022 instance.state = workInProgress.memoizedState;
4023 instance.refs = emptyRefsObject;
4024
4025 var contextType = ctor.contextType;
4026 if (typeof contextType === 'object' && contextType !== null) {
4027 instance.context = readContext(contextType);
4028 } else {
4029 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4030 instance.context = getMaskedContext(workInProgress, unmaskedContext);
4031 }
4032
4033 {
4034 if (instance.state === newProps) {
4035 var componentName = getComponentName(ctor) || 'Component';
4036 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
4037 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
4038 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);
4039 }
4040 }
4041
4042 if (workInProgress.mode & StrictMode) {
4043 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
4044
4045 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
4046 }
4047
4048 if (warnAboutDeprecatedLifecycles) {
4049 ReactStrictModeWarnings.recordDeprecationWarnings(workInProgress, instance);
4050 }
4051 }
4052
4053 var updateQueue = workInProgress.updateQueue;
4054 if (updateQueue !== null) {
4055 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4056 instance.state = workInProgress.memoizedState;
4057 }
4058
4059 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4060 if (typeof getDerivedStateFromProps === 'function') {
4061 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4062 instance.state = workInProgress.memoizedState;
4063 }
4064
4065 // In order to support react-lifecycles-compat polyfilled components,
4066 // Unsafe lifecycles should not be invoked for components using the new APIs.
4067 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4068 callComponentWillMount(workInProgress, instance);
4069 // If we had additional state updates during this life-cycle, let's
4070 // process them now.
4071 updateQueue = workInProgress.updateQueue;
4072 if (updateQueue !== null) {
4073 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4074 instance.state = workInProgress.memoizedState;
4075 }
4076 }
4077
4078 if (typeof instance.componentDidMount === 'function') {
4079 workInProgress.effectTag |= Update;
4080 }
4081}
4082
4083function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
4084 var instance = workInProgress.stateNode;
4085
4086 var oldProps = workInProgress.memoizedProps;
4087 instance.props = oldProps;
4088
4089 var oldContext = instance.context;
4090 var contextType = ctor.contextType;
4091 var nextContext = void 0;
4092 if (typeof contextType === 'object' && contextType !== null) {
4093 nextContext = readContext(contextType);
4094 } else {
4095 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4096 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
4097 }
4098
4099 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4100 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4101
4102 // Note: During these life-cycles, instance.props/instance.state are what
4103 // ever the previously attempted to render - not the "current". However,
4104 // during componentDidUpdate we pass the "current" props.
4105
4106 // In order to support react-lifecycles-compat polyfilled components,
4107 // Unsafe lifecycles should not be invoked for components using the new APIs.
4108 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4109 if (oldProps !== newProps || oldContext !== nextContext) {
4110 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4111 }
4112 }
4113
4114 resetHasForceUpdateBeforeProcessing();
4115
4116 var oldState = workInProgress.memoizedState;
4117 var newState = instance.state = oldState;
4118 var updateQueue = workInProgress.updateQueue;
4119 if (updateQueue !== null) {
4120 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4121 newState = workInProgress.memoizedState;
4122 }
4123 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4124 // If an update was already in progress, we should schedule an Update
4125 // effect even though we're bailing out, so that cWU/cDU are called.
4126 if (typeof instance.componentDidMount === 'function') {
4127 workInProgress.effectTag |= Update;
4128 }
4129 return false;
4130 }
4131
4132 if (typeof getDerivedStateFromProps === 'function') {
4133 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4134 newState = workInProgress.memoizedState;
4135 }
4136
4137 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4138
4139 if (shouldUpdate) {
4140 // In order to support react-lifecycles-compat polyfilled components,
4141 // Unsafe lifecycles should not be invoked for components using the new APIs.
4142 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
4143 startPhaseTimer(workInProgress, 'componentWillMount');
4144 if (typeof instance.componentWillMount === 'function') {
4145 instance.componentWillMount();
4146 }
4147 if (typeof instance.UNSAFE_componentWillMount === 'function') {
4148 instance.UNSAFE_componentWillMount();
4149 }
4150 stopPhaseTimer();
4151 }
4152 if (typeof instance.componentDidMount === 'function') {
4153 workInProgress.effectTag |= Update;
4154 }
4155 } else {
4156 // If an update was already in progress, we should schedule an Update
4157 // effect even though we're bailing out, so that cWU/cDU are called.
4158 if (typeof instance.componentDidMount === 'function') {
4159 workInProgress.effectTag |= Update;
4160 }
4161
4162 // If shouldComponentUpdate returned false, we should still update the
4163 // memoized state to indicate that this work can be reused.
4164 workInProgress.memoizedProps = newProps;
4165 workInProgress.memoizedState = newState;
4166 }
4167
4168 // Update the existing instance's state, props, and context pointers even
4169 // if shouldComponentUpdate returns false.
4170 instance.props = newProps;
4171 instance.state = newState;
4172 instance.context = nextContext;
4173
4174 return shouldUpdate;
4175}
4176
4177// Invokes the update life-cycles and returns false if it shouldn't rerender.
4178function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
4179 var instance = workInProgress.stateNode;
4180
4181 var oldProps = workInProgress.memoizedProps;
4182 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
4183
4184 var oldContext = instance.context;
4185 var contextType = ctor.contextType;
4186 var nextContext = void 0;
4187 if (typeof contextType === 'object' && contextType !== null) {
4188 nextContext = readContext(contextType);
4189 } else {
4190 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
4191 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
4192 }
4193
4194 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
4195 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function';
4196
4197 // Note: During these life-cycles, instance.props/instance.state are what
4198 // ever the previously attempted to render - not the "current". However,
4199 // during componentDidUpdate we pass the "current" props.
4200
4201 // In order to support react-lifecycles-compat polyfilled components,
4202 // Unsafe lifecycles should not be invoked for components using the new APIs.
4203 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
4204 if (oldProps !== newProps || oldContext !== nextContext) {
4205 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
4206 }
4207 }
4208
4209 resetHasForceUpdateBeforeProcessing();
4210
4211 var oldState = workInProgress.memoizedState;
4212 var newState = instance.state = oldState;
4213 var updateQueue = workInProgress.updateQueue;
4214 if (updateQueue !== null) {
4215 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
4216 newState = workInProgress.memoizedState;
4217 }
4218
4219 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
4220 // If an update was already in progress, we should schedule an Update
4221 // effect even though we're bailing out, so that cWU/cDU are called.
4222 if (typeof instance.componentDidUpdate === 'function') {
4223 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4224 workInProgress.effectTag |= Update;
4225 }
4226 }
4227 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4228 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4229 workInProgress.effectTag |= Snapshot;
4230 }
4231 }
4232 return false;
4233 }
4234
4235 if (typeof getDerivedStateFromProps === 'function') {
4236 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
4237 newState = workInProgress.memoizedState;
4238 }
4239
4240 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
4241
4242 if (shouldUpdate) {
4243 // In order to support react-lifecycles-compat polyfilled components,
4244 // Unsafe lifecycles should not be invoked for components using the new APIs.
4245 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
4246 startPhaseTimer(workInProgress, 'componentWillUpdate');
4247 if (typeof instance.componentWillUpdate === 'function') {
4248 instance.componentWillUpdate(newProps, newState, nextContext);
4249 }
4250 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
4251 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
4252 }
4253 stopPhaseTimer();
4254 }
4255 if (typeof instance.componentDidUpdate === 'function') {
4256 workInProgress.effectTag |= Update;
4257 }
4258 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4259 workInProgress.effectTag |= Snapshot;
4260 }
4261 } else {
4262 // If an update was already in progress, we should schedule an Update
4263 // effect even though we're bailing out, so that cWU/cDU are called.
4264 if (typeof instance.componentDidUpdate === 'function') {
4265 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4266 workInProgress.effectTag |= Update;
4267 }
4268 }
4269 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
4270 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
4271 workInProgress.effectTag |= Snapshot;
4272 }
4273 }
4274
4275 // If shouldComponentUpdate returned false, we should still update the
4276 // memoized props/state to indicate that this work can be reused.
4277 workInProgress.memoizedProps = newProps;
4278 workInProgress.memoizedState = newState;
4279 }
4280
4281 // Update the existing instance's state, props, and context pointers even
4282 // if shouldComponentUpdate returns false.
4283 instance.props = newProps;
4284 instance.state = newState;
4285 instance.context = nextContext;
4286
4287 return shouldUpdate;
4288}
4289
4290var didWarnAboutMaps = void 0;
4291var didWarnAboutGenerators = void 0;
4292var didWarnAboutStringRefInStrictMode = void 0;
4293var ownerHasKeyUseWarning = void 0;
4294var ownerHasFunctionTypeWarning = void 0;
4295var warnForMissingKey = function (child) {};
4296
4297{
4298 didWarnAboutMaps = false;
4299 didWarnAboutGenerators = false;
4300 didWarnAboutStringRefInStrictMode = {};
4301
4302 /**
4303 * Warn if there's no key explicitly set on dynamic arrays of children or
4304 * object keys are not valid. This allows us to keep track of children between
4305 * updates.
4306 */
4307 ownerHasKeyUseWarning = {};
4308 ownerHasFunctionTypeWarning = {};
4309
4310 warnForMissingKey = function (child) {
4311 if (child === null || typeof child !== 'object') {
4312 return;
4313 }
4314 if (!child._store || child._store.validated || child.key != null) {
4315 return;
4316 }
4317 !(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;
4318 child._store.validated = true;
4319
4320 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
4321 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
4322 return;
4323 }
4324 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
4325
4326 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
4327 };
4328}
4329
4330var isArray = Array.isArray;
4331
4332function coerceRef(returnFiber, current, element) {
4333 var mixedRef = element.ref;
4334 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
4335 {
4336 if (returnFiber.mode & StrictMode) {
4337 var componentName = getComponentName(returnFiber.type) || 'Component';
4338 if (!didWarnAboutStringRefInStrictMode[componentName]) {
4339 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));
4340 didWarnAboutStringRefInStrictMode[componentName] = true;
4341 }
4342 }
4343 }
4344
4345 if (element._owner) {
4346 var owner = element._owner;
4347 var inst = void 0;
4348 if (owner) {
4349 var ownerFiber = owner;
4350 !(ownerFiber.tag === ClassComponent) ? invariant(false, 'Function components cannot have refs. Did you mean to use React.forwardRef()?') : void 0;
4351 inst = ownerFiber.stateNode;
4352 }
4353 !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;
4354 var stringRef = '' + mixedRef;
4355 // Check if previous string ref matches new string ref
4356 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
4357 return current.ref;
4358 }
4359 var ref = function (value) {
4360 var refs = inst.refs;
4361 if (refs === emptyRefsObject) {
4362 // This is a lazy pooled frozen object, so we need to initialize.
4363 refs = inst.refs = {};
4364 }
4365 if (value === null) {
4366 delete refs[stringRef];
4367 } else {
4368 refs[stringRef] = value;
4369 }
4370 };
4371 ref._stringRef = stringRef;
4372 return ref;
4373 } else {
4374 !(typeof mixedRef === 'string') ? invariant(false, 'Expected ref to be a function, a string, an object returned by React.createRef(), or null.') : void 0;
4375 !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;
4376 }
4377 }
4378 return mixedRef;
4379}
4380
4381function throwOnInvalidObjectType(returnFiber, newChild) {
4382 if (returnFiber.type !== 'textarea') {
4383 var addendum = '';
4384 {
4385 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
4386 }
4387 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);
4388 }
4389}
4390
4391function warnOnFunctionType() {
4392 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();
4393
4394 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
4395 return;
4396 }
4397 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
4398
4399 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.');
4400}
4401
4402// This wrapper function exists because I expect to clone the code in each path
4403// to be able to optimize each path individually by branching early. This needs
4404// a compiler or we can do it manually. Helpers that don't need this branching
4405// live outside of this function.
4406function ChildReconciler(shouldTrackSideEffects) {
4407 function deleteChild(returnFiber, childToDelete) {
4408 if (!shouldTrackSideEffects) {
4409 // Noop.
4410 return;
4411 }
4412 // Deletions are added in reversed order so we add it to the front.
4413 // At this point, the return fiber's effect list is empty except for
4414 // deletions, so we can just append the deletion to the list. The remaining
4415 // effects aren't added until the complete phase. Once we implement
4416 // resuming, this may not be true.
4417 var last = returnFiber.lastEffect;
4418 if (last !== null) {
4419 last.nextEffect = childToDelete;
4420 returnFiber.lastEffect = childToDelete;
4421 } else {
4422 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
4423 }
4424 childToDelete.nextEffect = null;
4425 childToDelete.effectTag = Deletion;
4426 }
4427
4428 function deleteRemainingChildren(returnFiber, currentFirstChild) {
4429 if (!shouldTrackSideEffects) {
4430 // Noop.
4431 return null;
4432 }
4433
4434 // TODO: For the shouldClone case, this could be micro-optimized a bit by
4435 // assuming that after the first child we've already added everything.
4436 var childToDelete = currentFirstChild;
4437 while (childToDelete !== null) {
4438 deleteChild(returnFiber, childToDelete);
4439 childToDelete = childToDelete.sibling;
4440 }
4441 return null;
4442 }
4443
4444 function mapRemainingChildren(returnFiber, currentFirstChild) {
4445 // Add the remaining children to a temporary map so that we can find them by
4446 // keys quickly. Implicit (null) keys get added to this set with their index
4447 var existingChildren = new Map();
4448
4449 var existingChild = currentFirstChild;
4450 while (existingChild !== null) {
4451 if (existingChild.key !== null) {
4452 existingChildren.set(existingChild.key, existingChild);
4453 } else {
4454 existingChildren.set(existingChild.index, existingChild);
4455 }
4456 existingChild = existingChild.sibling;
4457 }
4458 return existingChildren;
4459 }
4460
4461 function useFiber(fiber, pendingProps, expirationTime) {
4462 // We currently set sibling to null and index to 0 here because it is easy
4463 // to forget to do before returning it. E.g. for the single child case.
4464 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
4465 clone.index = 0;
4466 clone.sibling = null;
4467 return clone;
4468 }
4469
4470 function placeChild(newFiber, lastPlacedIndex, newIndex) {
4471 newFiber.index = newIndex;
4472 if (!shouldTrackSideEffects) {
4473 // Noop.
4474 return lastPlacedIndex;
4475 }
4476 var current = newFiber.alternate;
4477 if (current !== null) {
4478 var oldIndex = current.index;
4479 if (oldIndex < lastPlacedIndex) {
4480 // This is a move.
4481 newFiber.effectTag = Placement;
4482 return lastPlacedIndex;
4483 } else {
4484 // This item can stay in place.
4485 return oldIndex;
4486 }
4487 } else {
4488 // This is an insertion.
4489 newFiber.effectTag = Placement;
4490 return lastPlacedIndex;
4491 }
4492 }
4493
4494 function placeSingleChild(newFiber) {
4495 // This is simpler for the single child case. We only need to do a
4496 // placement for inserting new children.
4497 if (shouldTrackSideEffects && newFiber.alternate === null) {
4498 newFiber.effectTag = Placement;
4499 }
4500 return newFiber;
4501 }
4502
4503 function updateTextNode(returnFiber, current, textContent, expirationTime) {
4504 if (current === null || current.tag !== HostText) {
4505 // Insert
4506 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
4507 created.return = returnFiber;
4508 return created;
4509 } else {
4510 // Update
4511 var existing = useFiber(current, textContent, expirationTime);
4512 existing.return = returnFiber;
4513 return existing;
4514 }
4515 }
4516
4517 function updateElement(returnFiber, current, element, expirationTime) {
4518 if (current !== null && current.elementType === element.type) {
4519 // Move based on index
4520 var existing = useFiber(current, element.props, expirationTime);
4521 existing.ref = coerceRef(returnFiber, current, element);
4522 existing.return = returnFiber;
4523 {
4524 existing._debugSource = element._source;
4525 existing._debugOwner = element._owner;
4526 }
4527 return existing;
4528 } else {
4529 // Insert
4530 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
4531 created.ref = coerceRef(returnFiber, current, element);
4532 created.return = returnFiber;
4533 return created;
4534 }
4535 }
4536
4537 function updatePortal(returnFiber, current, portal, expirationTime) {
4538 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
4539 // Insert
4540 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
4541 created.return = returnFiber;
4542 return created;
4543 } else {
4544 // Update
4545 var existing = useFiber(current, portal.children || [], expirationTime);
4546 existing.return = returnFiber;
4547 return existing;
4548 }
4549 }
4550
4551 function updateFragment(returnFiber, current, fragment, expirationTime, key) {
4552 if (current === null || current.tag !== Fragment) {
4553 // Insert
4554 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
4555 created.return = returnFiber;
4556 return created;
4557 } else {
4558 // Update
4559 var existing = useFiber(current, fragment, expirationTime);
4560 existing.return = returnFiber;
4561 return existing;
4562 }
4563 }
4564
4565 function createChild(returnFiber, newChild, expirationTime) {
4566 if (typeof newChild === 'string' || typeof newChild === 'number') {
4567 // Text nodes don't have keys. If the previous node is implicitly keyed
4568 // we can continue to replace it without aborting even if it is not a text
4569 // node.
4570 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
4571 created.return = returnFiber;
4572 return created;
4573 }
4574
4575 if (typeof newChild === 'object' && newChild !== null) {
4576 switch (newChild.$$typeof) {
4577 case REACT_ELEMENT_TYPE:
4578 {
4579 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
4580 _created.ref = coerceRef(returnFiber, null, newChild);
4581 _created.return = returnFiber;
4582 return _created;
4583 }
4584 case REACT_PORTAL_TYPE:
4585 {
4586 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
4587 _created2.return = returnFiber;
4588 return _created2;
4589 }
4590 }
4591
4592 if (isArray(newChild) || getIteratorFn(newChild)) {
4593 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
4594 _created3.return = returnFiber;
4595 return _created3;
4596 }
4597
4598 throwOnInvalidObjectType(returnFiber, newChild);
4599 }
4600
4601 {
4602 if (typeof newChild === 'function') {
4603 warnOnFunctionType();
4604 }
4605 }
4606
4607 return null;
4608 }
4609
4610 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
4611 // Update the fiber if the keys match, otherwise return null.
4612
4613 var key = oldFiber !== null ? oldFiber.key : null;
4614
4615 if (typeof newChild === 'string' || typeof newChild === 'number') {
4616 // Text nodes don't have keys. If the previous node is implicitly keyed
4617 // we can continue to replace it without aborting even if it is not a text
4618 // node.
4619 if (key !== null) {
4620 return null;
4621 }
4622 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
4623 }
4624
4625 if (typeof newChild === 'object' && newChild !== null) {
4626 switch (newChild.$$typeof) {
4627 case REACT_ELEMENT_TYPE:
4628 {
4629 if (newChild.key === key) {
4630 if (newChild.type === REACT_FRAGMENT_TYPE) {
4631 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
4632 }
4633 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
4634 } else {
4635 return null;
4636 }
4637 }
4638 case REACT_PORTAL_TYPE:
4639 {
4640 if (newChild.key === key) {
4641 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
4642 } else {
4643 return null;
4644 }
4645 }
4646 }
4647
4648 if (isArray(newChild) || getIteratorFn(newChild)) {
4649 if (key !== null) {
4650 return null;
4651 }
4652
4653 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
4654 }
4655
4656 throwOnInvalidObjectType(returnFiber, newChild);
4657 }
4658
4659 {
4660 if (typeof newChild === 'function') {
4661 warnOnFunctionType();
4662 }
4663 }
4664
4665 return null;
4666 }
4667
4668 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
4669 if (typeof newChild === 'string' || typeof newChild === 'number') {
4670 // Text nodes don't have keys, so we neither have to check the old nor
4671 // new node for the key. If both are text nodes, they match.
4672 var matchedFiber = existingChildren.get(newIdx) || null;
4673 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
4674 }
4675
4676 if (typeof newChild === 'object' && newChild !== null) {
4677 switch (newChild.$$typeof) {
4678 case REACT_ELEMENT_TYPE:
4679 {
4680 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4681 if (newChild.type === REACT_FRAGMENT_TYPE) {
4682 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
4683 }
4684 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
4685 }
4686 case REACT_PORTAL_TYPE:
4687 {
4688 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
4689 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
4690 }
4691 }
4692
4693 if (isArray(newChild) || getIteratorFn(newChild)) {
4694 var _matchedFiber3 = existingChildren.get(newIdx) || null;
4695 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
4696 }
4697
4698 throwOnInvalidObjectType(returnFiber, newChild);
4699 }
4700
4701 {
4702 if (typeof newChild === 'function') {
4703 warnOnFunctionType();
4704 }
4705 }
4706
4707 return null;
4708 }
4709
4710 /**
4711 * Warns if there is a duplicate or missing key
4712 */
4713 function warnOnInvalidKey(child, knownKeys) {
4714 {
4715 if (typeof child !== 'object' || child === null) {
4716 return knownKeys;
4717 }
4718 switch (child.$$typeof) {
4719 case REACT_ELEMENT_TYPE:
4720 case REACT_PORTAL_TYPE:
4721 warnForMissingKey(child);
4722 var key = child.key;
4723 if (typeof key !== 'string') {
4724 break;
4725 }
4726 if (knownKeys === null) {
4727 knownKeys = new Set();
4728 knownKeys.add(key);
4729 break;
4730 }
4731 if (!knownKeys.has(key)) {
4732 knownKeys.add(key);
4733 break;
4734 }
4735 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);
4736 break;
4737 default:
4738 break;
4739 }
4740 }
4741 return knownKeys;
4742 }
4743
4744 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
4745 // This algorithm can't optimize by searching from boths ends since we
4746 // don't have backpointers on fibers. I'm trying to see how far we can get
4747 // with that model. If it ends up not being worth the tradeoffs, we can
4748 // add it later.
4749
4750 // Even with a two ended optimization, we'd want to optimize for the case
4751 // where there are few changes and brute force the comparison instead of
4752 // going for the Map. It'd like to explore hitting that path first in
4753 // forward-only mode and only go for the Map once we notice that we need
4754 // lots of look ahead. This doesn't handle reversal as well as two ended
4755 // search but that's unusual. Besides, for the two ended optimization to
4756 // work on Iterables, we'd need to copy the whole set.
4757
4758 // In this first iteration, we'll just live with hitting the bad case
4759 // (adding everything to a Map) in for every insert/move.
4760
4761 // If you change this code, also update reconcileChildrenIterator() which
4762 // uses the same algorithm.
4763
4764 {
4765 // First, validate keys.
4766 var knownKeys = null;
4767 for (var i = 0; i < newChildren.length; i++) {
4768 var child = newChildren[i];
4769 knownKeys = warnOnInvalidKey(child, knownKeys);
4770 }
4771 }
4772
4773 var resultingFirstChild = null;
4774 var previousNewFiber = null;
4775
4776 var oldFiber = currentFirstChild;
4777 var lastPlacedIndex = 0;
4778 var newIdx = 0;
4779 var nextOldFiber = null;
4780 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
4781 if (oldFiber.index > newIdx) {
4782 nextOldFiber = oldFiber;
4783 oldFiber = null;
4784 } else {
4785 nextOldFiber = oldFiber.sibling;
4786 }
4787 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
4788 if (newFiber === null) {
4789 // TODO: This breaks on empty slots like null children. That's
4790 // unfortunate because it triggers the slow path all the time. We need
4791 // a better way to communicate whether this was a miss or null,
4792 // boolean, undefined, etc.
4793 if (oldFiber === null) {
4794 oldFiber = nextOldFiber;
4795 }
4796 break;
4797 }
4798 if (shouldTrackSideEffects) {
4799 if (oldFiber && newFiber.alternate === null) {
4800 // We matched the slot, but we didn't reuse the existing fiber, so we
4801 // need to delete the existing child.
4802 deleteChild(returnFiber, oldFiber);
4803 }
4804 }
4805 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4806 if (previousNewFiber === null) {
4807 // TODO: Move out of the loop. This only happens for the first run.
4808 resultingFirstChild = newFiber;
4809 } else {
4810 // TODO: Defer siblings if we're not at the right index for this slot.
4811 // I.e. if we had null values before, then we want to defer this
4812 // for each null value. However, we also don't want to call updateSlot
4813 // with the previous one.
4814 previousNewFiber.sibling = newFiber;
4815 }
4816 previousNewFiber = newFiber;
4817 oldFiber = nextOldFiber;
4818 }
4819
4820 if (newIdx === newChildren.length) {
4821 // We've reached the end of the new children. We can delete the rest.
4822 deleteRemainingChildren(returnFiber, oldFiber);
4823 return resultingFirstChild;
4824 }
4825
4826 if (oldFiber === null) {
4827 // If we don't have any more existing children we can choose a fast path
4828 // since the rest will all be insertions.
4829 for (; newIdx < newChildren.length; newIdx++) {
4830 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
4831 if (!_newFiber) {
4832 continue;
4833 }
4834 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
4835 if (previousNewFiber === null) {
4836 // TODO: Move out of the loop. This only happens for the first run.
4837 resultingFirstChild = _newFiber;
4838 } else {
4839 previousNewFiber.sibling = _newFiber;
4840 }
4841 previousNewFiber = _newFiber;
4842 }
4843 return resultingFirstChild;
4844 }
4845
4846 // Add all children to a key map for quick lookups.
4847 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
4848
4849 // Keep scanning and use the map to restore deleted items as moves.
4850 for (; newIdx < newChildren.length; newIdx++) {
4851 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
4852 if (_newFiber2) {
4853 if (shouldTrackSideEffects) {
4854 if (_newFiber2.alternate !== null) {
4855 // The new fiber is a work in progress, but if there exists a
4856 // current, that means that we reused the fiber. We need to delete
4857 // it from the child list so that we don't add it to the deletion
4858 // list.
4859 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
4860 }
4861 }
4862 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
4863 if (previousNewFiber === null) {
4864 resultingFirstChild = _newFiber2;
4865 } else {
4866 previousNewFiber.sibling = _newFiber2;
4867 }
4868 previousNewFiber = _newFiber2;
4869 }
4870 }
4871
4872 if (shouldTrackSideEffects) {
4873 // Any existing children that weren't consumed above were deleted. We need
4874 // to add them to the deletion list.
4875 existingChildren.forEach(function (child) {
4876 return deleteChild(returnFiber, child);
4877 });
4878 }
4879
4880 return resultingFirstChild;
4881 }
4882
4883 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
4884 // This is the same implementation as reconcileChildrenArray(),
4885 // but using the iterator instead.
4886
4887 var iteratorFn = getIteratorFn(newChildrenIterable);
4888 !(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;
4889
4890 {
4891 // We don't support rendering Generators because it's a mutation.
4892 // See https://github.com/facebook/react/issues/12995
4893 if (typeof Symbol === 'function' &&
4894 // $FlowFixMe Flow doesn't know about toStringTag
4895 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
4896 !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;
4897 didWarnAboutGenerators = true;
4898 }
4899
4900 // Warn about using Maps as children
4901 if (newChildrenIterable.entries === iteratorFn) {
4902 !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;
4903 didWarnAboutMaps = true;
4904 }
4905
4906 // First, validate keys.
4907 // We'll get a different iterator later for the main pass.
4908 var _newChildren = iteratorFn.call(newChildrenIterable);
4909 if (_newChildren) {
4910 var knownKeys = null;
4911 var _step = _newChildren.next();
4912 for (; !_step.done; _step = _newChildren.next()) {
4913 var child = _step.value;
4914 knownKeys = warnOnInvalidKey(child, knownKeys);
4915 }
4916 }
4917 }
4918
4919 var newChildren = iteratorFn.call(newChildrenIterable);
4920 !(newChildren != null) ? invariant(false, 'An iterable object provided no iterator.') : void 0;
4921
4922 var resultingFirstChild = null;
4923 var previousNewFiber = null;
4924
4925 var oldFiber = currentFirstChild;
4926 var lastPlacedIndex = 0;
4927 var newIdx = 0;
4928 var nextOldFiber = null;
4929
4930 var step = newChildren.next();
4931 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
4932 if (oldFiber.index > newIdx) {
4933 nextOldFiber = oldFiber;
4934 oldFiber = null;
4935 } else {
4936 nextOldFiber = oldFiber.sibling;
4937 }
4938 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
4939 if (newFiber === null) {
4940 // TODO: This breaks on empty slots like null children. That's
4941 // unfortunate because it triggers the slow path all the time. We need
4942 // a better way to communicate whether this was a miss or null,
4943 // boolean, undefined, etc.
4944 if (!oldFiber) {
4945 oldFiber = nextOldFiber;
4946 }
4947 break;
4948 }
4949 if (shouldTrackSideEffects) {
4950 if (oldFiber && newFiber.alternate === null) {
4951 // We matched the slot, but we didn't reuse the existing fiber, so we
4952 // need to delete the existing child.
4953 deleteChild(returnFiber, oldFiber);
4954 }
4955 }
4956 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
4957 if (previousNewFiber === null) {
4958 // TODO: Move out of the loop. This only happens for the first run.
4959 resultingFirstChild = newFiber;
4960 } else {
4961 // TODO: Defer siblings if we're not at the right index for this slot.
4962 // I.e. if we had null values before, then we want to defer this
4963 // for each null value. However, we also don't want to call updateSlot
4964 // with the previous one.
4965 previousNewFiber.sibling = newFiber;
4966 }
4967 previousNewFiber = newFiber;
4968 oldFiber = nextOldFiber;
4969 }
4970
4971 if (step.done) {
4972 // We've reached the end of the new children. We can delete the rest.
4973 deleteRemainingChildren(returnFiber, oldFiber);
4974 return resultingFirstChild;
4975 }
4976
4977 if (oldFiber === null) {
4978 // If we don't have any more existing children we can choose a fast path
4979 // since the rest will all be insertions.
4980 for (; !step.done; newIdx++, step = newChildren.next()) {
4981 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
4982 if (_newFiber3 === null) {
4983 continue;
4984 }
4985 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
4986 if (previousNewFiber === null) {
4987 // TODO: Move out of the loop. This only happens for the first run.
4988 resultingFirstChild = _newFiber3;
4989 } else {
4990 previousNewFiber.sibling = _newFiber3;
4991 }
4992 previousNewFiber = _newFiber3;
4993 }
4994 return resultingFirstChild;
4995 }
4996
4997 // Add all children to a key map for quick lookups.
4998 var existingChildren = mapRemainingChildren(returnFiber, oldFiber);
4999
5000 // Keep scanning and use the map to restore deleted items as moves.
5001 for (; !step.done; newIdx++, step = newChildren.next()) {
5002 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
5003 if (_newFiber4 !== null) {
5004 if (shouldTrackSideEffects) {
5005 if (_newFiber4.alternate !== null) {
5006 // The new fiber is a work in progress, but if there exists a
5007 // current, that means that we reused the fiber. We need to delete
5008 // it from the child list so that we don't add it to the deletion
5009 // list.
5010 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
5011 }
5012 }
5013 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
5014 if (previousNewFiber === null) {
5015 resultingFirstChild = _newFiber4;
5016 } else {
5017 previousNewFiber.sibling = _newFiber4;
5018 }
5019 previousNewFiber = _newFiber4;
5020 }
5021 }
5022
5023 if (shouldTrackSideEffects) {
5024 // Any existing children that weren't consumed above were deleted. We need
5025 // to add them to the deletion list.
5026 existingChildren.forEach(function (child) {
5027 return deleteChild(returnFiber, child);
5028 });
5029 }
5030
5031 return resultingFirstChild;
5032 }
5033
5034 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
5035 // There's no need to check for keys on text nodes since we don't have a
5036 // way to define them.
5037 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
5038 // We already have an existing node so let's just update it and delete
5039 // the rest.
5040 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
5041 var existing = useFiber(currentFirstChild, textContent, expirationTime);
5042 existing.return = returnFiber;
5043 return existing;
5044 }
5045 // The existing first child is not a text node so we need to create one
5046 // and delete the existing ones.
5047 deleteRemainingChildren(returnFiber, currentFirstChild);
5048 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
5049 created.return = returnFiber;
5050 return created;
5051 }
5052
5053 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
5054 var key = element.key;
5055 var child = currentFirstChild;
5056 while (child !== null) {
5057 // TODO: If key === null and child.key === null, then this only applies to
5058 // the first item in the list.
5059 if (child.key === key) {
5060 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type) {
5061 deleteRemainingChildren(returnFiber, child.sibling);
5062 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
5063 existing.ref = coerceRef(returnFiber, child, element);
5064 existing.return = returnFiber;
5065 {
5066 existing._debugSource = element._source;
5067 existing._debugOwner = element._owner;
5068 }
5069 return existing;
5070 } else {
5071 deleteRemainingChildren(returnFiber, child);
5072 break;
5073 }
5074 } else {
5075 deleteChild(returnFiber, child);
5076 }
5077 child = child.sibling;
5078 }
5079
5080 if (element.type === REACT_FRAGMENT_TYPE) {
5081 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
5082 created.return = returnFiber;
5083 return created;
5084 } else {
5085 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
5086 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
5087 _created4.return = returnFiber;
5088 return _created4;
5089 }
5090 }
5091
5092 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
5093 var key = portal.key;
5094 var child = currentFirstChild;
5095 while (child !== null) {
5096 // TODO: If key === null and child.key === null, then this only applies to
5097 // the first item in the list.
5098 if (child.key === key) {
5099 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
5100 deleteRemainingChildren(returnFiber, child.sibling);
5101 var existing = useFiber(child, portal.children || [], expirationTime);
5102 existing.return = returnFiber;
5103 return existing;
5104 } else {
5105 deleteRemainingChildren(returnFiber, child);
5106 break;
5107 }
5108 } else {
5109 deleteChild(returnFiber, child);
5110 }
5111 child = child.sibling;
5112 }
5113
5114 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
5115 created.return = returnFiber;
5116 return created;
5117 }
5118
5119 // This API will tag the children with the side-effect of the reconciliation
5120 // itself. They will be added to the side-effect list as we pass through the
5121 // children and the parent.
5122 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
5123 // This function is not recursive.
5124 // If the top level item is an array, we treat it as a set of children,
5125 // not as a fragment. Nested arrays on the other hand will be treated as
5126 // fragment nodes. Recursion happens at the normal flow.
5127
5128 // Handle top level unkeyed fragments as if they were arrays.
5129 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
5130 // We treat the ambiguous cases above the same.
5131 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
5132 if (isUnkeyedTopLevelFragment) {
5133 newChild = newChild.props.children;
5134 }
5135
5136 // Handle object types
5137 var isObject = typeof newChild === 'object' && newChild !== null;
5138
5139 if (isObject) {
5140 switch (newChild.$$typeof) {
5141 case REACT_ELEMENT_TYPE:
5142 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
5143 case REACT_PORTAL_TYPE:
5144 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
5145 }
5146 }
5147
5148 if (typeof newChild === 'string' || typeof newChild === 'number') {
5149 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
5150 }
5151
5152 if (isArray(newChild)) {
5153 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
5154 }
5155
5156 if (getIteratorFn(newChild)) {
5157 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
5158 }
5159
5160 if (isObject) {
5161 throwOnInvalidObjectType(returnFiber, newChild);
5162 }
5163
5164 {
5165 if (typeof newChild === 'function') {
5166 warnOnFunctionType();
5167 }
5168 }
5169 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
5170 // If the new child is undefined, and the return fiber is a composite
5171 // component, throw an error. If Fiber return types are disabled,
5172 // we already threw above.
5173 switch (returnFiber.tag) {
5174 case ClassComponent:
5175 {
5176 {
5177 var instance = returnFiber.stateNode;
5178 if (instance.render._isMockFunction) {
5179 // We allow auto-mocks to proceed as if they're returning null.
5180 break;
5181 }
5182 }
5183 }
5184 // Intentionally fall through to the next case, which handles both
5185 // functions and classes
5186 // eslint-disable-next-lined no-fallthrough
5187 case FunctionComponent:
5188 {
5189 var Component = returnFiber.type;
5190 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');
5191 }
5192 }
5193 }
5194
5195 // Remaining cases are all treated as empty.
5196 return deleteRemainingChildren(returnFiber, currentFirstChild);
5197 }
5198
5199 return reconcileChildFibers;
5200}
5201
5202var reconcileChildFibers = ChildReconciler(true);
5203var mountChildFibers = ChildReconciler(false);
5204
5205function cloneChildFibers(current, workInProgress) {
5206 !(current === null || workInProgress.child === current.child) ? invariant(false, 'Resuming work not yet implemented.') : void 0;
5207
5208 if (workInProgress.child === null) {
5209 return;
5210 }
5211
5212 var currentChild = workInProgress.child;
5213 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5214 workInProgress.child = newChild;
5215
5216 newChild.return = workInProgress;
5217 while (currentChild.sibling !== null) {
5218 currentChild = currentChild.sibling;
5219 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
5220 newChild.return = workInProgress;
5221 }
5222 newChild.sibling = null;
5223}
5224
5225var NO_CONTEXT$1 = {};
5226
5227var contextStackCursor$1 = createCursor(NO_CONTEXT$1);
5228var contextFiberStackCursor = createCursor(NO_CONTEXT$1);
5229var rootInstanceStackCursor = createCursor(NO_CONTEXT$1);
5230
5231function requiredContext(c) {
5232 !(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;
5233 return c;
5234}
5235
5236function getRootHostContainer() {
5237 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5238 return rootInstance;
5239}
5240
5241function pushHostContainer(fiber, nextRootInstance) {
5242 // Push current root instance onto the stack;
5243 // This allows us to reset root when portals are popped.
5244 push(rootInstanceStackCursor, nextRootInstance, fiber);
5245 // Track the context and the Fiber that provided it.
5246 // This enables us to pop only Fibers that provide unique contexts.
5247 push(contextFiberStackCursor, fiber, fiber);
5248
5249 // Finally, we need to push the host context to the stack.
5250 // However, we can't just call getRootHostContext() and push it because
5251 // we'd have a different number of entries on the stack depending on
5252 // whether getRootHostContext() throws somewhere in renderer code or not.
5253 // So we push an empty value first. This lets us safely unwind on errors.
5254 push(contextStackCursor$1, NO_CONTEXT$1, fiber);
5255 var nextRootContext = getRootHostContext(nextRootInstance);
5256 // Now that we know this function doesn't throw, replace it.
5257 pop(contextStackCursor$1, fiber);
5258 push(contextStackCursor$1, nextRootContext, fiber);
5259}
5260
5261function popHostContainer(fiber) {
5262 pop(contextStackCursor$1, fiber);
5263 pop(contextFiberStackCursor, fiber);
5264 pop(rootInstanceStackCursor, fiber);
5265}
5266
5267function getHostContext() {
5268 var context = requiredContext(contextStackCursor$1.current);
5269 return context;
5270}
5271
5272function pushHostContext(fiber) {
5273 var rootInstance = requiredContext(rootInstanceStackCursor.current);
5274 var context = requiredContext(contextStackCursor$1.current);
5275 var nextContext = getChildHostContext(context, fiber.type, rootInstance);
5276
5277 // Don't push this Fiber's context unless it's unique.
5278 if (context === nextContext) {
5279 return;
5280 }
5281
5282 // Track the context and the Fiber that provided it.
5283 // This enables us to pop only Fibers that provide unique contexts.
5284 push(contextFiberStackCursor, fiber, fiber);
5285 push(contextStackCursor$1, nextContext, fiber);
5286}
5287
5288function popHostContext(fiber) {
5289 // Do not pop unless this Fiber provided the current context.
5290 // pushHostContext() only pushes Fibers that provide unique contexts.
5291 if (contextFiberStackCursor.current !== fiber) {
5292 return;
5293 }
5294
5295 pop(contextStackCursor$1, fiber);
5296 pop(contextFiberStackCursor, fiber);
5297}
5298
5299var NoEffect$1 = /* */0;
5300var UnmountSnapshot = /* */2;
5301var UnmountMutation = /* */4;
5302var MountMutation = /* */8;
5303var UnmountLayout = /* */16;
5304var MountLayout = /* */32;
5305var MountPassive = /* */64;
5306var UnmountPassive = /* */128;
5307
5308var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
5309
5310
5311var didWarnAboutMismatchedHooksForComponent = void 0;
5312{
5313 didWarnAboutMismatchedHooksForComponent = new Set();
5314}
5315
5316// These are set right before calling the component.
5317var renderExpirationTime = NoWork;
5318// The work-in-progress fiber. I've named it differently to distinguish it from
5319// the work-in-progress hook.
5320var currentlyRenderingFiber$1 = null;
5321
5322// Hooks are stored as a linked list on the fiber's memoizedState field. The
5323// current hook list is the list that belongs to the current fiber. The
5324// work-in-progress hook list is a new list that will be added to the
5325// work-in-progress fiber.
5326var firstCurrentHook = null;
5327var currentHook = null;
5328var nextCurrentHook = null;
5329var firstWorkInProgressHook = null;
5330var workInProgressHook = null;
5331var nextWorkInProgressHook = null;
5332
5333var remainingExpirationTime = NoWork;
5334var componentUpdateQueue = null;
5335var sideEffectTag = 0;
5336
5337// Updates scheduled during render will trigger an immediate re-render at the
5338// end of the current pass. We can't store these updates on the normal queue,
5339// because if the work is aborted, they should be discarded. Because this is
5340// a relatively rare case, we also don't want to add an additional field to
5341// either the hook or queue object types. So we store them in a lazily create
5342// map of queue -> render-phase updates, which are discarded once the component
5343// completes without re-rendering.
5344
5345// Whether an update was scheduled during the currently executing render pass.
5346var didScheduleRenderPhaseUpdate = false;
5347// Lazily created map of render-phase updates
5348var renderPhaseUpdates = null;
5349// Counter to prevent infinite loops.
5350var numberOfReRenders = 0;
5351var RE_RENDER_LIMIT = 25;
5352
5353// In DEV, this is the name of the currently executing primitive hook
5354var currentHookNameInDev = null;
5355
5356function warnOnHookMismatchInDev() {
5357 {
5358 var componentName = getComponentName(currentlyRenderingFiber$1.type);
5359 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
5360 didWarnAboutMismatchedHooksForComponent.add(componentName);
5361
5362 var secondColumnStart = 22;
5363
5364 var table = '';
5365 var prevHook = firstCurrentHook;
5366 var nextHook = firstWorkInProgressHook;
5367 var n = 1;
5368 while (prevHook !== null && nextHook !== null) {
5369 var oldHookName = prevHook._debugType;
5370 var newHookName = nextHook._debugType;
5371
5372 var row = n + '. ' + oldHookName;
5373
5374 // Extra space so second column lines up
5375 // lol @ IE not supporting String#repeat
5376 while (row.length < secondColumnStart) {
5377 row += ' ';
5378 }
5379
5380 row += newHookName + '\n';
5381
5382 table += row;
5383 prevHook = prevHook.next;
5384 nextHook = nextHook.next;
5385 n++;
5386 }
5387
5388 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);
5389 }
5390 }
5391}
5392
5393function throwInvalidHookError() {
5394 invariant(false, 'Hooks can only be called inside the body of a function component. (https://fb.me/react-invalid-hook-call)');
5395}
5396
5397function areHookInputsEqual(nextDeps, prevDeps) {
5398 if (prevDeps === null) {
5399 {
5400 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);
5401 }
5402 return false;
5403 }
5404
5405 {
5406 // Don't bother comparing lengths in prod because these arrays should be
5407 // passed inline.
5408 if (nextDeps.length !== prevDeps.length) {
5409 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(', ') + ']');
5410 }
5411 }
5412 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
5413 if (is(nextDeps[i], prevDeps[i])) {
5414 continue;
5415 }
5416 return false;
5417 }
5418 return true;
5419}
5420
5421function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
5422 renderExpirationTime = nextRenderExpirationTime;
5423 currentlyRenderingFiber$1 = workInProgress;
5424 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
5425
5426 // The following should have already been reset
5427 // currentHook = null;
5428 // workInProgressHook = null;
5429
5430 // remainingExpirationTime = NoWork;
5431 // componentUpdateQueue = null;
5432
5433 // didScheduleRenderPhaseUpdate = false;
5434 // renderPhaseUpdates = null;
5435 // numberOfReRenders = 0;
5436 // sideEffectTag = 0;
5437
5438 {
5439 ReactCurrentDispatcher$1.current = nextCurrentHook === null ? HooksDispatcherOnMountInDEV : HooksDispatcherOnUpdateInDEV;
5440 }
5441
5442 var children = Component(props, refOrContext);
5443
5444 if (didScheduleRenderPhaseUpdate) {
5445 do {
5446 didScheduleRenderPhaseUpdate = false;
5447 numberOfReRenders += 1;
5448
5449 // Start over from the beginning of the list
5450 firstCurrentHook = nextCurrentHook = current !== null ? current.memoizedState : null;
5451 nextWorkInProgressHook = firstWorkInProgressHook;
5452
5453 currentHook = null;
5454 workInProgressHook = null;
5455 componentUpdateQueue = null;
5456
5457 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
5458
5459 children = Component(props, refOrContext);
5460 } while (didScheduleRenderPhaseUpdate);
5461
5462 renderPhaseUpdates = null;
5463 numberOfReRenders = 0;
5464 }
5465
5466 {
5467 currentHookNameInDev = null;
5468 }
5469
5470 // We can assume the previous dispatcher is always this one, since we set it
5471 // at the beginning of the render phase and there's no re-entrancy.
5472 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5473
5474 var renderedWork = currentlyRenderingFiber$1;
5475
5476 renderedWork.memoizedState = firstWorkInProgressHook;
5477 renderedWork.expirationTime = remainingExpirationTime;
5478 renderedWork.updateQueue = componentUpdateQueue;
5479 renderedWork.effectTag |= sideEffectTag;
5480
5481 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
5482
5483 renderExpirationTime = NoWork;
5484 currentlyRenderingFiber$1 = null;
5485
5486 firstCurrentHook = null;
5487 currentHook = null;
5488 nextCurrentHook = null;
5489 firstWorkInProgressHook = null;
5490 workInProgressHook = null;
5491 nextWorkInProgressHook = null;
5492
5493 remainingExpirationTime = NoWork;
5494 componentUpdateQueue = null;
5495 sideEffectTag = 0;
5496
5497 // These were reset above
5498 // didScheduleRenderPhaseUpdate = false;
5499 // renderPhaseUpdates = null;
5500 // numberOfReRenders = 0;
5501
5502 !!didRenderTooFewHooks ? invariant(false, 'Rendered fewer hooks than expected. This may be caused by an accidental early return statement.') : void 0;
5503
5504 return children;
5505}
5506
5507function bailoutHooks(current, workInProgress, expirationTime) {
5508 workInProgress.updateQueue = current.updateQueue;
5509 workInProgress.effectTag &= ~(Passive | Update);
5510 if (current.expirationTime <= expirationTime) {
5511 current.expirationTime = NoWork;
5512 }
5513}
5514
5515function resetHooks() {
5516 // We can assume the previous dispatcher is always this one, since we set it
5517 // at the beginning of the render phase and there's no re-entrancy.
5518 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
5519
5520 // This is used to reset the state of this module when a component throws.
5521 // It's also called inside mountIndeterminateComponent if we determine the
5522 // component is a module-style component.
5523 renderExpirationTime = NoWork;
5524 currentlyRenderingFiber$1 = null;
5525
5526 firstCurrentHook = null;
5527 currentHook = null;
5528 nextCurrentHook = null;
5529 firstWorkInProgressHook = null;
5530 workInProgressHook = null;
5531 nextWorkInProgressHook = null;
5532
5533 remainingExpirationTime = NoWork;
5534 componentUpdateQueue = null;
5535 sideEffectTag = 0;
5536
5537 {
5538 currentHookNameInDev = null;
5539 }
5540
5541 didScheduleRenderPhaseUpdate = false;
5542 renderPhaseUpdates = null;
5543 numberOfReRenders = 0;
5544}
5545
5546function mountWorkInProgressHook() {
5547 var hook = {
5548 memoizedState: null,
5549
5550 baseState: null,
5551 queue: null,
5552 baseUpdate: null,
5553
5554 next: null
5555 };
5556
5557 {
5558 hook._debugType = currentHookNameInDev;
5559 if (currentlyRenderingFiber$1 !== null && currentlyRenderingFiber$1.alternate !== null) {
5560 warning$1(false, '%s: Rendered more hooks than during the previous render. This is ' + 'not currently supported and may lead to unexpected behavior.', getComponentName(currentlyRenderingFiber$1.type));
5561 }
5562 }
5563 if (workInProgressHook === null) {
5564 // This is the first hook in the list
5565 firstWorkInProgressHook = workInProgressHook = hook;
5566 } else {
5567 // Append to the end of the list
5568 workInProgressHook = workInProgressHook.next = hook;
5569 }
5570 return workInProgressHook;
5571}
5572
5573function updateWorkInProgressHook() {
5574 // This function is used both for updates and for re-renders triggered by a
5575 // render phase update. It assumes there is either a current hook we can
5576 // clone, or a work-in-progress hook from a previous render pass that we can
5577 // use as a base. When we reach the end of the base list, we must switch to
5578 // the dispatcher used for mounts.
5579 if (nextWorkInProgressHook !== null) {
5580 // There's already a work-in-progress. Reuse it.
5581 workInProgressHook = nextWorkInProgressHook;
5582 nextWorkInProgressHook = workInProgressHook.next;
5583
5584 currentHook = nextCurrentHook;
5585 nextCurrentHook = currentHook !== null ? currentHook.next : null;
5586 } else {
5587 // Clone from the current hook.
5588 !(nextCurrentHook !== null) ? invariant(false, 'Rendered more hooks than during the previous render.') : void 0;
5589 currentHook = nextCurrentHook;
5590
5591 var newHook = {
5592 memoizedState: currentHook.memoizedState,
5593
5594 baseState: currentHook.baseState,
5595 queue: currentHook.queue,
5596 baseUpdate: currentHook.baseUpdate,
5597
5598 next: null
5599 };
5600
5601 if (workInProgressHook === null) {
5602 // This is the first hook in the list.
5603 workInProgressHook = firstWorkInProgressHook = newHook;
5604 } else {
5605 // Append to the end of the list.
5606 workInProgressHook = workInProgressHook.next = newHook;
5607 }
5608 nextCurrentHook = currentHook.next;
5609
5610 {
5611 newHook._debugType = currentHookNameInDev;
5612 if (currentHookNameInDev !== currentHook._debugType) {
5613 warnOnHookMismatchInDev();
5614 }
5615 }
5616 }
5617 return workInProgressHook;
5618}
5619
5620function createFunctionComponentUpdateQueue() {
5621 return {
5622 lastEffect: null
5623 };
5624}
5625
5626function basicStateReducer(state, action) {
5627 return typeof action === 'function' ? action(state) : action;
5628}
5629
5630function mountContext(context, observedBits) {
5631 {
5632 mountWorkInProgressHook();
5633 }
5634 return readContext(context, observedBits);
5635}
5636
5637function updateContext(context, observedBits) {
5638 {
5639 updateWorkInProgressHook();
5640 }
5641 return readContext(context, observedBits);
5642}
5643
5644function mountReducer(reducer, initialArg, init) {
5645 var hook = mountWorkInProgressHook();
5646 var initialState = void 0;
5647 if (init !== undefined) {
5648 initialState = init(initialArg);
5649 } else {
5650 initialState = initialArg;
5651 }
5652 hook.memoizedState = hook.baseState = initialState;
5653 var queue = hook.queue = {
5654 last: null,
5655 dispatch: null,
5656 eagerReducer: reducer,
5657 eagerState: initialState
5658 };
5659 var dispatch = queue.dispatch = dispatchAction.bind(null,
5660 // Flow doesn't know this is non-null, but we do.
5661 currentlyRenderingFiber$1, queue);
5662 return [hook.memoizedState, dispatch];
5663}
5664
5665function updateReducer(reducer, initialArg, init) {
5666 var hook = updateWorkInProgressHook();
5667 var queue = hook.queue;
5668 !(queue !== null) ? invariant(false, 'Should have a queue. This is likely a bug in React. Please file an issue.') : void 0;
5669
5670 if (numberOfReRenders > 0) {
5671 // This is a re-render. Apply the new render phase updates to the previous
5672 var _dispatch = queue.dispatch;
5673 if (renderPhaseUpdates !== null) {
5674 // Render phase updates are stored in a map of queue -> linked list
5675 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
5676 if (firstRenderPhaseUpdate !== undefined) {
5677 renderPhaseUpdates.delete(queue);
5678 var newState = hook.memoizedState;
5679 var update = firstRenderPhaseUpdate;
5680 do {
5681 // Process this render phase update. We don't have to check the
5682 // priority because it will always be the same as the current
5683 // render's.
5684 var _action = update.action;
5685 newState = reducer(newState, _action);
5686 update = update.next;
5687 } while (update !== null);
5688
5689 // Mark that the fiber performed work, but only if the new state is
5690 // different from the current state.
5691 if (!is(newState, hook.memoizedState)) {
5692 markWorkInProgressReceivedUpdate();
5693 }
5694
5695 hook.memoizedState = newState;
5696
5697 // Don't persist the state accumlated from the render phase updates to
5698 // the base state unless the queue is empty.
5699 // TODO: Not sure if this is the desired semantics, but it's what we
5700 // do for gDSFP. I can't remember why.
5701 if (hook.baseUpdate === queue.last) {
5702 hook.baseState = newState;
5703 }
5704
5705 return [newState, _dispatch];
5706 }
5707 }
5708 return [hook.memoizedState, _dispatch];
5709 }
5710
5711 // The last update in the entire queue
5712 var last = queue.last;
5713 // The last update that is part of the base state.
5714 var baseUpdate = hook.baseUpdate;
5715 var baseState = hook.baseState;
5716
5717 // Find the first unprocessed update.
5718 var first = void 0;
5719 if (baseUpdate !== null) {
5720 if (last !== null) {
5721 // For the first update, the queue is a circular linked list where
5722 // `queue.last.next = queue.first`. Once the first update commits, and
5723 // the `baseUpdate` is no longer empty, we can unravel the list.
5724 last.next = null;
5725 }
5726 first = baseUpdate.next;
5727 } else {
5728 first = last !== null ? last.next : null;
5729 }
5730 if (first !== null) {
5731 var _newState = baseState;
5732 var newBaseState = null;
5733 var newBaseUpdate = null;
5734 var prevUpdate = baseUpdate;
5735 var _update = first;
5736 var didSkip = false;
5737 do {
5738 var updateExpirationTime = _update.expirationTime;
5739 if (updateExpirationTime < renderExpirationTime) {
5740 // Priority is insufficient. Skip this update. If this is the first
5741 // skipped update, the previous update/state is the new base
5742 // update/state.
5743 if (!didSkip) {
5744 didSkip = true;
5745 newBaseUpdate = prevUpdate;
5746 newBaseState = _newState;
5747 }
5748 // Update the remaining priority in the queue.
5749 if (updateExpirationTime > remainingExpirationTime) {
5750 remainingExpirationTime = updateExpirationTime;
5751 }
5752 } else {
5753 // Process this update.
5754 if (_update.eagerReducer === reducer) {
5755 // If this update was processed eagerly, and its reducer matches the
5756 // current reducer, we can use the eagerly computed state.
5757 _newState = _update.eagerState;
5758 } else {
5759 var _action2 = _update.action;
5760 _newState = reducer(_newState, _action2);
5761 }
5762 }
5763 prevUpdate = _update;
5764 _update = _update.next;
5765 } while (_update !== null && _update !== first);
5766
5767 if (!didSkip) {
5768 newBaseUpdate = prevUpdate;
5769 newBaseState = _newState;
5770 }
5771
5772 // Mark that the fiber performed work, but only if the new state is
5773 // different from the current state.
5774 if (!is(_newState, hook.memoizedState)) {
5775 markWorkInProgressReceivedUpdate();
5776 }
5777
5778 hook.memoizedState = _newState;
5779 hook.baseUpdate = newBaseUpdate;
5780 hook.baseState = newBaseState;
5781
5782 queue.eagerReducer = reducer;
5783 queue.eagerState = _newState;
5784 }
5785
5786 var dispatch = queue.dispatch;
5787 return [hook.memoizedState, dispatch];
5788}
5789
5790function mountState(initialState) {
5791 var hook = mountWorkInProgressHook();
5792 if (typeof initialState === 'function') {
5793 initialState = initialState();
5794 }
5795 hook.memoizedState = hook.baseState = initialState;
5796 var queue = hook.queue = {
5797 last: null,
5798 dispatch: null,
5799 eagerReducer: basicStateReducer,
5800 eagerState: initialState
5801 };
5802 var dispatch = queue.dispatch = dispatchAction.bind(null,
5803 // Flow doesn't know this is non-null, but we do.
5804 currentlyRenderingFiber$1, queue);
5805 return [hook.memoizedState, dispatch];
5806}
5807
5808function updateState(initialState) {
5809 return updateReducer(basicStateReducer, initialState);
5810}
5811
5812function pushEffect(tag, create, destroy, deps) {
5813 var effect = {
5814 tag: tag,
5815 create: create,
5816 destroy: destroy,
5817 deps: deps,
5818 // Circular
5819 next: null
5820 };
5821 if (componentUpdateQueue === null) {
5822 componentUpdateQueue = createFunctionComponentUpdateQueue();
5823 componentUpdateQueue.lastEffect = effect.next = effect;
5824 } else {
5825 var _lastEffect = componentUpdateQueue.lastEffect;
5826 if (_lastEffect === null) {
5827 componentUpdateQueue.lastEffect = effect.next = effect;
5828 } else {
5829 var firstEffect = _lastEffect.next;
5830 _lastEffect.next = effect;
5831 effect.next = firstEffect;
5832 componentUpdateQueue.lastEffect = effect;
5833 }
5834 }
5835 return effect;
5836}
5837
5838function mountRef(initialValue) {
5839 var hook = mountWorkInProgressHook();
5840 var ref = { current: initialValue };
5841 {
5842 Object.seal(ref);
5843 }
5844 hook.memoizedState = ref;
5845 return ref;
5846}
5847
5848function updateRef(initialValue) {
5849 var hook = updateWorkInProgressHook();
5850 return hook.memoizedState;
5851}
5852
5853function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5854 var hook = mountWorkInProgressHook();
5855 var nextDeps = deps === undefined ? null : deps;
5856 sideEffectTag |= fiberEffectTag;
5857 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
5858}
5859
5860function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
5861 var hook = updateWorkInProgressHook();
5862 var nextDeps = deps === undefined ? null : deps;
5863 var destroy = undefined;
5864
5865 if (currentHook !== null) {
5866 var prevEffect = currentHook.memoizedState;
5867 destroy = prevEffect.destroy;
5868 if (nextDeps !== null) {
5869 var prevDeps = prevEffect.deps;
5870 if (areHookInputsEqual(nextDeps, prevDeps)) {
5871 pushEffect(NoEffect$1, create, destroy, nextDeps);
5872 return;
5873 }
5874 }
5875 }
5876
5877 sideEffectTag |= fiberEffectTag;
5878 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
5879}
5880
5881function mountEffect(create, deps) {
5882 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5883}
5884
5885function updateEffect(create, deps) {
5886 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
5887}
5888
5889function mountLayoutEffect(create, deps) {
5890 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5891}
5892
5893function updateLayoutEffect(create, deps) {
5894 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
5895}
5896
5897function imperativeHandleEffect(create, ref) {
5898 if (typeof ref === 'function') {
5899 var refCallback = ref;
5900 var _inst = create();
5901 refCallback(_inst);
5902 return function () {
5903 refCallback(null);
5904 };
5905 } else if (ref !== null && ref !== undefined) {
5906 var refObject = ref;
5907 {
5908 !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;
5909 }
5910 var _inst2 = create();
5911 refObject.current = _inst2;
5912 return function () {
5913 refObject.current = null;
5914 };
5915 }
5916}
5917
5918function mountImperativeHandle(ref, create, deps) {
5919 {
5920 !(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;
5921 }
5922
5923 // TODO: If deps are provided, should we skip comparing the ref itself?
5924 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
5925
5926 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
5927}
5928
5929function updateImperativeHandle(ref, create, deps) {
5930 {
5931 !(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;
5932 }
5933
5934 // TODO: If deps are provided, should we skip comparing the ref itself?
5935 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : [ref];
5936
5937 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
5938}
5939
5940function mountDebugValue(value, formatterFn) {
5941 // This hook is normally a no-op.
5942 // The react-debug-hooks package injects its own implementation
5943 // so that e.g. DevTools can display custom hook values.
5944}
5945
5946var updateDebugValue = mountDebugValue;
5947
5948function mountCallback(callback, deps) {
5949 var hook = mountWorkInProgressHook();
5950 var nextDeps = deps === undefined ? null : deps;
5951 hook.memoizedState = [callback, nextDeps];
5952 return callback;
5953}
5954
5955function updateCallback(callback, deps) {
5956 var hook = updateWorkInProgressHook();
5957 var nextDeps = deps === undefined ? null : deps;
5958 var prevState = hook.memoizedState;
5959 if (prevState !== null) {
5960 if (nextDeps !== null) {
5961 var prevDeps = prevState[1];
5962 if (areHookInputsEqual(nextDeps, prevDeps)) {
5963 return prevState[0];
5964 }
5965 }
5966 }
5967 hook.memoizedState = [callback, nextDeps];
5968 return callback;
5969}
5970
5971function mountMemo(nextCreate, deps) {
5972 var hook = mountWorkInProgressHook();
5973 var nextDeps = deps === undefined ? null : deps;
5974 var nextValue = nextCreate();
5975 hook.memoizedState = [nextValue, nextDeps];
5976 return nextValue;
5977}
5978
5979function updateMemo(nextCreate, deps) {
5980 var hook = updateWorkInProgressHook();
5981 var nextDeps = deps === undefined ? null : deps;
5982 var prevState = hook.memoizedState;
5983 if (prevState !== null) {
5984 // Assume these are defined. If they're not, areHookInputsEqual will warn.
5985 if (nextDeps !== null) {
5986 var prevDeps = prevState[1];
5987 if (areHookInputsEqual(nextDeps, prevDeps)) {
5988 return prevState[0];
5989 }
5990 }
5991 }
5992 var nextValue = nextCreate();
5993 hook.memoizedState = [nextValue, nextDeps];
5994 return nextValue;
5995}
5996
5997// in a test-like environment, we want to warn if dispatchAction()
5998// is called outside of a batchedUpdates/TestUtils.act(...) call.
5999var shouldWarnForUnbatchedSetState = false;
6000
6001{
6002 // jest isnt' a 'global', it's just exposed to tests via a wrapped function
6003 // further, this isn't a test file, so flow doesn't recognize the symbol. So...
6004 // $FlowExpectedError - because requirements don't give a damn about your type sigs.
6005 if ('undefined' !== typeof jest) {
6006 shouldWarnForUnbatchedSetState = true;
6007 }
6008}
6009
6010function dispatchAction(fiber, queue, action) {
6011 !(numberOfReRenders < RE_RENDER_LIMIT) ? invariant(false, 'Too many re-renders. React limits the number of renders to prevent an infinite loop.') : void 0;
6012
6013 {
6014 !(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;
6015 }
6016
6017 var alternate = fiber.alternate;
6018 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
6019 // This is a render phase update. Stash it in a lazily-created map of
6020 // queue -> linked list of updates. After this render pass, we'll restart
6021 // and apply the stashed updates on top of the work-in-progress hook.
6022 didScheduleRenderPhaseUpdate = true;
6023 var update = {
6024 expirationTime: renderExpirationTime,
6025 action: action,
6026 eagerReducer: null,
6027 eagerState: null,
6028 next: null
6029 };
6030 if (renderPhaseUpdates === null) {
6031 renderPhaseUpdates = new Map();
6032 }
6033 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
6034 if (firstRenderPhaseUpdate === undefined) {
6035 renderPhaseUpdates.set(queue, update);
6036 } else {
6037 // Append the update to the end of the list.
6038 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
6039 while (lastRenderPhaseUpdate.next !== null) {
6040 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
6041 }
6042 lastRenderPhaseUpdate.next = update;
6043 }
6044 } else {
6045 flushPassiveEffects();
6046
6047 var currentTime = requestCurrentTime();
6048 var _expirationTime = computeExpirationForFiber(currentTime, fiber);
6049
6050 var _update2 = {
6051 expirationTime: _expirationTime,
6052 action: action,
6053 eagerReducer: null,
6054 eagerState: null,
6055 next: null
6056 };
6057
6058 // Append the update to the end of the list.
6059 var _last = queue.last;
6060 if (_last === null) {
6061 // This is the first update. Create a circular list.
6062 _update2.next = _update2;
6063 } else {
6064 var first = _last.next;
6065 if (first !== null) {
6066 // Still circular.
6067 _update2.next = first;
6068 }
6069 _last.next = _update2;
6070 }
6071 queue.last = _update2;
6072
6073 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
6074 // The queue is currently empty, which means we can eagerly compute the
6075 // next state before entering the render phase. If the new state is the
6076 // same as the current state, we may be able to bail out entirely.
6077 var _eagerReducer = queue.eagerReducer;
6078 if (_eagerReducer !== null) {
6079 var prevDispatcher = void 0;
6080 {
6081 prevDispatcher = ReactCurrentDispatcher$1.current;
6082 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6083 }
6084 try {
6085 var currentState = queue.eagerState;
6086 var _eagerState = _eagerReducer(currentState, action);
6087 // Stash the eagerly computed state, and the reducer used to compute
6088 // it, on the update object. If the reducer hasn't changed by the
6089 // time we enter the render phase, then the eager state can be used
6090 // without calling the reducer again.
6091 _update2.eagerReducer = _eagerReducer;
6092 _update2.eagerState = _eagerState;
6093 if (is(_eagerState, currentState)) {
6094 // Fast path. We can bail out without scheduling React to re-render.
6095 // It's still possible that we'll need to rebase this update later,
6096 // if the component re-renders for a different reason and by that
6097 // time the reducer has changed.
6098 return;
6099 }
6100 } catch (error) {
6101 // Suppress the error. It will throw again in the render phase.
6102 } finally {
6103 {
6104 ReactCurrentDispatcher$1.current = prevDispatcher;
6105 }
6106 }
6107 }
6108 }
6109 {
6110 if (shouldWarnForUnbatchedSetState === true) {
6111 warnIfNotCurrentlyBatchingInDev(fiber);
6112 }
6113 }
6114 scheduleWork(fiber, _expirationTime);
6115 }
6116}
6117
6118var ContextOnlyDispatcher = {
6119 readContext: readContext,
6120
6121 useCallback: throwInvalidHookError,
6122 useContext: throwInvalidHookError,
6123 useEffect: throwInvalidHookError,
6124 useImperativeHandle: throwInvalidHookError,
6125 useLayoutEffect: throwInvalidHookError,
6126 useMemo: throwInvalidHookError,
6127 useReducer: throwInvalidHookError,
6128 useRef: throwInvalidHookError,
6129 useState: throwInvalidHookError,
6130 useDebugValue: throwInvalidHookError
6131};
6132
6133var HooksDispatcherOnMountInDEV = null;
6134var HooksDispatcherOnUpdateInDEV = null;
6135var InvalidNestedHooksDispatcherOnMountInDEV = null;
6136var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
6137
6138{
6139 var warnInvalidContextAccess = function () {
6140 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().');
6141 };
6142
6143 var warnInvalidHookAccess = function () {
6144 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');
6145 };
6146
6147 HooksDispatcherOnMountInDEV = {
6148 readContext: function (context, observedBits) {
6149 return readContext(context, observedBits);
6150 },
6151 useCallback: function (callback, deps) {
6152 currentHookNameInDev = 'useCallback';
6153 return mountCallback(callback, deps);
6154 },
6155 useContext: function (context, observedBits) {
6156 currentHookNameInDev = 'useContext';
6157 return mountContext(context, observedBits);
6158 },
6159 useEffect: function (create, deps) {
6160 currentHookNameInDev = 'useEffect';
6161 return mountEffect(create, deps);
6162 },
6163 useImperativeHandle: function (ref, create, deps) {
6164 currentHookNameInDev = 'useImperativeHandle';
6165 return mountImperativeHandle(ref, create, deps);
6166 },
6167 useLayoutEffect: function (create, deps) {
6168 currentHookNameInDev = 'useLayoutEffect';
6169 return mountLayoutEffect(create, deps);
6170 },
6171 useMemo: function (create, deps) {
6172 currentHookNameInDev = 'useMemo';
6173 var prevDispatcher = ReactCurrentDispatcher$1.current;
6174 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6175 try {
6176 return mountMemo(create, deps);
6177 } finally {
6178 ReactCurrentDispatcher$1.current = prevDispatcher;
6179 }
6180 },
6181 useReducer: function (reducer, initialArg, init) {
6182 currentHookNameInDev = 'useReducer';
6183 var prevDispatcher = ReactCurrentDispatcher$1.current;
6184 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6185 try {
6186 return mountReducer(reducer, initialArg, init);
6187 } finally {
6188 ReactCurrentDispatcher$1.current = prevDispatcher;
6189 }
6190 },
6191 useRef: function (initialValue) {
6192 currentHookNameInDev = 'useRef';
6193 return mountRef(initialValue);
6194 },
6195 useState: function (initialState) {
6196 currentHookNameInDev = 'useState';
6197 var prevDispatcher = ReactCurrentDispatcher$1.current;
6198 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6199 try {
6200 return mountState(initialState);
6201 } finally {
6202 ReactCurrentDispatcher$1.current = prevDispatcher;
6203 }
6204 },
6205 useDebugValue: function (value, formatterFn) {
6206 currentHookNameInDev = 'useDebugValue';
6207 return mountDebugValue(value, formatterFn);
6208 }
6209 };
6210
6211 HooksDispatcherOnUpdateInDEV = {
6212 readContext: function (context, observedBits) {
6213 return readContext(context, observedBits);
6214 },
6215 useCallback: function (callback, deps) {
6216 currentHookNameInDev = 'useCallback';
6217 return updateCallback(callback, deps);
6218 },
6219 useContext: function (context, observedBits) {
6220 currentHookNameInDev = 'useContext';
6221 return updateContext(context, observedBits);
6222 },
6223 useEffect: function (create, deps) {
6224 currentHookNameInDev = 'useEffect';
6225 return updateEffect(create, deps);
6226 },
6227 useImperativeHandle: function (ref, create, deps) {
6228 currentHookNameInDev = 'useImperativeHandle';
6229 return updateImperativeHandle(ref, create, deps);
6230 },
6231 useLayoutEffect: function (create, deps) {
6232 currentHookNameInDev = 'useLayoutEffect';
6233 return updateLayoutEffect(create, deps);
6234 },
6235 useMemo: function (create, deps) {
6236 currentHookNameInDev = 'useMemo';
6237 var prevDispatcher = ReactCurrentDispatcher$1.current;
6238 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6239 try {
6240 return updateMemo(create, deps);
6241 } finally {
6242 ReactCurrentDispatcher$1.current = prevDispatcher;
6243 }
6244 },
6245 useReducer: function (reducer, initialArg, init) {
6246 currentHookNameInDev = 'useReducer';
6247 var prevDispatcher = ReactCurrentDispatcher$1.current;
6248 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6249 try {
6250 return updateReducer(reducer, initialArg, init);
6251 } finally {
6252 ReactCurrentDispatcher$1.current = prevDispatcher;
6253 }
6254 },
6255 useRef: function (initialValue) {
6256 currentHookNameInDev = 'useRef';
6257 return updateRef(initialValue);
6258 },
6259 useState: function (initialState) {
6260 currentHookNameInDev = 'useState';
6261 var prevDispatcher = ReactCurrentDispatcher$1.current;
6262 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6263 try {
6264 return updateState(initialState);
6265 } finally {
6266 ReactCurrentDispatcher$1.current = prevDispatcher;
6267 }
6268 },
6269 useDebugValue: function (value, formatterFn) {
6270 currentHookNameInDev = 'useDebugValue';
6271 return updateDebugValue(value, formatterFn);
6272 }
6273 };
6274
6275 InvalidNestedHooksDispatcherOnMountInDEV = {
6276 readContext: function (context, observedBits) {
6277 warnInvalidContextAccess();
6278 return readContext(context, observedBits);
6279 },
6280 useCallback: function (callback, deps) {
6281 currentHookNameInDev = 'useCallback';
6282 warnInvalidHookAccess();
6283 return mountCallback(callback, deps);
6284 },
6285 useContext: function (context, observedBits) {
6286 currentHookNameInDev = 'useContext';
6287 warnInvalidHookAccess();
6288 return mountContext(context, observedBits);
6289 },
6290 useEffect: function (create, deps) {
6291 currentHookNameInDev = 'useEffect';
6292 warnInvalidHookAccess();
6293 return mountEffect(create, deps);
6294 },
6295 useImperativeHandle: function (ref, create, deps) {
6296 currentHookNameInDev = 'useImperativeHandle';
6297 warnInvalidHookAccess();
6298 return mountImperativeHandle(ref, create, deps);
6299 },
6300 useLayoutEffect: function (create, deps) {
6301 currentHookNameInDev = 'useLayoutEffect';
6302 warnInvalidHookAccess();
6303 return mountLayoutEffect(create, deps);
6304 },
6305 useMemo: function (create, deps) {
6306 currentHookNameInDev = 'useMemo';
6307 warnInvalidHookAccess();
6308 var prevDispatcher = ReactCurrentDispatcher$1.current;
6309 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6310 try {
6311 return mountMemo(create, deps);
6312 } finally {
6313 ReactCurrentDispatcher$1.current = prevDispatcher;
6314 }
6315 },
6316 useReducer: function (reducer, initialArg, init) {
6317 currentHookNameInDev = 'useReducer';
6318 warnInvalidHookAccess();
6319 var prevDispatcher = ReactCurrentDispatcher$1.current;
6320 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6321 try {
6322 return mountReducer(reducer, initialArg, init);
6323 } finally {
6324 ReactCurrentDispatcher$1.current = prevDispatcher;
6325 }
6326 },
6327 useRef: function (initialValue) {
6328 currentHookNameInDev = 'useRef';
6329 warnInvalidHookAccess();
6330 return mountRef(initialValue);
6331 },
6332 useState: function (initialState) {
6333 currentHookNameInDev = 'useState';
6334 warnInvalidHookAccess();
6335 var prevDispatcher = ReactCurrentDispatcher$1.current;
6336 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
6337 try {
6338 return mountState(initialState);
6339 } finally {
6340 ReactCurrentDispatcher$1.current = prevDispatcher;
6341 }
6342 },
6343 useDebugValue: function (value, formatterFn) {
6344 currentHookNameInDev = 'useDebugValue';
6345 warnInvalidHookAccess();
6346 return mountDebugValue(value, formatterFn);
6347 }
6348 };
6349
6350 InvalidNestedHooksDispatcherOnUpdateInDEV = {
6351 readContext: function (context, observedBits) {
6352 warnInvalidContextAccess();
6353 return readContext(context, observedBits);
6354 },
6355 useCallback: function (callback, deps) {
6356 currentHookNameInDev = 'useCallback';
6357 warnInvalidHookAccess();
6358 return updateCallback(callback, deps);
6359 },
6360 useContext: function (context, observedBits) {
6361 currentHookNameInDev = 'useContext';
6362 warnInvalidHookAccess();
6363 return updateContext(context, observedBits);
6364 },
6365 useEffect: function (create, deps) {
6366 currentHookNameInDev = 'useEffect';
6367 warnInvalidHookAccess();
6368 return updateEffect(create, deps);
6369 },
6370 useImperativeHandle: function (ref, create, deps) {
6371 currentHookNameInDev = 'useImperativeHandle';
6372 warnInvalidHookAccess();
6373 return updateImperativeHandle(ref, create, deps);
6374 },
6375 useLayoutEffect: function (create, deps) {
6376 currentHookNameInDev = 'useLayoutEffect';
6377 warnInvalidHookAccess();
6378 return updateLayoutEffect(create, deps);
6379 },
6380 useMemo: function (create, deps) {
6381 currentHookNameInDev = 'useMemo';
6382 warnInvalidHookAccess();
6383 var prevDispatcher = ReactCurrentDispatcher$1.current;
6384 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6385 try {
6386 return updateMemo(create, deps);
6387 } finally {
6388 ReactCurrentDispatcher$1.current = prevDispatcher;
6389 }
6390 },
6391 useReducer: function (reducer, initialArg, init) {
6392 currentHookNameInDev = 'useReducer';
6393 warnInvalidHookAccess();
6394 var prevDispatcher = ReactCurrentDispatcher$1.current;
6395 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6396 try {
6397 return updateReducer(reducer, initialArg, init);
6398 } finally {
6399 ReactCurrentDispatcher$1.current = prevDispatcher;
6400 }
6401 },
6402 useRef: function (initialValue) {
6403 currentHookNameInDev = 'useRef';
6404 warnInvalidHookAccess();
6405 return updateRef(initialValue);
6406 },
6407 useState: function (initialState) {
6408 currentHookNameInDev = 'useState';
6409 warnInvalidHookAccess();
6410 var prevDispatcher = ReactCurrentDispatcher$1.current;
6411 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
6412 try {
6413 return updateState(initialState);
6414 } finally {
6415 ReactCurrentDispatcher$1.current = prevDispatcher;
6416 }
6417 },
6418 useDebugValue: function (value, formatterFn) {
6419 currentHookNameInDev = 'useDebugValue';
6420 warnInvalidHookAccess();
6421 return updateDebugValue(value, formatterFn);
6422 }
6423 };
6424}
6425
6426var commitTime = 0;
6427var profilerStartTime = -1;
6428
6429function getCommitTime() {
6430 return commitTime;
6431}
6432
6433function recordCommitTime() {
6434 if (!enableProfilerTimer) {
6435 return;
6436 }
6437 commitTime = unstable_now();
6438}
6439
6440function startProfilerTimer(fiber) {
6441 if (!enableProfilerTimer) {
6442 return;
6443 }
6444
6445 profilerStartTime = unstable_now();
6446
6447 if (fiber.actualStartTime < 0) {
6448 fiber.actualStartTime = unstable_now();
6449 }
6450}
6451
6452function stopProfilerTimerIfRunning(fiber) {
6453 if (!enableProfilerTimer) {
6454 return;
6455 }
6456 profilerStartTime = -1;
6457}
6458
6459function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
6460 if (!enableProfilerTimer) {
6461 return;
6462 }
6463
6464 if (profilerStartTime >= 0) {
6465 var elapsedTime = unstable_now() - profilerStartTime;
6466 fiber.actualDuration += elapsedTime;
6467 if (overrideBaseTime) {
6468 fiber.selfBaseDuration = elapsedTime;
6469 }
6470 profilerStartTime = -1;
6471 }
6472}
6473
6474// The deepest Fiber on the stack involved in a hydration context.
6475// This may have been an insertion or a hydration.
6476var hydrationParentFiber = null;
6477var nextHydratableInstance = null;
6478var isHydrating = false;
6479
6480function enterHydrationState(fiber) {
6481 if (!supportsHydration) {
6482 return false;
6483 }
6484
6485 var parentInstance = fiber.stateNode.containerInfo;
6486 nextHydratableInstance = getFirstHydratableChild(parentInstance);
6487 hydrationParentFiber = fiber;
6488 isHydrating = true;
6489 return true;
6490}
6491
6492function deleteHydratableInstance(returnFiber, instance) {
6493 {
6494 switch (returnFiber.tag) {
6495 case HostRoot:
6496 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
6497 break;
6498 case HostComponent:
6499 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
6500 break;
6501 }
6502 }
6503
6504 var childToDelete = createFiberFromHostInstanceForDeletion();
6505 childToDelete.stateNode = instance;
6506 childToDelete.return = returnFiber;
6507 childToDelete.effectTag = Deletion;
6508
6509 // This might seem like it belongs on progressedFirstDeletion. However,
6510 // these children are not part of the reconciliation list of children.
6511 // Even if we abort and rereconcile the children, that will try to hydrate
6512 // again and the nodes are still in the host tree so these will be
6513 // recreated.
6514 if (returnFiber.lastEffect !== null) {
6515 returnFiber.lastEffect.nextEffect = childToDelete;
6516 returnFiber.lastEffect = childToDelete;
6517 } else {
6518 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
6519 }
6520}
6521
6522function insertNonHydratedInstance(returnFiber, fiber) {
6523 fiber.effectTag |= Placement;
6524 {
6525 switch (returnFiber.tag) {
6526 case HostRoot:
6527 {
6528 var parentContainer = returnFiber.stateNode.containerInfo;
6529 switch (fiber.tag) {
6530 case HostComponent:
6531 var type = fiber.type;
6532 var props = fiber.pendingProps;
6533 didNotFindHydratableContainerInstance(parentContainer, type, props);
6534 break;
6535 case HostText:
6536 var text = fiber.pendingProps;
6537 didNotFindHydratableContainerTextInstance(parentContainer, text);
6538 break;
6539 }
6540 break;
6541 }
6542 case HostComponent:
6543 {
6544 var parentType = returnFiber.type;
6545 var parentProps = returnFiber.memoizedProps;
6546 var parentInstance = returnFiber.stateNode;
6547 switch (fiber.tag) {
6548 case HostComponent:
6549 var _type = fiber.type;
6550 var _props = fiber.pendingProps;
6551 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
6552 break;
6553 case HostText:
6554 var _text = fiber.pendingProps;
6555 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
6556 break;
6557 }
6558 break;
6559 }
6560 default:
6561 return;
6562 }
6563 }
6564}
6565
6566function tryHydrate(fiber, nextInstance) {
6567 switch (fiber.tag) {
6568 case HostComponent:
6569 {
6570 var type = fiber.type;
6571 var props = fiber.pendingProps;
6572 var instance = canHydrateInstance(nextInstance, type, props);
6573 if (instance !== null) {
6574 fiber.stateNode = instance;
6575 return true;
6576 }
6577 return false;
6578 }
6579 case HostText:
6580 {
6581 var text = fiber.pendingProps;
6582 var textInstance = canHydrateTextInstance(nextInstance, text);
6583 if (textInstance !== null) {
6584 fiber.stateNode = textInstance;
6585 return true;
6586 }
6587 return false;
6588 }
6589 default:
6590 return false;
6591 }
6592}
6593
6594function tryToClaimNextHydratableInstance(fiber) {
6595 if (!isHydrating) {
6596 return;
6597 }
6598 var nextInstance = nextHydratableInstance;
6599 if (!nextInstance) {
6600 // Nothing to hydrate. Make it an insertion.
6601 insertNonHydratedInstance(hydrationParentFiber, fiber);
6602 isHydrating = false;
6603 hydrationParentFiber = fiber;
6604 return;
6605 }
6606 var firstAttemptedInstance = nextInstance;
6607 if (!tryHydrate(fiber, nextInstance)) {
6608 // If we can't hydrate this instance let's try the next one.
6609 // We use this as a heuristic. It's based on intuition and not data so it
6610 // might be flawed or unnecessary.
6611 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
6612 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
6613 // Nothing to hydrate. Make it an insertion.
6614 insertNonHydratedInstance(hydrationParentFiber, fiber);
6615 isHydrating = false;
6616 hydrationParentFiber = fiber;
6617 return;
6618 }
6619 // We matched the next one, we'll now assume that the first one was
6620 // superfluous and we'll delete it. Since we can't eagerly delete it
6621 // we'll have to schedule a deletion. To do that, this node needs a dummy
6622 // fiber associated with it.
6623 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
6624 }
6625 hydrationParentFiber = fiber;
6626 nextHydratableInstance = getFirstHydratableChild(nextInstance);
6627}
6628
6629function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
6630 if (!supportsHydration) {
6631 invariant(false, 'Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6632 }
6633
6634 var instance = fiber.stateNode;
6635 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber);
6636 // TODO: Type this specific to this type of component.
6637 fiber.updateQueue = updatePayload;
6638 // If the update payload indicates that there is a change or if there
6639 // is a new ref we mark this as an update.
6640 if (updatePayload !== null) {
6641 return true;
6642 }
6643 return false;
6644}
6645
6646function prepareToHydrateHostTextInstance(fiber) {
6647 if (!supportsHydration) {
6648 invariant(false, 'Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.');
6649 }
6650
6651 var textInstance = fiber.stateNode;
6652 var textContent = fiber.memoizedProps;
6653 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
6654 {
6655 if (shouldUpdate) {
6656 // We assume that prepareToHydrateHostTextInstance is called in a context where the
6657 // hydration parent is the parent host component of this host text.
6658 var returnFiber = hydrationParentFiber;
6659 if (returnFiber !== null) {
6660 switch (returnFiber.tag) {
6661 case HostRoot:
6662 {
6663 var parentContainer = returnFiber.stateNode.containerInfo;
6664 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
6665 break;
6666 }
6667 case HostComponent:
6668 {
6669 var parentType = returnFiber.type;
6670 var parentProps = returnFiber.memoizedProps;
6671 var parentInstance = returnFiber.stateNode;
6672 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
6673 break;
6674 }
6675 }
6676 }
6677 }
6678 }
6679 return shouldUpdate;
6680}
6681
6682function popToNextHostParent(fiber) {
6683 var parent = fiber.return;
6684 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot) {
6685 parent = parent.return;
6686 }
6687 hydrationParentFiber = parent;
6688}
6689
6690function popHydrationState(fiber) {
6691 if (!supportsHydration) {
6692 return false;
6693 }
6694 if (fiber !== hydrationParentFiber) {
6695 // We're deeper than the current hydration context, inside an inserted
6696 // tree.
6697 return false;
6698 }
6699 if (!isHydrating) {
6700 // If we're not currently hydrating but we're in a hydration context, then
6701 // we were an insertion and now need to pop up reenter hydration of our
6702 // siblings.
6703 popToNextHostParent(fiber);
6704 isHydrating = true;
6705 return false;
6706 }
6707
6708 var type = fiber.type;
6709
6710 // If we have any remaining hydratable nodes, we need to delete them now.
6711 // We only do this deeper than head and body since they tend to have random
6712 // other nodes in them. We also ignore components with pure text content in
6713 // side of them.
6714 // TODO: Better heuristic.
6715 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
6716 var nextInstance = nextHydratableInstance;
6717 while (nextInstance) {
6718 deleteHydratableInstance(fiber, nextInstance);
6719 nextInstance = getNextHydratableSibling(nextInstance);
6720 }
6721 }
6722
6723 popToNextHostParent(fiber);
6724 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
6725 return true;
6726}
6727
6728function resetHydrationState() {
6729 if (!supportsHydration) {
6730 return;
6731 }
6732
6733 hydrationParentFiber = null;
6734 nextHydratableInstance = null;
6735 isHydrating = false;
6736}
6737
6738var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
6739
6740var didReceiveUpdate = false;
6741
6742var didWarnAboutBadClass = void 0;
6743var didWarnAboutContextTypeOnFunctionComponent = void 0;
6744var didWarnAboutGetDerivedStateOnFunctionComponent = void 0;
6745var didWarnAboutFunctionRefs = void 0;
6746var didWarnAboutReassigningProps = void 0;
6747
6748{
6749 didWarnAboutBadClass = {};
6750 didWarnAboutContextTypeOnFunctionComponent = {};
6751 didWarnAboutGetDerivedStateOnFunctionComponent = {};
6752 didWarnAboutFunctionRefs = {};
6753 didWarnAboutReassigningProps = false;
6754}
6755
6756function reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime) {
6757 if (current === null) {
6758 // If this is a fresh new component that hasn't been rendered yet, we
6759 // won't update its child set by applying minimal side-effects. Instead,
6760 // we will add them all to the child before it gets rendered. That means
6761 // we can optimize this reconciliation pass by not tracking side-effects.
6762 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
6763 } else {
6764 // If the current child is the same as the work in progress, it means that
6765 // we haven't yet started any work on these children. Therefore, we use
6766 // the clone algorithm to create a copy of all the current children.
6767
6768 // If we had any progressed work already, that is invalid at this point so
6769 // let's throw it out.
6770 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderExpirationTime);
6771 }
6772}
6773
6774function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime) {
6775 // This function is fork of reconcileChildren. It's used in cases where we
6776 // want to reconcile without matching against the existing set. This has the
6777 // effect of all current children being unmounted; even if the type and key
6778 // are the same, the old child is unmounted and a new child is created.
6779 //
6780 // To do this, we're going to go through the reconcile algorithm twice. In
6781 // the first pass, we schedule a deletion for all the current children by
6782 // passing null.
6783 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderExpirationTime);
6784 // In the second pass, we mount the new children. The trick here is that we
6785 // pass null in place of where we usually pass the current child set. This has
6786 // the effect of remounting all children regardless of whether their their
6787 // identity matches.
6788 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
6789}
6790
6791function updateForwardRef(current, workInProgress, Component, nextProps, renderExpirationTime) {
6792 {
6793 if (workInProgress.type !== workInProgress.elementType) {
6794 // Lazy component props can't be validated in createElement
6795 // because they're only guaranteed to be resolved here.
6796 var innerPropTypes = Component.propTypes;
6797 if (innerPropTypes) {
6798 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6799 'prop', getComponentName(Component), getCurrentFiberStackInDev);
6800 }
6801 }
6802 }
6803
6804 var render = Component.render;
6805 var ref = workInProgress.ref;
6806
6807 // The rest is a fork of updateFunctionComponent
6808 var nextChildren = void 0;
6809 prepareToReadContext(workInProgress, renderExpirationTime);
6810 {
6811 ReactCurrentOwner$2.current = workInProgress;
6812 setCurrentPhase('render');
6813 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
6814 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
6815 // Only double-render components with Hooks
6816 if (workInProgress.memoizedState !== null) {
6817 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderExpirationTime);
6818 }
6819 }
6820 setCurrentPhase(null);
6821 }
6822
6823 if (current !== null && !didReceiveUpdate) {
6824 bailoutHooks(current, workInProgress, renderExpirationTime);
6825 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6826 }
6827
6828 // React DevTools reads this flag.
6829 workInProgress.effectTag |= PerformedWork;
6830 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6831 return workInProgress.child;
6832}
6833
6834function updateMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
6835 if (current === null) {
6836 var type = Component.type;
6837 if (isSimpleFunctionComponent(type) && Component.compare === null &&
6838 // SimpleMemoComponent codepath doesn't resolve outer props either.
6839 Component.defaultProps === undefined) {
6840 // If this is a plain function component without default props,
6841 // and with only the default shallow comparison, we upgrade it
6842 // to a SimpleMemoComponent to allow fast path updates.
6843 workInProgress.tag = SimpleMemoComponent;
6844 workInProgress.type = type;
6845 {
6846 validateFunctionComponentInDev(workInProgress, type);
6847 }
6848 return updateSimpleMemoComponent(current, workInProgress, type, nextProps, updateExpirationTime, renderExpirationTime);
6849 }
6850 {
6851 var innerPropTypes = type.propTypes;
6852 if (innerPropTypes) {
6853 // Inner memo component props aren't currently validated in createElement.
6854 // We could move it there, but we'd still need this for lazy code path.
6855 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6856 'prop', getComponentName(type), getCurrentFiberStackInDev);
6857 }
6858 }
6859 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
6860 child.ref = workInProgress.ref;
6861 child.return = workInProgress;
6862 workInProgress.child = child;
6863 return child;
6864 }
6865 {
6866 var _type = Component.type;
6867 var _innerPropTypes = _type.propTypes;
6868 if (_innerPropTypes) {
6869 // Inner memo component props aren't currently validated in createElement.
6870 // We could move it there, but we'd still need this for lazy code path.
6871 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
6872 'prop', getComponentName(_type), getCurrentFiberStackInDev);
6873 }
6874 }
6875 var currentChild = current.child; // This is always exactly one child
6876 if (updateExpirationTime < renderExpirationTime) {
6877 // This will be the props with resolved defaultProps,
6878 // unlike current.memoizedProps which will be the unresolved ones.
6879 var prevProps = currentChild.memoizedProps;
6880 // Default to shallow comparison
6881 var compare = Component.compare;
6882 compare = compare !== null ? compare : shallowEqual;
6883 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
6884 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6885 }
6886 }
6887 // React DevTools reads this flag.
6888 workInProgress.effectTag |= PerformedWork;
6889 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
6890 newChild.ref = workInProgress.ref;
6891 newChild.return = workInProgress;
6892 workInProgress.child = newChild;
6893 return newChild;
6894}
6895
6896function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
6897 {
6898 if (workInProgress.type !== workInProgress.elementType) {
6899 // Lazy component props can't be validated in createElement
6900 // because they're only guaranteed to be resolved here.
6901 var outerMemoType = workInProgress.elementType;
6902 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
6903 // We warn when you define propTypes on lazy()
6904 // so let's just skip over it to find memo() outer wrapper.
6905 // Inner props for memo are validated later.
6906 outerMemoType = refineResolvedLazyComponent(outerMemoType);
6907 }
6908 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
6909 if (outerPropTypes) {
6910 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
6911 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
6912 }
6913 // Inner propTypes will be validated in the function component path.
6914 }
6915 }
6916 if (current !== null) {
6917 var prevProps = current.memoizedProps;
6918 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref) {
6919 didReceiveUpdate = false;
6920 if (updateExpirationTime < renderExpirationTime) {
6921 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6922 }
6923 }
6924 }
6925 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime);
6926}
6927
6928function updateFragment(current, workInProgress, renderExpirationTime) {
6929 var nextChildren = workInProgress.pendingProps;
6930 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6931 return workInProgress.child;
6932}
6933
6934function updateMode(current, workInProgress, renderExpirationTime) {
6935 var nextChildren = workInProgress.pendingProps.children;
6936 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6937 return workInProgress.child;
6938}
6939
6940function updateProfiler(current, workInProgress, renderExpirationTime) {
6941 if (enableProfilerTimer) {
6942 workInProgress.effectTag |= Update;
6943 }
6944 var nextProps = workInProgress.pendingProps;
6945 var nextChildren = nextProps.children;
6946 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6947 return workInProgress.child;
6948}
6949
6950function markRef(current, workInProgress) {
6951 var ref = workInProgress.ref;
6952 if (current === null && ref !== null || current !== null && current.ref !== ref) {
6953 // Schedule a Ref effect
6954 workInProgress.effectTag |= Ref;
6955 }
6956}
6957
6958function updateFunctionComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
6959 {
6960 if (workInProgress.type !== workInProgress.elementType) {
6961 // Lazy component props can't be validated in createElement
6962 // because they're only guaranteed to be resolved here.
6963 var innerPropTypes = Component.propTypes;
6964 if (innerPropTypes) {
6965 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
6966 'prop', getComponentName(Component), getCurrentFiberStackInDev);
6967 }
6968 }
6969 }
6970
6971 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
6972 var context = getMaskedContext(workInProgress, unmaskedContext);
6973
6974 var nextChildren = void 0;
6975 prepareToReadContext(workInProgress, renderExpirationTime);
6976 {
6977 ReactCurrentOwner$2.current = workInProgress;
6978 setCurrentPhase('render');
6979 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
6980 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
6981 // Only double-render components with Hooks
6982 if (workInProgress.memoizedState !== null) {
6983 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderExpirationTime);
6984 }
6985 }
6986 setCurrentPhase(null);
6987 }
6988
6989 if (current !== null && !didReceiveUpdate) {
6990 bailoutHooks(current, workInProgress, renderExpirationTime);
6991 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
6992 }
6993
6994 // React DevTools reads this flag.
6995 workInProgress.effectTag |= PerformedWork;
6996 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
6997 return workInProgress.child;
6998}
6999
7000function updateClassComponent(current, workInProgress, Component, nextProps, renderExpirationTime) {
7001 {
7002 if (workInProgress.type !== workInProgress.elementType) {
7003 // Lazy component props can't be validated in createElement
7004 // because they're only guaranteed to be resolved here.
7005 var innerPropTypes = Component.propTypes;
7006 if (innerPropTypes) {
7007 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
7008 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7009 }
7010 }
7011 }
7012
7013 // Push context providers early to prevent context stack mismatches.
7014 // During mounting we don't know the child context yet as the instance doesn't exist.
7015 // We will invalidate the child context in finishClassComponent() right after rendering.
7016 var hasContext = void 0;
7017 if (isContextProvider(Component)) {
7018 hasContext = true;
7019 pushContextProvider(workInProgress);
7020 } else {
7021 hasContext = false;
7022 }
7023 prepareToReadContext(workInProgress, renderExpirationTime);
7024
7025 var instance = workInProgress.stateNode;
7026 var shouldUpdate = void 0;
7027 if (instance === null) {
7028 if (current !== null) {
7029 // An class component without an instance only mounts if it suspended
7030 // inside a non- concurrent tree, in an inconsistent state. We want to
7031 // tree it like a new mount, even though an empty version of it already
7032 // committed. Disconnect the alternate pointers.
7033 current.alternate = null;
7034 workInProgress.alternate = null;
7035 // Since this is conceptually a new fiber, schedule a Placement effect
7036 workInProgress.effectTag |= Placement;
7037 }
7038 // In the initial pass we might need to construct the instance.
7039 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7040 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7041 shouldUpdate = true;
7042 } else if (current === null) {
7043 // In a resume, we'll already have an instance we can reuse.
7044 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7045 } else {
7046 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderExpirationTime);
7047 }
7048 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
7049 {
7050 var inst = workInProgress.stateNode;
7051 if (inst.props !== nextProps) {
7052 !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;
7053 didWarnAboutReassigningProps = true;
7054 }
7055 }
7056 return nextUnitOfWork;
7057}
7058
7059function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
7060 // Refs should update even if shouldComponentUpdate returns false
7061 markRef(current, workInProgress);
7062
7063 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
7064
7065 if (!shouldUpdate && !didCaptureError) {
7066 // Context providers should defer to sCU for rendering
7067 if (hasContext) {
7068 invalidateContextProvider(workInProgress, Component, false);
7069 }
7070
7071 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7072 }
7073
7074 var instance = workInProgress.stateNode;
7075
7076 // Rerender
7077 ReactCurrentOwner$2.current = workInProgress;
7078 var nextChildren = void 0;
7079 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
7080 // If we captured an error, but getDerivedStateFrom catch is not defined,
7081 // unmount all the children. componentDidCatch will schedule an update to
7082 // re-render a fallback. This is temporary until we migrate everyone to
7083 // the new API.
7084 // TODO: Warn in a future release.
7085 nextChildren = null;
7086
7087 if (enableProfilerTimer) {
7088 stopProfilerTimerIfRunning(workInProgress);
7089 }
7090 } else {
7091 {
7092 setCurrentPhase('render');
7093 nextChildren = instance.render();
7094 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7095 instance.render();
7096 }
7097 setCurrentPhase(null);
7098 }
7099 }
7100
7101 // React DevTools reads this flag.
7102 workInProgress.effectTag |= PerformedWork;
7103 if (current !== null && didCaptureError) {
7104 // If we're recovering from an error, reconcile without reusing any of
7105 // the existing children. Conceptually, the normal children and the children
7106 // that are shown on error are two different sets, so we shouldn't reuse
7107 // normal children even if their identities match.
7108 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderExpirationTime);
7109 } else {
7110 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7111 }
7112
7113 // Memoize state using the values we just used to render.
7114 // TODO: Restructure so we never read values from the instance.
7115 workInProgress.memoizedState = instance.state;
7116
7117 // The context might have changed so we need to recalculate it.
7118 if (hasContext) {
7119 invalidateContextProvider(workInProgress, Component, true);
7120 }
7121
7122 return workInProgress.child;
7123}
7124
7125function pushHostRootContext(workInProgress) {
7126 var root = workInProgress.stateNode;
7127 if (root.pendingContext) {
7128 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
7129 } else if (root.context) {
7130 // Should always be set
7131 pushTopLevelContextObject(workInProgress, root.context, false);
7132 }
7133 pushHostContainer(workInProgress, root.containerInfo);
7134}
7135
7136function updateHostRoot(current, workInProgress, renderExpirationTime) {
7137 pushHostRootContext(workInProgress);
7138 var updateQueue = workInProgress.updateQueue;
7139 !(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;
7140 var nextProps = workInProgress.pendingProps;
7141 var prevState = workInProgress.memoizedState;
7142 var prevChildren = prevState !== null ? prevState.element : null;
7143 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
7144 var nextState = workInProgress.memoizedState;
7145 // Caution: React DevTools currently depends on this property
7146 // being called "element".
7147 var nextChildren = nextState.element;
7148 if (nextChildren === prevChildren) {
7149 // If the state is the same as before, that's a bailout because we had
7150 // no work that expires at this time.
7151 resetHydrationState();
7152 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7153 }
7154 var root = workInProgress.stateNode;
7155 if ((current === null || current.child === null) && root.hydrate && enterHydrationState(workInProgress)) {
7156 // If we don't have any current children this might be the first pass.
7157 // We always try to hydrate. If this isn't a hydration pass there won't
7158 // be any children to hydrate which is effectively the same thing as
7159 // not hydrating.
7160
7161 // This is a bit of a hack. We track the host root as a placement to
7162 // know that we're currently in a mounting state. That way isMounted
7163 // works as expected. We must reset this before committing.
7164 // TODO: Delete this when we delete isMounted and findDOMNode.
7165 workInProgress.effectTag |= Placement;
7166
7167 // Ensure that children mount into this root without tracking
7168 // side-effects. This ensures that we don't store Placement effects on
7169 // nodes that will be hydrated.
7170 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7171 } else {
7172 // Otherwise reset hydration state in case we aborted and resumed another
7173 // root.
7174 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7175 resetHydrationState();
7176 }
7177 return workInProgress.child;
7178}
7179
7180function updateHostComponent(current, workInProgress, renderExpirationTime) {
7181 pushHostContext(workInProgress);
7182
7183 if (current === null) {
7184 tryToClaimNextHydratableInstance(workInProgress);
7185 }
7186
7187 var type = workInProgress.type;
7188 var nextProps = workInProgress.pendingProps;
7189 var prevProps = current !== null ? current.memoizedProps : null;
7190
7191 var nextChildren = nextProps.children;
7192 var isDirectTextChild = shouldSetTextContent(type, nextProps);
7193
7194 if (isDirectTextChild) {
7195 // We special case a direct text child of a host node. This is a common
7196 // case. We won't handle it as a reified child. We will instead handle
7197 // this in the host environment that also have access to this prop. That
7198 // avoids allocating another HostText fiber and traversing it.
7199 nextChildren = null;
7200 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
7201 // If we're switching from a direct text child to a normal child, or to
7202 // empty, we need to schedule the text content to be reset.
7203 workInProgress.effectTag |= ContentReset;
7204 }
7205
7206 markRef(current, workInProgress);
7207
7208 // Check the host config to see if the children are offscreen/hidden.
7209 if (renderExpirationTime !== Never && workInProgress.mode & ConcurrentMode && shouldDeprioritizeSubtree(type, nextProps)) {
7210 // Schedule this fiber to re-render at offscreen priority. Then bailout.
7211 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
7212 return null;
7213 }
7214
7215 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7216 return workInProgress.child;
7217}
7218
7219function updateHostText(current, workInProgress) {
7220 if (current === null) {
7221 tryToClaimNextHydratableInstance(workInProgress);
7222 }
7223 // Nothing to do here. This is terminal. We'll do the completion step
7224 // immediately after.
7225 return null;
7226}
7227
7228function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
7229 if (_current !== null) {
7230 // An lazy component only mounts if it suspended inside a non-
7231 // concurrent tree, in an inconsistent state. We want to treat it like
7232 // a new mount, even though an empty version of it already committed.
7233 // Disconnect the alternate pointers.
7234 _current.alternate = null;
7235 workInProgress.alternate = null;
7236 // Since this is conceptually a new fiber, schedule a Placement effect
7237 workInProgress.effectTag |= Placement;
7238 }
7239
7240 var props = workInProgress.pendingProps;
7241 // We can't start a User Timing measurement with correct label yet.
7242 // Cancel and resume right after we know the tag.
7243 cancelWorkTimer(workInProgress);
7244 var Component = readLazyComponentType(elementType);
7245 // Store the unwrapped component in the type.
7246 workInProgress.type = Component;
7247 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
7248 startWorkTimer(workInProgress);
7249 var resolvedProps = resolveDefaultProps(Component, props);
7250 var child = void 0;
7251 switch (resolvedTag) {
7252 case FunctionComponent:
7253 {
7254 {
7255 validateFunctionComponentInDev(workInProgress, Component);
7256 }
7257 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7258 break;
7259 }
7260 case ClassComponent:
7261 {
7262 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7263 break;
7264 }
7265 case ForwardRef:
7266 {
7267 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
7268 break;
7269 }
7270 case MemoComponent:
7271 {
7272 {
7273 if (workInProgress.type !== workInProgress.elementType) {
7274 var outerPropTypes = Component.propTypes;
7275 if (outerPropTypes) {
7276 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
7277 'prop', getComponentName(Component), getCurrentFiberStackInDev);
7278 }
7279 }
7280 }
7281 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
7282 updateExpirationTime, renderExpirationTime);
7283 break;
7284 }
7285 default:
7286 {
7287 var hint = '';
7288 {
7289 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
7290 hint = ' Did you wrap a component in React.lazy() more than once?';
7291 }
7292 }
7293 // This message intentionally doesn't mention ForwardRef or MemoComponent
7294 // because the fact that it's a separate type of work is an
7295 // implementation detail.
7296 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);
7297 }
7298 }
7299 return child;
7300}
7301
7302function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
7303 if (_current !== null) {
7304 // An incomplete component only mounts if it suspended inside a non-
7305 // concurrent tree, in an inconsistent state. We want to treat it like
7306 // a new mount, even though an empty version of it already committed.
7307 // Disconnect the alternate pointers.
7308 _current.alternate = null;
7309 workInProgress.alternate = null;
7310 // Since this is conceptually a new fiber, schedule a Placement effect
7311 workInProgress.effectTag |= Placement;
7312 }
7313
7314 // Promote the fiber to a class and try rendering again.
7315 workInProgress.tag = ClassComponent;
7316
7317 // The rest of this function is a fork of `updateClassComponent`
7318
7319 // Push context providers early to prevent context stack mismatches.
7320 // During mounting we don't know the child context yet as the instance doesn't exist.
7321 // We will invalidate the child context in finishClassComponent() right after rendering.
7322 var hasContext = void 0;
7323 if (isContextProvider(Component)) {
7324 hasContext = true;
7325 pushContextProvider(workInProgress);
7326 } else {
7327 hasContext = false;
7328 }
7329 prepareToReadContext(workInProgress, renderExpirationTime);
7330
7331 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7332 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
7333
7334 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7335}
7336
7337function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
7338 if (_current !== null) {
7339 // An indeterminate component only mounts if it suspended inside a non-
7340 // concurrent tree, in an inconsistent state. We want to treat it like
7341 // a new mount, even though an empty version of it already committed.
7342 // Disconnect the alternate pointers.
7343 _current.alternate = null;
7344 workInProgress.alternate = null;
7345 // Since this is conceptually a new fiber, schedule a Placement effect
7346 workInProgress.effectTag |= Placement;
7347 }
7348
7349 var props = workInProgress.pendingProps;
7350 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
7351 var context = getMaskedContext(workInProgress, unmaskedContext);
7352
7353 prepareToReadContext(workInProgress, renderExpirationTime);
7354
7355 var value = void 0;
7356
7357 {
7358 if (Component.prototype && typeof Component.prototype.render === 'function') {
7359 var componentName = getComponentName(Component) || 'Unknown';
7360
7361 if (!didWarnAboutBadClass[componentName]) {
7362 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);
7363 didWarnAboutBadClass[componentName] = true;
7364 }
7365 }
7366
7367 if (workInProgress.mode & StrictMode) {
7368 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
7369 }
7370
7371 ReactCurrentOwner$2.current = workInProgress;
7372 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7373 }
7374 // React DevTools reads this flag.
7375 workInProgress.effectTag |= PerformedWork;
7376
7377 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
7378 // Proceed under the assumption that this is a class instance
7379 workInProgress.tag = ClassComponent;
7380
7381 // Throw out any hooks that were used.
7382 resetHooks();
7383
7384 // Push context providers early to prevent context stack mismatches.
7385 // During mounting we don't know the child context yet as the instance doesn't exist.
7386 // We will invalidate the child context in finishClassComponent() right after rendering.
7387 var hasContext = false;
7388 if (isContextProvider(Component)) {
7389 hasContext = true;
7390 pushContextProvider(workInProgress);
7391 } else {
7392 hasContext = false;
7393 }
7394
7395 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
7396
7397 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
7398 if (typeof getDerivedStateFromProps === 'function') {
7399 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
7400 }
7401
7402 adoptClassInstance(workInProgress, value);
7403 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
7404 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
7405 } else {
7406 // Proceed under the assumption that this is a function component
7407 workInProgress.tag = FunctionComponent;
7408 {
7409 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
7410 // Only double-render components with Hooks
7411 if (workInProgress.memoizedState !== null) {
7412 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
7413 }
7414 }
7415 }
7416 reconcileChildren(null, workInProgress, value, renderExpirationTime);
7417 {
7418 validateFunctionComponentInDev(workInProgress, Component);
7419 }
7420 return workInProgress.child;
7421 }
7422}
7423
7424function validateFunctionComponentInDev(workInProgress, Component) {
7425 if (Component) {
7426 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
7427 }
7428 if (workInProgress.ref !== null) {
7429 var info = '';
7430 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
7431 if (ownerName) {
7432 info += '\n\nCheck the render method of `' + ownerName + '`.';
7433 }
7434
7435 var warningKey = ownerName || workInProgress._debugID || '';
7436 var debugSource = workInProgress._debugSource;
7437 if (debugSource) {
7438 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
7439 }
7440 if (!didWarnAboutFunctionRefs[warningKey]) {
7441 didWarnAboutFunctionRefs[warningKey] = true;
7442 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);
7443 }
7444 }
7445
7446 if (typeof Component.getDerivedStateFromProps === 'function') {
7447 var componentName = getComponentName(Component) || 'Unknown';
7448
7449 if (!didWarnAboutGetDerivedStateOnFunctionComponent[componentName]) {
7450 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', componentName);
7451 didWarnAboutGetDerivedStateOnFunctionComponent[componentName] = true;
7452 }
7453 }
7454
7455 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
7456 var _componentName = getComponentName(Component) || 'Unknown';
7457
7458 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName]) {
7459 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName);
7460 didWarnAboutContextTypeOnFunctionComponent[_componentName] = true;
7461 }
7462 }
7463}
7464
7465function updateSuspenseComponent(current, workInProgress, renderExpirationTime) {
7466 var mode = workInProgress.mode;
7467 var nextProps = workInProgress.pendingProps;
7468
7469 // We should attempt to render the primary children unless this boundary
7470 // already suspended during this render (`alreadyCaptured` is true).
7471 var nextState = workInProgress.memoizedState;
7472
7473 var nextDidTimeout = void 0;
7474 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
7475 // This is the first attempt.
7476 nextState = null;
7477 nextDidTimeout = false;
7478 } else {
7479 // Something in this boundary's subtree already suspended. Switch to
7480 // rendering the fallback children.
7481 nextState = {
7482 timedOutAt: nextState !== null ? nextState.timedOutAt : NoWork
7483 };
7484 nextDidTimeout = true;
7485 workInProgress.effectTag &= ~DidCapture;
7486 }
7487
7488 // This next part is a bit confusing. If the children timeout, we switch to
7489 // showing the fallback children in place of the "primary" children.
7490 // However, we don't want to delete the primary children because then their
7491 // state will be lost (both the React state and the host state, e.g.
7492 // uncontrolled form inputs). Instead we keep them mounted and hide them.
7493 // Both the fallback children AND the primary children are rendered at the
7494 // same time. Once the primary children are un-suspended, we can delete
7495 // the fallback children — don't need to preserve their state.
7496 //
7497 // The two sets of children are siblings in the host environment, but
7498 // semantically, for purposes of reconciliation, they are two separate sets.
7499 // So we store them using two fragment fibers.
7500 //
7501 // However, we want to avoid allocating extra fibers for every placeholder.
7502 // They're only necessary when the children time out, because that's the
7503 // only time when both sets are mounted.
7504 //
7505 // So, the extra fragment fibers are only used if the children time out.
7506 // Otherwise, we render the primary children directly. This requires some
7507 // custom reconciliation logic to preserve the state of the primary
7508 // children. It's essentially a very basic form of re-parenting.
7509
7510 // `child` points to the child fiber. In the normal case, this is the first
7511 // fiber of the primary children set. In the timed-out case, it's a
7512 // a fragment fiber containing the primary children.
7513 var child = void 0;
7514 // `next` points to the next fiber React should render. In the normal case,
7515 // it's the same as `child`: the first fiber of the primary children set.
7516 // In the timed-out case, it's a fragment fiber containing the *fallback*
7517 // children -- we skip over the primary children entirely.
7518 var next = void 0;
7519 if (current === null) {
7520 // This is the initial mount. This branch is pretty simple because there's
7521 // no previous state that needs to be preserved.
7522 if (nextDidTimeout) {
7523 // Mount separate fragments for primary and fallback children.
7524 var nextFallbackChildren = nextProps.fallback;
7525 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
7526
7527 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7528 // Outside of concurrent mode, we commit the effects from the
7529 var progressedState = workInProgress.memoizedState;
7530 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
7531 primaryChildFragment.child = progressedPrimaryChild;
7532 }
7533
7534 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
7535 primaryChildFragment.sibling = fallbackChildFragment;
7536 child = primaryChildFragment;
7537 // Skip the primary children, and continue working on the
7538 // fallback children.
7539 next = fallbackChildFragment;
7540 child.return = next.return = workInProgress;
7541 } else {
7542 // Mount the primary children without an intermediate fragment fiber.
7543 var nextPrimaryChildren = nextProps.children;
7544 child = next = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
7545 }
7546 } else {
7547 // This is an update. This branch is more complicated because we need to
7548 // ensure the state of the primary children is preserved.
7549 var prevState = current.memoizedState;
7550 var prevDidTimeout = prevState !== null;
7551 if (prevDidTimeout) {
7552 // The current tree already timed out. That means each child set is
7553 var currentPrimaryChildFragment = current.child;
7554 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
7555 if (nextDidTimeout) {
7556 // Still timed out. Reuse the current primary children by cloning
7557 // its fragment. We're going to skip over these entirely.
7558 var _nextFallbackChildren = nextProps.fallback;
7559 var _primaryChildFragment = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
7560
7561 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7562 // Outside of concurrent mode, we commit the effects from the
7563 var _progressedState = workInProgress.memoizedState;
7564 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
7565 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
7566 _primaryChildFragment.child = _progressedPrimaryChild;
7567 }
7568 }
7569
7570 // Because primaryChildFragment is a new fiber that we're inserting as the
7571 // parent of a new tree, we need to set its treeBaseDuration.
7572 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7573 // treeBaseDuration is the sum of all the child tree base durations.
7574 var treeBaseDuration = 0;
7575 var hiddenChild = _primaryChildFragment.child;
7576 while (hiddenChild !== null) {
7577 treeBaseDuration += hiddenChild.treeBaseDuration;
7578 hiddenChild = hiddenChild.sibling;
7579 }
7580 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
7581 }
7582
7583 // Clone the fallback child fragment, too. These we'll continue
7584 // working on.
7585 var _fallbackChildFragment = _primaryChildFragment.sibling = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren, currentFallbackChildFragment.expirationTime);
7586 child = _primaryChildFragment;
7587 _primaryChildFragment.childExpirationTime = NoWork;
7588 // Skip the primary children, and continue working on the
7589 // fallback children.
7590 next = _fallbackChildFragment;
7591 child.return = next.return = workInProgress;
7592 } else {
7593 // No longer suspended. Switch back to showing the primary children,
7594 // and remove the intermediate fragment fiber.
7595 var _nextPrimaryChildren = nextProps.children;
7596 var currentPrimaryChild = currentPrimaryChildFragment.child;
7597 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime);
7598
7599 // If this render doesn't suspend, we need to delete the fallback
7600 // children. Wait until the complete phase, after we've confirmed the
7601 // fallback is no longer needed.
7602 // TODO: Would it be better to store the fallback fragment on
7603 // the stateNode?
7604
7605 // Continue rendering the children, like we normally do.
7606 child = next = primaryChild;
7607 }
7608 } else {
7609 // The current tree has not already timed out. That means the primary
7610 // children are not wrapped in a fragment fiber.
7611 var _currentPrimaryChild = current.child;
7612 if (nextDidTimeout) {
7613 // Timed out. Wrap the children in a fragment fiber to keep them
7614 // separate from the fallback children.
7615 var _nextFallbackChildren2 = nextProps.fallback;
7616 var _primaryChildFragment2 = createFiberFromFragment(
7617 // It shouldn't matter what the pending props are because we aren't
7618 // going to render this fragment.
7619 null, mode, NoWork, null);
7620 _primaryChildFragment2.child = _currentPrimaryChild;
7621
7622 // Even though we're creating a new fiber, there are no new children,
7623 // because we're reusing an already mounted tree. So we don't need to
7624 // schedule a placement.
7625 // primaryChildFragment.effectTag |= Placement;
7626
7627 if ((workInProgress.mode & ConcurrentMode) === NoContext) {
7628 // Outside of concurrent mode, we commit the effects from the
7629 var _progressedState2 = workInProgress.memoizedState;
7630 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
7631 _primaryChildFragment2.child = _progressedPrimaryChild2;
7632 }
7633
7634 // Because primaryChildFragment is a new fiber that we're inserting as the
7635 // parent of a new tree, we need to set its treeBaseDuration.
7636 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
7637 // treeBaseDuration is the sum of all the child tree base durations.
7638 var _treeBaseDuration = 0;
7639 var _hiddenChild = _primaryChildFragment2.child;
7640 while (_hiddenChild !== null) {
7641 _treeBaseDuration += _hiddenChild.treeBaseDuration;
7642 _hiddenChild = _hiddenChild.sibling;
7643 }
7644 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
7645 }
7646
7647 // Create a fragment from the fallback children, too.
7648 var _fallbackChildFragment2 = _primaryChildFragment2.sibling = createFiberFromFragment(_nextFallbackChildren2, mode, renderExpirationTime, null);
7649 _fallbackChildFragment2.effectTag |= Placement;
7650 child = _primaryChildFragment2;
7651 _primaryChildFragment2.childExpirationTime = NoWork;
7652 // Skip the primary children, and continue working on the
7653 // fallback children.
7654 next = _fallbackChildFragment2;
7655 child.return = next.return = workInProgress;
7656 } else {
7657 // Still haven't timed out. Continue rendering the children, like we
7658 // normally do.
7659 var _nextPrimaryChildren2 = nextProps.children;
7660 next = child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
7661 }
7662 }
7663 workInProgress.stateNode = current.stateNode;
7664 }
7665
7666 workInProgress.memoizedState = nextState;
7667 workInProgress.child = child;
7668 return next;
7669}
7670
7671function updatePortalComponent(current, workInProgress, renderExpirationTime) {
7672 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7673 var nextChildren = workInProgress.pendingProps;
7674 if (current === null) {
7675 // Portals are special because we don't append the children during mount
7676 // but at commit. Therefore we need to track insertions which the normal
7677 // flow doesn't do during mount. This doesn't happen at the root because
7678 // the root always starts with a "current" with a null child.
7679 // TODO: Consider unifying this with how the root works.
7680 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
7681 } else {
7682 reconcileChildren(current, workInProgress, nextChildren, renderExpirationTime);
7683 }
7684 return workInProgress.child;
7685}
7686
7687function updateContextProvider(current, workInProgress, renderExpirationTime) {
7688 var providerType = workInProgress.type;
7689 var context = providerType._context;
7690
7691 var newProps = workInProgress.pendingProps;
7692 var oldProps = workInProgress.memoizedProps;
7693
7694 var newValue = newProps.value;
7695
7696 {
7697 var providerPropTypes = workInProgress.type.propTypes;
7698
7699 if (providerPropTypes) {
7700 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
7701 }
7702 }
7703
7704 pushProvider(workInProgress, newValue);
7705
7706 if (oldProps !== null) {
7707 var oldValue = oldProps.value;
7708 var changedBits = calculateChangedBits(context, newValue, oldValue);
7709 if (changedBits === 0) {
7710 // No change. Bailout early if children are the same.
7711 if (oldProps.children === newProps.children && !hasContextChanged()) {
7712 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7713 }
7714 } else {
7715 // The context value changed. Search for matching consumers and schedule
7716 // them to update.
7717 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
7718 }
7719 }
7720
7721 var newChildren = newProps.children;
7722 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
7723 return workInProgress.child;
7724}
7725
7726var hasWarnedAboutUsingContextAsConsumer = false;
7727
7728function updateContextConsumer(current, workInProgress, renderExpirationTime) {
7729 var context = workInProgress.type;
7730 // The logic below for Context differs depending on PROD or DEV mode. In
7731 // DEV mode, we create a separate object for Context.Consumer that acts
7732 // like a proxy to Context. This proxy object adds unnecessary code in PROD
7733 // so we use the old behaviour (Context.Consumer references Context) to
7734 // reduce size and overhead. The separate object references context via
7735 // a property called "_context", which also gives us the ability to check
7736 // in DEV mode if this property exists or not and warn if it does not.
7737 {
7738 if (context._context === undefined) {
7739 // This may be because it's a Context (rather than a Consumer).
7740 // Or it may be because it's older React where they're the same thing.
7741 // We only want to warn if we're sure it's a new React.
7742 if (context !== context.Consumer) {
7743 if (!hasWarnedAboutUsingContextAsConsumer) {
7744 hasWarnedAboutUsingContextAsConsumer = true;
7745 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?');
7746 }
7747 }
7748 } else {
7749 context = context._context;
7750 }
7751 }
7752 var newProps = workInProgress.pendingProps;
7753 var render = newProps.children;
7754
7755 {
7756 !(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;
7757 }
7758
7759 prepareToReadContext(workInProgress, renderExpirationTime);
7760 var newValue = readContext(context, newProps.unstable_observedBits);
7761 var newChildren = void 0;
7762 {
7763 ReactCurrentOwner$2.current = workInProgress;
7764 setCurrentPhase('render');
7765 newChildren = render(newValue);
7766 setCurrentPhase(null);
7767 }
7768
7769 // React DevTools reads this flag.
7770 workInProgress.effectTag |= PerformedWork;
7771 reconcileChildren(current, workInProgress, newChildren, renderExpirationTime);
7772 return workInProgress.child;
7773}
7774
7775function markWorkInProgressReceivedUpdate() {
7776 didReceiveUpdate = true;
7777}
7778
7779function bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime) {
7780 cancelWorkTimer(workInProgress);
7781
7782 if (current !== null) {
7783 // Reuse previous context list
7784 workInProgress.contextDependencies = current.contextDependencies;
7785 }
7786
7787 if (enableProfilerTimer) {
7788 // Don't update "base" render times for bailouts.
7789 stopProfilerTimerIfRunning(workInProgress);
7790 }
7791
7792 // Check if the children have any pending work.
7793 var childExpirationTime = workInProgress.childExpirationTime;
7794 if (childExpirationTime < renderExpirationTime) {
7795 // The children don't have any work either. We can skip them.
7796 // TODO: Once we add back resuming, we should check if the children are
7797 // a work-in-progress set. If so, we need to transfer their effects.
7798 return null;
7799 } else {
7800 // This fiber doesn't have work, but its subtree does. Clone the child
7801 // fibers and continue.
7802 cloneChildFibers(current, workInProgress);
7803 return workInProgress.child;
7804 }
7805}
7806
7807function beginWork(current, workInProgress, renderExpirationTime) {
7808 var updateExpirationTime = workInProgress.expirationTime;
7809
7810 if (current !== null) {
7811 var oldProps = current.memoizedProps;
7812 var newProps = workInProgress.pendingProps;
7813
7814 if (oldProps !== newProps || hasContextChanged()) {
7815 // If props or context changed, mark the fiber as having performed work.
7816 // This may be unset if the props are determined to be equal later (memo).
7817 didReceiveUpdate = true;
7818 } else if (updateExpirationTime < renderExpirationTime) {
7819 didReceiveUpdate = false;
7820 // This fiber does not have any pending work. Bailout without entering
7821 // the begin phase. There's still some bookkeeping we that needs to be done
7822 // in this optimized path, mostly pushing stuff onto the stack.
7823 switch (workInProgress.tag) {
7824 case HostRoot:
7825 pushHostRootContext(workInProgress);
7826 resetHydrationState();
7827 break;
7828 case HostComponent:
7829 pushHostContext(workInProgress);
7830 break;
7831 case ClassComponent:
7832 {
7833 var Component = workInProgress.type;
7834 if (isContextProvider(Component)) {
7835 pushContextProvider(workInProgress);
7836 }
7837 break;
7838 }
7839 case HostPortal:
7840 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
7841 break;
7842 case ContextProvider:
7843 {
7844 var newValue = workInProgress.memoizedProps.value;
7845 pushProvider(workInProgress, newValue);
7846 break;
7847 }
7848 case Profiler:
7849 if (enableProfilerTimer) {
7850 workInProgress.effectTag |= Update;
7851 }
7852 break;
7853 case SuspenseComponent:
7854 {
7855 var state = workInProgress.memoizedState;
7856 var didTimeout = state !== null;
7857 if (didTimeout) {
7858 // If this boundary is currently timed out, we need to decide
7859 // whether to retry the primary children, or to skip over it and
7860 // go straight to the fallback. Check the priority of the primary
7861 var primaryChildFragment = workInProgress.child;
7862 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
7863 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
7864 // The primary children have pending work. Use the normal path
7865 // to attempt to render the primary children again.
7866 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
7867 } else {
7868 // The primary children do not have pending work with sufficient
7869 // priority. Bailout.
7870 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7871 if (child !== null) {
7872 // The fallback children have pending work. Skip over the
7873 // primary children and work on the fallback.
7874 return child.sibling;
7875 } else {
7876 return null;
7877 }
7878 }
7879 }
7880 break;
7881 }
7882 }
7883 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderExpirationTime);
7884 }
7885 } else {
7886 didReceiveUpdate = false;
7887 }
7888
7889 // Before entering the begin phase, clear the expiration time.
7890 workInProgress.expirationTime = NoWork;
7891
7892 switch (workInProgress.tag) {
7893 case IndeterminateComponent:
7894 {
7895 var elementType = workInProgress.elementType;
7896 return mountIndeterminateComponent(current, workInProgress, elementType, renderExpirationTime);
7897 }
7898 case LazyComponent:
7899 {
7900 var _elementType = workInProgress.elementType;
7901 return mountLazyComponent(current, workInProgress, _elementType, updateExpirationTime, renderExpirationTime);
7902 }
7903 case FunctionComponent:
7904 {
7905 var _Component = workInProgress.type;
7906 var unresolvedProps = workInProgress.pendingProps;
7907 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
7908 return updateFunctionComponent(current, workInProgress, _Component, resolvedProps, renderExpirationTime);
7909 }
7910 case ClassComponent:
7911 {
7912 var _Component2 = workInProgress.type;
7913 var _unresolvedProps = workInProgress.pendingProps;
7914 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
7915 return updateClassComponent(current, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
7916 }
7917 case HostRoot:
7918 return updateHostRoot(current, workInProgress, renderExpirationTime);
7919 case HostComponent:
7920 return updateHostComponent(current, workInProgress, renderExpirationTime);
7921 case HostText:
7922 return updateHostText(current, workInProgress);
7923 case SuspenseComponent:
7924 return updateSuspenseComponent(current, workInProgress, renderExpirationTime);
7925 case HostPortal:
7926 return updatePortalComponent(current, workInProgress, renderExpirationTime);
7927 case ForwardRef:
7928 {
7929 var type = workInProgress.type;
7930 var _unresolvedProps2 = workInProgress.pendingProps;
7931 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
7932 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderExpirationTime);
7933 }
7934 case Fragment:
7935 return updateFragment(current, workInProgress, renderExpirationTime);
7936 case Mode:
7937 return updateMode(current, workInProgress, renderExpirationTime);
7938 case Profiler:
7939 return updateProfiler(current, workInProgress, renderExpirationTime);
7940 case ContextProvider:
7941 return updateContextProvider(current, workInProgress, renderExpirationTime);
7942 case ContextConsumer:
7943 return updateContextConsumer(current, workInProgress, renderExpirationTime);
7944 case MemoComponent:
7945 {
7946 var _type2 = workInProgress.type;
7947 var _unresolvedProps3 = workInProgress.pendingProps;
7948 // Resolve outer props first, then resolve inner props.
7949 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
7950 {
7951 if (workInProgress.type !== workInProgress.elementType) {
7952 var outerPropTypes = _type2.propTypes;
7953 if (outerPropTypes) {
7954 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
7955 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
7956 }
7957 }
7958 }
7959 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
7960 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
7961 }
7962 case SimpleMemoComponent:
7963 {
7964 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
7965 }
7966 case IncompleteClassComponent:
7967 {
7968 var _Component3 = workInProgress.type;
7969 var _unresolvedProps4 = workInProgress.pendingProps;
7970 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
7971 return mountIncompleteClassComponent(current, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
7972 }
7973 default:
7974 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
7975 }
7976}
7977
7978var valueCursor = createCursor(null);
7979
7980var rendererSigil = void 0;
7981{
7982 // Use this to detect multiple renderers using the same context
7983 rendererSigil = {};
7984}
7985
7986var currentlyRenderingFiber = null;
7987var lastContextDependency = null;
7988var lastContextWithAllBitsObserved = null;
7989
7990var isDisallowedContextReadInDEV = false;
7991
7992function resetContextDependences() {
7993 // This is called right before React yields execution, to ensure `readContext`
7994 // cannot be called outside the render phase.
7995 currentlyRenderingFiber = null;
7996 lastContextDependency = null;
7997 lastContextWithAllBitsObserved = null;
7998 {
7999 isDisallowedContextReadInDEV = false;
8000 }
8001}
8002
8003function enterDisallowedContextReadInDEV() {
8004 {
8005 isDisallowedContextReadInDEV = true;
8006 }
8007}
8008
8009function exitDisallowedContextReadInDEV() {
8010 {
8011 isDisallowedContextReadInDEV = false;
8012 }
8013}
8014
8015function pushProvider(providerFiber, nextValue) {
8016 var context = providerFiber.type._context;
8017
8018 if (isPrimaryRenderer) {
8019 push(valueCursor, context._currentValue, providerFiber);
8020
8021 context._currentValue = nextValue;
8022 {
8023 !(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;
8024 context._currentRenderer = rendererSigil;
8025 }
8026 } else {
8027 push(valueCursor, context._currentValue2, providerFiber);
8028
8029 context._currentValue2 = nextValue;
8030 {
8031 !(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;
8032 context._currentRenderer2 = rendererSigil;
8033 }
8034 }
8035}
8036
8037function popProvider(providerFiber) {
8038 var currentValue = valueCursor.current;
8039
8040 pop(valueCursor, providerFiber);
8041
8042 var context = providerFiber.type._context;
8043 if (isPrimaryRenderer) {
8044 context._currentValue = currentValue;
8045 } else {
8046 context._currentValue2 = currentValue;
8047 }
8048}
8049
8050function calculateChangedBits(context, newValue, oldValue) {
8051 if (is(oldValue, newValue)) {
8052 // No change
8053 return 0;
8054 } else {
8055 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : maxSigned31BitInt;
8056
8057 {
8058 !((changedBits & maxSigned31BitInt) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
8059 }
8060 return changedBits | 0;
8061 }
8062}
8063
8064function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
8065 var fiber = workInProgress.child;
8066 if (fiber !== null) {
8067 // Set the return pointer of the child to the work-in-progress fiber.
8068 fiber.return = workInProgress;
8069 }
8070 while (fiber !== null) {
8071 var nextFiber = void 0;
8072
8073 // Visit this fiber.
8074 var list = fiber.contextDependencies;
8075 if (list !== null) {
8076 nextFiber = fiber.child;
8077
8078 var dependency = list.first;
8079 while (dependency !== null) {
8080 // Check if the context matches.
8081 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
8082 // Match! Schedule an update on this fiber.
8083
8084 if (fiber.tag === ClassComponent) {
8085 // Schedule a force update on the work-in-progress.
8086 var update = createUpdate(renderExpirationTime);
8087 update.tag = ForceUpdate;
8088 // TODO: Because we don't have a work-in-progress, this will add the
8089 // update to the current fiber, too, which means it will persist even if
8090 // this render is thrown away. Since it's a race condition, not sure it's
8091 // worth fixing.
8092 enqueueUpdate(fiber, update);
8093 }
8094
8095 if (fiber.expirationTime < renderExpirationTime) {
8096 fiber.expirationTime = renderExpirationTime;
8097 }
8098 var alternate = fiber.alternate;
8099 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
8100 alternate.expirationTime = renderExpirationTime;
8101 }
8102 // Update the child expiration time of all the ancestors, including
8103 // the alternates.
8104 var node = fiber.return;
8105 while (node !== null) {
8106 alternate = node.alternate;
8107 if (node.childExpirationTime < renderExpirationTime) {
8108 node.childExpirationTime = renderExpirationTime;
8109 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8110 alternate.childExpirationTime = renderExpirationTime;
8111 }
8112 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
8113 alternate.childExpirationTime = renderExpirationTime;
8114 } else {
8115 // Neither alternate was updated, which means the rest of the
8116 // ancestor path already has sufficient priority.
8117 break;
8118 }
8119 node = node.return;
8120 }
8121
8122 // Mark the expiration time on the list, too.
8123 if (list.expirationTime < renderExpirationTime) {
8124 list.expirationTime = renderExpirationTime;
8125 }
8126
8127 // Since we already found a match, we can stop traversing the
8128 // dependency list.
8129 break;
8130 }
8131 dependency = dependency.next;
8132 }
8133 } else if (fiber.tag === ContextProvider) {
8134 // Don't scan deeper if this is a matching provider
8135 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
8136 } else {
8137 // Traverse down.
8138 nextFiber = fiber.child;
8139 }
8140
8141 if (nextFiber !== null) {
8142 // Set the return pointer of the child to the work-in-progress fiber.
8143 nextFiber.return = fiber;
8144 } else {
8145 // No child. Traverse to next sibling.
8146 nextFiber = fiber;
8147 while (nextFiber !== null) {
8148 if (nextFiber === workInProgress) {
8149 // We're back to the root of this subtree. Exit.
8150 nextFiber = null;
8151 break;
8152 }
8153 var sibling = nextFiber.sibling;
8154 if (sibling !== null) {
8155 // Set the return pointer of the sibling to the work-in-progress fiber.
8156 sibling.return = nextFiber.return;
8157 nextFiber = sibling;
8158 break;
8159 }
8160 // No more siblings. Traverse up.
8161 nextFiber = nextFiber.return;
8162 }
8163 }
8164 fiber = nextFiber;
8165 }
8166}
8167
8168function prepareToReadContext(workInProgress, renderExpirationTime) {
8169 currentlyRenderingFiber = workInProgress;
8170 lastContextDependency = null;
8171 lastContextWithAllBitsObserved = null;
8172
8173 var currentDependencies = workInProgress.contextDependencies;
8174 if (currentDependencies !== null && currentDependencies.expirationTime >= renderExpirationTime) {
8175 // Context list has a pending update. Mark that this fiber performed work.
8176 markWorkInProgressReceivedUpdate();
8177 }
8178
8179 // Reset the work-in-progress list
8180 workInProgress.contextDependencies = null;
8181}
8182
8183function readContext(context, observedBits) {
8184 {
8185 // This warning would fire if you read context inside a Hook like useMemo.
8186 // Unlike the class check below, it's not enforced in production for perf.
8187 !!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;
8188 }
8189
8190 if (lastContextWithAllBitsObserved === context) {
8191 // Nothing to do. We already observe everything in this context.
8192 } else if (observedBits === false || observedBits === 0) {
8193 // Do not observe any updates.
8194 } else {
8195 var resolvedObservedBits = void 0; // Avoid deopting on observable arguments or heterogeneous types.
8196 if (typeof observedBits !== 'number' || observedBits === maxSigned31BitInt) {
8197 // Observe all updates.
8198 lastContextWithAllBitsObserved = context;
8199 resolvedObservedBits = maxSigned31BitInt;
8200 } else {
8201 resolvedObservedBits = observedBits;
8202 }
8203
8204 var contextItem = {
8205 context: context,
8206 observedBits: resolvedObservedBits,
8207 next: null
8208 };
8209
8210 if (lastContextDependency === null) {
8211 !(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;
8212
8213 // This is the first dependency for this component. Create a new list.
8214 lastContextDependency = contextItem;
8215 currentlyRenderingFiber.contextDependencies = {
8216 first: contextItem,
8217 expirationTime: NoWork
8218 };
8219 } else {
8220 // Append a new context item.
8221 lastContextDependency = lastContextDependency.next = contextItem;
8222 }
8223 }
8224 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
8225}
8226
8227// UpdateQueue is a linked list of prioritized updates.
8228//
8229// Like fibers, update queues come in pairs: a current queue, which represents
8230// the visible state of the screen, and a work-in-progress queue, which can be
8231// mutated and processed asynchronously before it is committed — a form of
8232// double buffering. If a work-in-progress render is discarded before finishing,
8233// we create a new work-in-progress by cloning the current queue.
8234//
8235// Both queues share a persistent, singly-linked list structure. To schedule an
8236// update, we append it to the end of both queues. Each queue maintains a
8237// pointer to first update in the persistent list that hasn't been processed.
8238// The work-in-progress pointer always has a position equal to or greater than
8239// the current queue, since we always work on that one. The current queue's
8240// pointer is only updated during the commit phase, when we swap in the
8241// work-in-progress.
8242//
8243// For example:
8244//
8245// Current pointer: A - B - C - D - E - F
8246// Work-in-progress pointer: D - E - F
8247// ^
8248// The work-in-progress queue has
8249// processed more updates than current.
8250//
8251// The reason we append to both queues is because otherwise we might drop
8252// updates without ever processing them. For example, if we only add updates to
8253// the work-in-progress queue, some updates could be lost whenever a work-in
8254// -progress render restarts by cloning from current. Similarly, if we only add
8255// updates to the current queue, the updates will be lost whenever an already
8256// in-progress queue commits and swaps with the current queue. However, by
8257// adding to both queues, we guarantee that the update will be part of the next
8258// work-in-progress. (And because the work-in-progress queue becomes the
8259// current queue once it commits, there's no danger of applying the same
8260// update twice.)
8261//
8262// Prioritization
8263// --------------
8264//
8265// Updates are not sorted by priority, but by insertion; new updates are always
8266// appended to the end of the list.
8267//
8268// The priority is still important, though. When processing the update queue
8269// during the render phase, only the updates with sufficient priority are
8270// included in the result. If we skip an update because it has insufficient
8271// priority, it remains in the queue to be processed later, during a lower
8272// priority render. Crucially, all updates subsequent to a skipped update also
8273// remain in the queue *regardless of their priority*. That means high priority
8274// updates are sometimes processed twice, at two separate priorities. We also
8275// keep track of a base state, that represents the state before the first
8276// update in the queue is applied.
8277//
8278// For example:
8279//
8280// Given a base state of '', and the following queue of updates
8281//
8282// A1 - B2 - C1 - D2
8283//
8284// where the number indicates the priority, and the update is applied to the
8285// previous state by appending a letter, React will process these updates as
8286// two separate renders, one per distinct priority level:
8287//
8288// First render, at priority 1:
8289// Base state: ''
8290// Updates: [A1, C1]
8291// Result state: 'AC'
8292//
8293// Second render, at priority 2:
8294// Base state: 'A' <- The base state does not include C1,
8295// because B2 was skipped.
8296// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
8297// Result state: 'ABCD'
8298//
8299// Because we process updates in insertion order, and rebase high priority
8300// updates when preceding updates are skipped, the final result is deterministic
8301// regardless of priority. Intermediate state may vary according to system
8302// resources, but the final state is always the same.
8303
8304var UpdateState = 0;
8305var ReplaceState = 1;
8306var ForceUpdate = 2;
8307var CaptureUpdate = 3;
8308
8309// Global state that is reset at the beginning of calling `processUpdateQueue`.
8310// It should only be read right after calling `processUpdateQueue`, via
8311// `checkHasForceUpdateAfterProcessing`.
8312var hasForceUpdate = false;
8313
8314var didWarnUpdateInsideUpdate = void 0;
8315var currentlyProcessingQueue = void 0;
8316var resetCurrentlyProcessingQueue = void 0;
8317{
8318 didWarnUpdateInsideUpdate = false;
8319 currentlyProcessingQueue = null;
8320 resetCurrentlyProcessingQueue = function () {
8321 currentlyProcessingQueue = null;
8322 };
8323}
8324
8325function createUpdateQueue(baseState) {
8326 var queue = {
8327 baseState: baseState,
8328 firstUpdate: null,
8329 lastUpdate: null,
8330 firstCapturedUpdate: null,
8331 lastCapturedUpdate: null,
8332 firstEffect: null,
8333 lastEffect: null,
8334 firstCapturedEffect: null,
8335 lastCapturedEffect: null
8336 };
8337 return queue;
8338}
8339
8340function cloneUpdateQueue(currentQueue) {
8341 var queue = {
8342 baseState: currentQueue.baseState,
8343 firstUpdate: currentQueue.firstUpdate,
8344 lastUpdate: currentQueue.lastUpdate,
8345
8346 // TODO: With resuming, if we bail out and resuse the child tree, we should
8347 // keep these effects.
8348 firstCapturedUpdate: null,
8349 lastCapturedUpdate: null,
8350
8351 firstEffect: null,
8352 lastEffect: null,
8353
8354 firstCapturedEffect: null,
8355 lastCapturedEffect: null
8356 };
8357 return queue;
8358}
8359
8360function createUpdate(expirationTime) {
8361 return {
8362 expirationTime: expirationTime,
8363
8364 tag: UpdateState,
8365 payload: null,
8366 callback: null,
8367
8368 next: null,
8369 nextEffect: null
8370 };
8371}
8372
8373function appendUpdateToQueue(queue, update) {
8374 // Append the update to the end of the list.
8375 if (queue.lastUpdate === null) {
8376 // Queue is empty
8377 queue.firstUpdate = queue.lastUpdate = update;
8378 } else {
8379 queue.lastUpdate.next = update;
8380 queue.lastUpdate = update;
8381 }
8382}
8383
8384function enqueueUpdate(fiber, update) {
8385 // Update queues are created lazily.
8386 var alternate = fiber.alternate;
8387 var queue1 = void 0;
8388 var queue2 = void 0;
8389 if (alternate === null) {
8390 // There's only one fiber.
8391 queue1 = fiber.updateQueue;
8392 queue2 = null;
8393 if (queue1 === null) {
8394 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8395 }
8396 } else {
8397 // There are two owners.
8398 queue1 = fiber.updateQueue;
8399 queue2 = alternate.updateQueue;
8400 if (queue1 === null) {
8401 if (queue2 === null) {
8402 // Neither fiber has an update queue. Create new ones.
8403 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
8404 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
8405 } else {
8406 // Only one fiber has an update queue. Clone to create a new one.
8407 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
8408 }
8409 } else {
8410 if (queue2 === null) {
8411 // Only one fiber has an update queue. Clone to create a new one.
8412 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
8413 } else {
8414 // Both owners have an update queue.
8415 }
8416 }
8417 }
8418 if (queue2 === null || queue1 === queue2) {
8419 // There's only a single queue.
8420 appendUpdateToQueue(queue1, update);
8421 } else {
8422 // There are two queues. We need to append the update to both queues,
8423 // while accounting for the persistent structure of the list — we don't
8424 // want the same update to be added multiple times.
8425 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
8426 // One of the queues is not empty. We must add the update to both queues.
8427 appendUpdateToQueue(queue1, update);
8428 appendUpdateToQueue(queue2, update);
8429 } else {
8430 // Both queues are non-empty. The last update is the same in both lists,
8431 // because of structural sharing. So, only append to one of the lists.
8432 appendUpdateToQueue(queue1, update);
8433 // But we still need to update the `lastUpdate` pointer of queue2.
8434 queue2.lastUpdate = update;
8435 }
8436 }
8437
8438 {
8439 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
8440 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.');
8441 didWarnUpdateInsideUpdate = true;
8442 }
8443 }
8444}
8445
8446function enqueueCapturedUpdate(workInProgress, update) {
8447 // Captured updates go into a separate list, and only on the work-in-
8448 // progress queue.
8449 var workInProgressQueue = workInProgress.updateQueue;
8450 if (workInProgressQueue === null) {
8451 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
8452 } else {
8453 // TODO: I put this here rather than createWorkInProgress so that we don't
8454 // clone the queue unnecessarily. There's probably a better way to
8455 // structure this.
8456 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
8457 }
8458
8459 // Append the update to the end of the list.
8460 if (workInProgressQueue.lastCapturedUpdate === null) {
8461 // This is the first render phase update
8462 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
8463 } else {
8464 workInProgressQueue.lastCapturedUpdate.next = update;
8465 workInProgressQueue.lastCapturedUpdate = update;
8466 }
8467}
8468
8469function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
8470 var current = workInProgress.alternate;
8471 if (current !== null) {
8472 // If the work-in-progress queue is equal to the current queue,
8473 // we need to clone it first.
8474 if (queue === current.updateQueue) {
8475 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
8476 }
8477 }
8478 return queue;
8479}
8480
8481function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
8482 switch (update.tag) {
8483 case ReplaceState:
8484 {
8485 var _payload = update.payload;
8486 if (typeof _payload === 'function') {
8487 // Updater function
8488 {
8489 enterDisallowedContextReadInDEV();
8490 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8491 _payload.call(instance, prevState, nextProps);
8492 }
8493 }
8494 var nextState = _payload.call(instance, prevState, nextProps);
8495 {
8496 exitDisallowedContextReadInDEV();
8497 }
8498 return nextState;
8499 }
8500 // State object
8501 return _payload;
8502 }
8503 case CaptureUpdate:
8504 {
8505 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
8506 }
8507 // Intentional fallthrough
8508 case UpdateState:
8509 {
8510 var _payload2 = update.payload;
8511 var partialState = void 0;
8512 if (typeof _payload2 === 'function') {
8513 // Updater function
8514 {
8515 enterDisallowedContextReadInDEV();
8516 if (debugRenderPhaseSideEffects || debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
8517 _payload2.call(instance, prevState, nextProps);
8518 }
8519 }
8520 partialState = _payload2.call(instance, prevState, nextProps);
8521 {
8522 exitDisallowedContextReadInDEV();
8523 }
8524 } else {
8525 // Partial state object
8526 partialState = _payload2;
8527 }
8528 if (partialState === null || partialState === undefined) {
8529 // Null and undefined are treated as no-ops.
8530 return prevState;
8531 }
8532 // Merge the partial state and the previous state.
8533 return _assign({}, prevState, partialState);
8534 }
8535 case ForceUpdate:
8536 {
8537 hasForceUpdate = true;
8538 return prevState;
8539 }
8540 }
8541 return prevState;
8542}
8543
8544function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
8545 hasForceUpdate = false;
8546
8547 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
8548
8549 {
8550 currentlyProcessingQueue = queue;
8551 }
8552
8553 // These values may change as we process the queue.
8554 var newBaseState = queue.baseState;
8555 var newFirstUpdate = null;
8556 var newExpirationTime = NoWork;
8557
8558 // Iterate through the list of updates to compute the result.
8559 var update = queue.firstUpdate;
8560 var resultState = newBaseState;
8561 while (update !== null) {
8562 var updateExpirationTime = update.expirationTime;
8563 if (updateExpirationTime < renderExpirationTime) {
8564 // This update does not have sufficient priority. Skip it.
8565 if (newFirstUpdate === null) {
8566 // This is the first skipped update. It will be the first update in
8567 // the new list.
8568 newFirstUpdate = update;
8569 // Since this is the first update that was skipped, the current result
8570 // is the new base state.
8571 newBaseState = resultState;
8572 }
8573 // Since this update will remain in the list, update the remaining
8574 // expiration time.
8575 if (newExpirationTime < updateExpirationTime) {
8576 newExpirationTime = updateExpirationTime;
8577 }
8578 } else {
8579 // This update does have sufficient priority. Process it and compute
8580 // a new result.
8581 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8582 var _callback = update.callback;
8583 if (_callback !== null) {
8584 workInProgress.effectTag |= Callback;
8585 // Set this to null, in case it was mutated during an aborted render.
8586 update.nextEffect = null;
8587 if (queue.lastEffect === null) {
8588 queue.firstEffect = queue.lastEffect = update;
8589 } else {
8590 queue.lastEffect.nextEffect = update;
8591 queue.lastEffect = update;
8592 }
8593 }
8594 }
8595 // Continue to the next update.
8596 update = update.next;
8597 }
8598
8599 // Separately, iterate though the list of captured updates.
8600 var newFirstCapturedUpdate = null;
8601 update = queue.firstCapturedUpdate;
8602 while (update !== null) {
8603 var _updateExpirationTime = update.expirationTime;
8604 if (_updateExpirationTime < renderExpirationTime) {
8605 // This update does not have sufficient priority. Skip it.
8606 if (newFirstCapturedUpdate === null) {
8607 // This is the first skipped captured update. It will be the first
8608 // update in the new list.
8609 newFirstCapturedUpdate = update;
8610 // If this is the first update that was skipped, the current result is
8611 // the new base state.
8612 if (newFirstUpdate === null) {
8613 newBaseState = resultState;
8614 }
8615 }
8616 // Since this update will remain in the list, update the remaining
8617 // expiration time.
8618 if (newExpirationTime < _updateExpirationTime) {
8619 newExpirationTime = _updateExpirationTime;
8620 }
8621 } else {
8622 // This update does have sufficient priority. Process it and compute
8623 // a new result.
8624 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
8625 var _callback2 = update.callback;
8626 if (_callback2 !== null) {
8627 workInProgress.effectTag |= Callback;
8628 // Set this to null, in case it was mutated during an aborted render.
8629 update.nextEffect = null;
8630 if (queue.lastCapturedEffect === null) {
8631 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
8632 } else {
8633 queue.lastCapturedEffect.nextEffect = update;
8634 queue.lastCapturedEffect = update;
8635 }
8636 }
8637 }
8638 update = update.next;
8639 }
8640
8641 if (newFirstUpdate === null) {
8642 queue.lastUpdate = null;
8643 }
8644 if (newFirstCapturedUpdate === null) {
8645 queue.lastCapturedUpdate = null;
8646 } else {
8647 workInProgress.effectTag |= Callback;
8648 }
8649 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
8650 // We processed every update, without skipping. That means the new base
8651 // state is the same as the result state.
8652 newBaseState = resultState;
8653 }
8654
8655 queue.baseState = newBaseState;
8656 queue.firstUpdate = newFirstUpdate;
8657 queue.firstCapturedUpdate = newFirstCapturedUpdate;
8658
8659 // Set the remaining expiration time to be whatever is remaining in the queue.
8660 // This should be fine because the only two other things that contribute to
8661 // expiration time are props and context. We're already in the middle of the
8662 // begin phase by the time we start processing the queue, so we've already
8663 // dealt with the props. Context in components that specify
8664 // shouldComponentUpdate is tricky; but we'll have to account for
8665 // that regardless.
8666 workInProgress.expirationTime = newExpirationTime;
8667 workInProgress.memoizedState = resultState;
8668
8669 {
8670 currentlyProcessingQueue = null;
8671 }
8672}
8673
8674function callCallback(callback, context) {
8675 !(typeof callback === 'function') ? invariant(false, 'Invalid argument passed as callback. Expected a function. Instead received: %s', callback) : void 0;
8676 callback.call(context);
8677}
8678
8679function resetHasForceUpdateBeforeProcessing() {
8680 hasForceUpdate = false;
8681}
8682
8683function checkHasForceUpdateAfterProcessing() {
8684 return hasForceUpdate;
8685}
8686
8687function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
8688 // If the finished render included captured updates, and there are still
8689 // lower priority updates left over, we need to keep the captured updates
8690 // in the queue so that they are rebased and not dropped once we process the
8691 // queue again at the lower priority.
8692 if (finishedQueue.firstCapturedUpdate !== null) {
8693 // Join the captured update list to the end of the normal list.
8694 if (finishedQueue.lastUpdate !== null) {
8695 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
8696 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
8697 }
8698 // Clear the list of captured updates.
8699 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
8700 }
8701
8702 // Commit the effects
8703 commitUpdateEffects(finishedQueue.firstEffect, instance);
8704 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
8705
8706 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
8707 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
8708}
8709
8710function commitUpdateEffects(effect, instance) {
8711 while (effect !== null) {
8712 var _callback3 = effect.callback;
8713 if (_callback3 !== null) {
8714 effect.callback = null;
8715 callCallback(_callback3, instance);
8716 }
8717 effect = effect.nextEffect;
8718 }
8719}
8720
8721function createCapturedValue(value, source) {
8722 // If the value is an error, call this function immediately after it is thrown
8723 // so the stack is accurate.
8724 return {
8725 value: value,
8726 source: source,
8727 stack: getStackByFiberInDevAndProd(source)
8728 };
8729}
8730
8731function markUpdate(workInProgress) {
8732 // Tag the fiber with an update effect. This turns a Placement into
8733 // a PlacementAndUpdate.
8734 workInProgress.effectTag |= Update;
8735}
8736
8737function markRef$1(workInProgress) {
8738 workInProgress.effectTag |= Ref;
8739}
8740
8741var appendAllChildren = void 0;
8742var updateHostContainer = void 0;
8743var updateHostComponent$1 = void 0;
8744var updateHostText$1 = void 0;
8745if (supportsMutation) {
8746 // Mutation mode
8747
8748 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
8749 // We only have the top Fiber that was created but we need recurse down its
8750 // children to find all the terminal nodes.
8751 var node = workInProgress.child;
8752 while (node !== null) {
8753 if (node.tag === HostComponent || node.tag === HostText) {
8754 appendInitialChild(parent, node.stateNode);
8755 } else if (node.tag === HostPortal) {
8756 // If we have a portal child, then we don't want to traverse
8757 // down its children. Instead, we'll get insertions from each child in
8758 // the portal directly.
8759 } else if (node.child !== null) {
8760 node.child.return = node;
8761 node = node.child;
8762 continue;
8763 }
8764 if (node === workInProgress) {
8765 return;
8766 }
8767 while (node.sibling === null) {
8768 if (node.return === null || node.return === workInProgress) {
8769 return;
8770 }
8771 node = node.return;
8772 }
8773 node.sibling.return = node.return;
8774 node = node.sibling;
8775 }
8776 };
8777
8778 updateHostContainer = function (workInProgress) {
8779 // Noop
8780 };
8781 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
8782 // If we have an alternate, that means this is an update and we need to
8783 // schedule a side-effect to do the updates.
8784 var oldProps = current.memoizedProps;
8785 if (oldProps === newProps) {
8786 // In mutation mode, this is sufficient for a bailout because
8787 // we won't touch this node even if children changed.
8788 return;
8789 }
8790
8791 // If we get updated because one of our children updated, we don't
8792 // have newProps so we'll have to reuse them.
8793 // TODO: Split the update API as separate for the props vs. children.
8794 // Even better would be if children weren't special cased at all tho.
8795 var instance = workInProgress.stateNode;
8796 var currentHostContext = getHostContext();
8797 // TODO: Experiencing an error where oldProps is null. Suggests a host
8798 // component is hitting the resume path. Figure out why. Possibly
8799 // related to `hidden`.
8800 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
8801 // TODO: Type this specific to this type of component.
8802 workInProgress.updateQueue = updatePayload;
8803 // If the update payload indicates that there is a change or if there
8804 // is a new ref we mark this as an update. All the work is done in commitWork.
8805 if (updatePayload) {
8806 markUpdate(workInProgress);
8807 }
8808 };
8809 updateHostText$1 = function (current, workInProgress, oldText, newText) {
8810 // If the text differs, mark it as an update. All the work in done in commitWork.
8811 if (oldText !== newText) {
8812 markUpdate(workInProgress);
8813 }
8814 };
8815} else if (supportsPersistence) {
8816 // Persistent host tree mode
8817
8818 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
8819 // We only have the top Fiber that was created but we need recurse down its
8820 // children to find all the terminal nodes.
8821 var node = workInProgress.child;
8822 while (node !== null) {
8823 // eslint-disable-next-line no-labels
8824 branches: if (node.tag === HostComponent) {
8825 var instance = node.stateNode;
8826 if (needsVisibilityToggle) {
8827 var props = node.memoizedProps;
8828 var type = node.type;
8829 if (isHidden) {
8830 // This child is inside a timed out tree. Hide it.
8831 instance = cloneHiddenInstance(instance, type, props, node);
8832 } else {
8833 // This child was previously inside a timed out tree. If it was not
8834 // updated during this render, it may need to be unhidden. Clone
8835 // again to be sure.
8836 instance = cloneUnhiddenInstance(instance, type, props, node);
8837 }
8838 node.stateNode = instance;
8839 }
8840 appendInitialChild(parent, instance);
8841 } else if (node.tag === HostText) {
8842 var _instance = node.stateNode;
8843 if (needsVisibilityToggle) {
8844 var text = node.memoizedProps;
8845 var rootContainerInstance = getRootHostContainer();
8846 var currentHostContext = getHostContext();
8847 if (isHidden) {
8848 _instance = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
8849 } else {
8850 _instance = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
8851 }
8852 node.stateNode = _instance;
8853 }
8854 appendInitialChild(parent, _instance);
8855 } else if (node.tag === HostPortal) {
8856 // If we have a portal child, then we don't want to traverse
8857 // down its children. Instead, we'll get insertions from each child in
8858 // the portal directly.
8859 } else if (node.tag === SuspenseComponent) {
8860 var current = node.alternate;
8861 if (current !== null) {
8862 var oldState = current.memoizedState;
8863 var newState = node.memoizedState;
8864 var oldIsHidden = oldState !== null;
8865 var newIsHidden = newState !== null;
8866 if (oldIsHidden !== newIsHidden) {
8867 // The placeholder either just timed out or switched back to the normal
8868 // children after having previously timed out. Toggle the visibility of
8869 // the direct host children.
8870 var primaryChildParent = newIsHidden ? node.child : node;
8871 if (primaryChildParent !== null) {
8872 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
8873 }
8874 // eslint-disable-next-line no-labels
8875 break branches;
8876 }
8877 }
8878 if (node.child !== null) {
8879 // Continue traversing like normal
8880 node.child.return = node;
8881 node = node.child;
8882 continue;
8883 }
8884 } else if (node.child !== null) {
8885 node.child.return = node;
8886 node = node.child;
8887 continue;
8888 }
8889 // $FlowFixMe This is correct but Flow is confused by the labeled break.
8890 node = node;
8891 if (node === workInProgress) {
8892 return;
8893 }
8894 while (node.sibling === null) {
8895 if (node.return === null || node.return === workInProgress) {
8896 return;
8897 }
8898 node = node.return;
8899 }
8900 node.sibling.return = node.return;
8901 node = node.sibling;
8902 }
8903 };
8904
8905 // An unfortunate fork of appendAllChildren because we have two different parent types.
8906 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
8907 // We only have the top Fiber that was created but we need recurse down its
8908 // children to find all the terminal nodes.
8909 var node = workInProgress.child;
8910 while (node !== null) {
8911 // eslint-disable-next-line no-labels
8912 branches: if (node.tag === HostComponent) {
8913 var instance = node.stateNode;
8914 if (needsVisibilityToggle) {
8915 var props = node.memoizedProps;
8916 var type = node.type;
8917 if (isHidden) {
8918 // This child is inside a timed out tree. Hide it.
8919 instance = cloneHiddenInstance(instance, type, props, node);
8920 } else {
8921 // This child was previously inside a timed out tree. If it was not
8922 // updated during this render, it may need to be unhidden. Clone
8923 // again to be sure.
8924 instance = cloneUnhiddenInstance(instance, type, props, node);
8925 }
8926 node.stateNode = instance;
8927 }
8928 appendChildToContainerChildSet(containerChildSet, instance);
8929 } else if (node.tag === HostText) {
8930 var _instance2 = node.stateNode;
8931 if (needsVisibilityToggle) {
8932 var text = node.memoizedProps;
8933 var rootContainerInstance = getRootHostContainer();
8934 var currentHostContext = getHostContext();
8935 if (isHidden) {
8936 _instance2 = createHiddenTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
8937 } else {
8938 _instance2 = createTextInstance(text, rootContainerInstance, currentHostContext, workInProgress);
8939 }
8940 node.stateNode = _instance2;
8941 }
8942 appendChildToContainerChildSet(containerChildSet, _instance2);
8943 } else if (node.tag === HostPortal) {
8944 // If we have a portal child, then we don't want to traverse
8945 // down its children. Instead, we'll get insertions from each child in
8946 // the portal directly.
8947 } else if (node.tag === SuspenseComponent) {
8948 var current = node.alternate;
8949 if (current !== null) {
8950 var oldState = current.memoizedState;
8951 var newState = node.memoizedState;
8952 var oldIsHidden = oldState !== null;
8953 var newIsHidden = newState !== null;
8954 if (oldIsHidden !== newIsHidden) {
8955 // The placeholder either just timed out or switched back to the normal
8956 // children after having previously timed out. Toggle the visibility of
8957 // the direct host children.
8958 var primaryChildParent = newIsHidden ? node.child : node;
8959 if (primaryChildParent !== null) {
8960 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
8961 }
8962 // eslint-disable-next-line no-labels
8963 break branches;
8964 }
8965 }
8966 if (node.child !== null) {
8967 // Continue traversing like normal
8968 node.child.return = node;
8969 node = node.child;
8970 continue;
8971 }
8972 } else if (node.child !== null) {
8973 node.child.return = node;
8974 node = node.child;
8975 continue;
8976 }
8977 // $FlowFixMe This is correct but Flow is confused by the labeled break.
8978 node = node;
8979 if (node === workInProgress) {
8980 return;
8981 }
8982 while (node.sibling === null) {
8983 if (node.return === null || node.return === workInProgress) {
8984 return;
8985 }
8986 node = node.return;
8987 }
8988 node.sibling.return = node.return;
8989 node = node.sibling;
8990 }
8991 };
8992 updateHostContainer = function (workInProgress) {
8993 var portalOrRoot = workInProgress.stateNode;
8994 var childrenUnchanged = workInProgress.firstEffect === null;
8995 if (childrenUnchanged) {
8996 // No changes, just reuse the existing instance.
8997 } else {
8998 var container = portalOrRoot.containerInfo;
8999 var newChildSet = createContainerChildSet(container);
9000 // If children might have changed, we have to add them all to the set.
9001 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
9002 portalOrRoot.pendingChildren = newChildSet;
9003 // Schedule an update on the container to swap out the container.
9004 markUpdate(workInProgress);
9005 finalizeContainerChildren(container, newChildSet);
9006 }
9007 };
9008 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9009 var currentInstance = current.stateNode;
9010 var oldProps = current.memoizedProps;
9011 // If there are no effects associated with this node, then none of our children had any updates.
9012 // This guarantees that we can reuse all of them.
9013 var childrenUnchanged = workInProgress.firstEffect === null;
9014 if (childrenUnchanged && oldProps === newProps) {
9015 // No changes, just reuse the existing instance.
9016 // Note that this might release a previous clone.
9017 workInProgress.stateNode = currentInstance;
9018 return;
9019 }
9020 var recyclableInstance = workInProgress.stateNode;
9021 var currentHostContext = getHostContext();
9022 var updatePayload = null;
9023 if (oldProps !== newProps) {
9024 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
9025 }
9026 if (childrenUnchanged && updatePayload === null) {
9027 // No changes, just reuse the existing instance.
9028 // Note that this might release a previous clone.
9029 workInProgress.stateNode = currentInstance;
9030 return;
9031 }
9032 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
9033 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
9034 markUpdate(workInProgress);
9035 }
9036 workInProgress.stateNode = newInstance;
9037 if (childrenUnchanged) {
9038 // If there are no other effects in this tree, we need to flag this node as having one.
9039 // Even though we're not going to use it for anything.
9040 // Otherwise parents won't know that there are new children to propagate upwards.
9041 markUpdate(workInProgress);
9042 } else {
9043 // If children might have changed, we have to add them all to the set.
9044 appendAllChildren(newInstance, workInProgress, false, false);
9045 }
9046 };
9047 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9048 if (oldText !== newText) {
9049 // If the text content differs, we'll create a new text instance for it.
9050 var rootContainerInstance = getRootHostContainer();
9051 var currentHostContext = getHostContext();
9052 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress);
9053 // We'll have to mark it as having an effect, even though we won't use the effect for anything.
9054 // This lets the parents know that at least one of their children has changed.
9055 markUpdate(workInProgress);
9056 }
9057 };
9058} else {
9059 // No host operations
9060 updateHostContainer = function (workInProgress) {
9061 // Noop
9062 };
9063 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
9064 // Noop
9065 };
9066 updateHostText$1 = function (current, workInProgress, oldText, newText) {
9067 // Noop
9068 };
9069}
9070
9071function completeWork(current, workInProgress, renderExpirationTime) {
9072 var newProps = workInProgress.pendingProps;
9073
9074 switch (workInProgress.tag) {
9075 case IndeterminateComponent:
9076 break;
9077 case LazyComponent:
9078 break;
9079 case SimpleMemoComponent:
9080 case FunctionComponent:
9081 break;
9082 case ClassComponent:
9083 {
9084 var Component = workInProgress.type;
9085 if (isContextProvider(Component)) {
9086 popContext(workInProgress);
9087 }
9088 break;
9089 }
9090 case HostRoot:
9091 {
9092 popHostContainer(workInProgress);
9093 popTopLevelContextObject(workInProgress);
9094 var fiberRoot = workInProgress.stateNode;
9095 if (fiberRoot.pendingContext) {
9096 fiberRoot.context = fiberRoot.pendingContext;
9097 fiberRoot.pendingContext = null;
9098 }
9099 if (current === null || current.child === null) {
9100 // If we hydrated, pop so that we can delete any remaining children
9101 // that weren't hydrated.
9102 popHydrationState(workInProgress);
9103 // This resets the hacky state to fix isMounted before committing.
9104 // TODO: Delete this when we delete isMounted and findDOMNode.
9105 workInProgress.effectTag &= ~Placement;
9106 }
9107 updateHostContainer(workInProgress);
9108 break;
9109 }
9110 case HostComponent:
9111 {
9112 popHostContext(workInProgress);
9113 var rootContainerInstance = getRootHostContainer();
9114 var type = workInProgress.type;
9115 if (current !== null && workInProgress.stateNode != null) {
9116 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
9117
9118 if (current.ref !== workInProgress.ref) {
9119 markRef$1(workInProgress);
9120 }
9121 } else {
9122 if (!newProps) {
9123 !(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;
9124 // This can happen when we abort work.
9125 break;
9126 }
9127
9128 var currentHostContext = getHostContext();
9129 // TODO: Move createInstance to beginWork and keep it on a context
9130 // "stack" as the parent. Then append children as we go in beginWork
9131 // or completeWork depending on we want to add then top->down or
9132 // bottom->up. Top->down is faster in IE11.
9133 var wasHydrated = popHydrationState(workInProgress);
9134 if (wasHydrated) {
9135 // TODO: Move this and createInstance step into the beginPhase
9136 // to consolidate.
9137 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
9138 // If changes to the hydrated node needs to be applied at the
9139 // commit-phase we mark this as such.
9140 markUpdate(workInProgress);
9141 }
9142 } else {
9143 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
9144
9145 appendAllChildren(instance, workInProgress, false, false);
9146
9147 // Certain renderers require commit-time effects for initial mount.
9148 // (eg DOM renderer supports auto-focus for certain elements).
9149 // Make sure such renderers get scheduled for later work.
9150 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
9151 markUpdate(workInProgress);
9152 }
9153 workInProgress.stateNode = instance;
9154 }
9155
9156 if (workInProgress.ref !== null) {
9157 // If there is a ref on a host node we need to schedule a callback
9158 markRef$1(workInProgress);
9159 }
9160 }
9161 break;
9162 }
9163 case HostText:
9164 {
9165 var newText = newProps;
9166 if (current && workInProgress.stateNode != null) {
9167 var oldText = current.memoizedProps;
9168 // If we have an alternate, that means this is an update and we need
9169 // to schedule a side-effect to do the updates.
9170 updateHostText$1(current, workInProgress, oldText, newText);
9171 } else {
9172 if (typeof newText !== 'string') {
9173 !(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;
9174 // This can happen when we abort work.
9175 }
9176 var _rootContainerInstance = getRootHostContainer();
9177 var _currentHostContext = getHostContext();
9178 var _wasHydrated = popHydrationState(workInProgress);
9179 if (_wasHydrated) {
9180 if (prepareToHydrateHostTextInstance(workInProgress)) {
9181 markUpdate(workInProgress);
9182 }
9183 } else {
9184 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
9185 }
9186 }
9187 break;
9188 }
9189 case ForwardRef:
9190 break;
9191 case SuspenseComponent:
9192 {
9193 var nextState = workInProgress.memoizedState;
9194 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
9195 // Something suspended. Re-render with the fallback children.
9196 workInProgress.expirationTime = renderExpirationTime;
9197 // Do not reset the effect list.
9198 return workInProgress;
9199 }
9200
9201 var nextDidTimeout = nextState !== null;
9202 var prevDidTimeout = current !== null && current.memoizedState !== null;
9203
9204 if (current !== null && !nextDidTimeout && prevDidTimeout) {
9205 // We just switched from the fallback to the normal children. Delete
9206 // the fallback.
9207 // TODO: Would it be better to store the fallback fragment on
9208 var currentFallbackChild = current.child.sibling;
9209 if (currentFallbackChild !== null) {
9210 // Deletions go at the beginning of the return fiber's effect list
9211 var first = workInProgress.firstEffect;
9212 if (first !== null) {
9213 workInProgress.firstEffect = currentFallbackChild;
9214 currentFallbackChild.nextEffect = first;
9215 } else {
9216 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
9217 currentFallbackChild.nextEffect = null;
9218 }
9219 currentFallbackChild.effectTag = Deletion;
9220 }
9221 }
9222
9223 if (nextDidTimeout || prevDidTimeout) {
9224 // If the children are hidden, or if they were previous hidden, schedule
9225 // an effect to toggle their visibility. This is also used to attach a
9226 // retry listener to the promise.
9227 workInProgress.effectTag |= Update;
9228 }
9229 break;
9230 }
9231 case Fragment:
9232 break;
9233 case Mode:
9234 break;
9235 case Profiler:
9236 break;
9237 case HostPortal:
9238 popHostContainer(workInProgress);
9239 updateHostContainer(workInProgress);
9240 break;
9241 case ContextProvider:
9242 // Pop provider fiber
9243 popProvider(workInProgress);
9244 break;
9245 case ContextConsumer:
9246 break;
9247 case MemoComponent:
9248 break;
9249 case IncompleteClassComponent:
9250 {
9251 // Same as class component case. I put it down here so that the tags are
9252 // sequential to ensure this switch is compiled to a jump table.
9253 var _Component = workInProgress.type;
9254 if (isContextProvider(_Component)) {
9255 popContext(workInProgress);
9256 }
9257 break;
9258 }
9259 default:
9260 invariant(false, 'Unknown unit of work tag. This error is likely caused by a bug in React. Please file an issue.');
9261 }
9262
9263 return null;
9264}
9265
9266function shouldCaptureSuspense(workInProgress) {
9267 // In order to capture, the Suspense component must have a fallback prop.
9268 if (workInProgress.memoizedProps.fallback === undefined) {
9269 return false;
9270 }
9271 // If it was the primary children that just suspended, capture and render the
9272 // fallback. Otherwise, don't capture and bubble to the next boundary.
9273 var nextState = workInProgress.memoizedState;
9274 return nextState === null;
9275}
9276
9277// This module is forked in different environments.
9278// By default, return `true` to log errors to the console.
9279// Forks can return `false` if this isn't desirable.
9280function showErrorDialog(capturedError) {
9281 return true;
9282}
9283
9284function logCapturedError(capturedError) {
9285 var logError = showErrorDialog(capturedError);
9286
9287 // Allow injected showErrorDialog() to prevent default console.error logging.
9288 // This enables renderers like ReactNative to better manage redbox behavior.
9289 if (logError === false) {
9290 return;
9291 }
9292
9293 var error = capturedError.error;
9294 {
9295 var componentName = capturedError.componentName,
9296 componentStack = capturedError.componentStack,
9297 errorBoundaryName = capturedError.errorBoundaryName,
9298 errorBoundaryFound = capturedError.errorBoundaryFound,
9299 willRetry = capturedError.willRetry;
9300
9301 // Browsers support silencing uncaught errors by calling
9302 // `preventDefault()` in window `error` handler.
9303 // We record this information as an expando on the error.
9304
9305 if (error != null && error._suppressLogging) {
9306 if (errorBoundaryFound && willRetry) {
9307 // The error is recoverable and was silenced.
9308 // Ignore it and don't print the stack addendum.
9309 // This is handy for testing error boundaries without noise.
9310 return;
9311 }
9312 // The error is fatal. Since the silencing might have
9313 // been accidental, we'll surface it anyway.
9314 // However, the browser would have silenced the original error
9315 // so we'll print it first, and then print the stack addendum.
9316 console.error(error);
9317 // For a more detailed description of this block, see:
9318 // https://github.com/facebook/react/pull/13384
9319 }
9320
9321 var componentNameMessage = componentName ? 'The above error occurred in the <' + componentName + '> component:' : 'The above error occurred in one of your React components:';
9322
9323 var errorBoundaryMessage = void 0;
9324 // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
9325 if (errorBoundaryFound && errorBoundaryName) {
9326 if (willRetry) {
9327 errorBoundaryMessage = 'React will try to recreate this component tree from scratch ' + ('using the error boundary you provided, ' + errorBoundaryName + '.');
9328 } else {
9329 errorBoundaryMessage = 'This error was initially handled by the error boundary ' + errorBoundaryName + '.\n' + 'Recreating the tree from scratch failed so React will unmount the tree.';
9330 }
9331 } else {
9332 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.';
9333 }
9334 var combinedMessage = '' + componentNameMessage + componentStack + '\n\n' + ('' + errorBoundaryMessage);
9335
9336 // In development, we provide our own message with just the component stack.
9337 // We don't include the original error message and JS stack because the browser
9338 // has already printed it. Even if the application swallows the error, it is still
9339 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
9340 console.error(combinedMessage);
9341 }
9342}
9343
9344var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
9345{
9346 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
9347}
9348
9349var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
9350
9351function logError(boundary, errorInfo) {
9352 var source = errorInfo.source;
9353 var stack = errorInfo.stack;
9354 if (stack === null && source !== null) {
9355 stack = getStackByFiberInDevAndProd(source);
9356 }
9357
9358 var capturedError = {
9359 componentName: source !== null ? getComponentName(source.type) : null,
9360 componentStack: stack !== null ? stack : '',
9361 error: errorInfo.value,
9362 errorBoundary: null,
9363 errorBoundaryName: null,
9364 errorBoundaryFound: false,
9365 willRetry: false
9366 };
9367
9368 if (boundary !== null && boundary.tag === ClassComponent) {
9369 capturedError.errorBoundary = boundary.stateNode;
9370 capturedError.errorBoundaryName = getComponentName(boundary.type);
9371 capturedError.errorBoundaryFound = true;
9372 capturedError.willRetry = true;
9373 }
9374
9375 try {
9376 logCapturedError(capturedError);
9377 } catch (e) {
9378 // This method must not throw, or React internal state will get messed up.
9379 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
9380 // we want to report this error outside of the normal stack as a last resort.
9381 // https://github.com/facebook/react/issues/13188
9382 setTimeout(function () {
9383 throw e;
9384 });
9385 }
9386}
9387
9388var callComponentWillUnmountWithTimer = function (current, instance) {
9389 startPhaseTimer(current, 'componentWillUnmount');
9390 instance.props = current.memoizedProps;
9391 instance.state = current.memoizedState;
9392 instance.componentWillUnmount();
9393 stopPhaseTimer();
9394};
9395
9396// Capture errors so they don't interrupt unmounting.
9397function safelyCallComponentWillUnmount(current, instance) {
9398 {
9399 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current, instance);
9400 if (hasCaughtError()) {
9401 var unmountError = clearCaughtError();
9402 captureCommitPhaseError(current, unmountError);
9403 }
9404 }
9405}
9406
9407function safelyDetachRef(current) {
9408 var ref = current.ref;
9409 if (ref !== null) {
9410 if (typeof ref === 'function') {
9411 {
9412 invokeGuardedCallback(null, ref, null, null);
9413 if (hasCaughtError()) {
9414 var refError = clearCaughtError();
9415 captureCommitPhaseError(current, refError);
9416 }
9417 }
9418 } else {
9419 ref.current = null;
9420 }
9421 }
9422}
9423
9424function safelyCallDestroy(current, destroy) {
9425 {
9426 invokeGuardedCallback(null, destroy, null);
9427 if (hasCaughtError()) {
9428 var error = clearCaughtError();
9429 captureCommitPhaseError(current, error);
9430 }
9431 }
9432}
9433
9434function commitBeforeMutationLifeCycles(current, finishedWork) {
9435 switch (finishedWork.tag) {
9436 case FunctionComponent:
9437 case ForwardRef:
9438 case SimpleMemoComponent:
9439 {
9440 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
9441 return;
9442 }
9443 case ClassComponent:
9444 {
9445 if (finishedWork.effectTag & Snapshot) {
9446 if (current !== null) {
9447 var prevProps = current.memoizedProps;
9448 var prevState = current.memoizedState;
9449 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
9450 var instance = finishedWork.stateNode;
9451 // We could update instance props and state here,
9452 // but instead we rely on them being set during last render.
9453 // TODO: revisit this when we implement resuming.
9454 {
9455 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9456 !(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;
9457 !(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;
9458 }
9459 }
9460 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
9461 {
9462 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
9463 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
9464 didWarnSet.add(finishedWork.type);
9465 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
9466 }
9467 }
9468 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
9469 stopPhaseTimer();
9470 }
9471 }
9472 return;
9473 }
9474 case HostRoot:
9475 case HostComponent:
9476 case HostText:
9477 case HostPortal:
9478 case IncompleteClassComponent:
9479 // Nothing to do for these component types
9480 return;
9481 default:
9482 {
9483 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.');
9484 }
9485 }
9486}
9487
9488function commitHookEffectList(unmountTag, mountTag, finishedWork) {
9489 var updateQueue = finishedWork.updateQueue;
9490 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
9491 if (lastEffect !== null) {
9492 var firstEffect = lastEffect.next;
9493 var effect = firstEffect;
9494 do {
9495 if ((effect.tag & unmountTag) !== NoEffect$1) {
9496 // Unmount
9497 var destroy = effect.destroy;
9498 effect.destroy = undefined;
9499 if (destroy !== undefined) {
9500 destroy();
9501 }
9502 }
9503 if ((effect.tag & mountTag) !== NoEffect$1) {
9504 // Mount
9505 var create = effect.create;
9506 effect.destroy = create();
9507
9508 {
9509 var _destroy = effect.destroy;
9510 if (_destroy !== undefined && typeof _destroy !== 'function') {
9511 var addendum = void 0;
9512 if (_destroy === null) {
9513 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
9514 } else if (typeof _destroy.then === 'function') {
9515 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.";
9516 } else {
9517 addendum = ' You returned: ' + _destroy;
9518 }
9519 warningWithoutStack$1(false, 'An Effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
9520 }
9521 }
9522 }
9523 effect = effect.next;
9524 } while (effect !== firstEffect);
9525 }
9526}
9527
9528function commitPassiveHookEffects(finishedWork) {
9529 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
9530 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
9531}
9532
9533function commitLifeCycles(finishedRoot, current, finishedWork, committedExpirationTime) {
9534 switch (finishedWork.tag) {
9535 case FunctionComponent:
9536 case ForwardRef:
9537 case SimpleMemoComponent:
9538 {
9539 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
9540 break;
9541 }
9542 case ClassComponent:
9543 {
9544 var instance = finishedWork.stateNode;
9545 if (finishedWork.effectTag & Update) {
9546 if (current === null) {
9547 startPhaseTimer(finishedWork, 'componentDidMount');
9548 // We could update instance props and state here,
9549 // but instead we rely on them being set during last render.
9550 // TODO: revisit this when we implement resuming.
9551 {
9552 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9553 !(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;
9554 !(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;
9555 }
9556 }
9557 instance.componentDidMount();
9558 stopPhaseTimer();
9559 } else {
9560 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
9561 var prevState = current.memoizedState;
9562 startPhaseTimer(finishedWork, 'componentDidUpdate');
9563 // We could update instance props and state here,
9564 // but instead we rely on them being set during last render.
9565 // TODO: revisit this when we implement resuming.
9566 {
9567 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9568 !(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;
9569 !(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;
9570 }
9571 }
9572 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
9573 stopPhaseTimer();
9574 }
9575 }
9576 var updateQueue = finishedWork.updateQueue;
9577 if (updateQueue !== null) {
9578 {
9579 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
9580 !(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;
9581 !(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;
9582 }
9583 }
9584 // We could update instance props and state here,
9585 // but instead we rely on them being set during last render.
9586 // TODO: revisit this when we implement resuming.
9587 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
9588 }
9589 return;
9590 }
9591 case HostRoot:
9592 {
9593 var _updateQueue = finishedWork.updateQueue;
9594 if (_updateQueue !== null) {
9595 var _instance = null;
9596 if (finishedWork.child !== null) {
9597 switch (finishedWork.child.tag) {
9598 case HostComponent:
9599 _instance = getPublicInstance(finishedWork.child.stateNode);
9600 break;
9601 case ClassComponent:
9602 _instance = finishedWork.child.stateNode;
9603 break;
9604 }
9605 }
9606 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
9607 }
9608 return;
9609 }
9610 case HostComponent:
9611 {
9612 var _instance2 = finishedWork.stateNode;
9613
9614 // Renderers may schedule work to be done after host components are mounted
9615 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
9616 // These effects should only be committed when components are first mounted,
9617 // aka when there is no current/alternate.
9618 if (current === null && finishedWork.effectTag & Update) {
9619 var type = finishedWork.type;
9620 var props = finishedWork.memoizedProps;
9621
9622 }
9623
9624 return;
9625 }
9626 case HostText:
9627 {
9628 // We have no life-cycles associated with text.
9629 return;
9630 }
9631 case HostPortal:
9632 {
9633 // We have no life-cycles associated with portals.
9634 return;
9635 }
9636 case Profiler:
9637 {
9638 if (enableProfilerTimer) {
9639 var onRender = finishedWork.memoizedProps.onRender;
9640
9641 if (enableSchedulerTracing) {
9642 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
9643 } else {
9644 onRender(finishedWork.memoizedProps.id, current === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
9645 }
9646 }
9647 return;
9648 }
9649 case SuspenseComponent:
9650 break;
9651 case IncompleteClassComponent:
9652 break;
9653 default:
9654 {
9655 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.');
9656 }
9657 }
9658}
9659
9660function hideOrUnhideAllChildren(finishedWork, isHidden) {
9661 if (supportsMutation) {
9662 // We only have the top Fiber that was inserted but we need recurse down its
9663 var node = finishedWork;
9664 while (true) {
9665 if (node.tag === HostComponent) {
9666 var instance = node.stateNode;
9667 if (isHidden) {
9668 hideInstance(instance);
9669 } else {
9670 unhideInstance(node.stateNode, node.memoizedProps);
9671 }
9672 } else if (node.tag === HostText) {
9673 var _instance3 = node.stateNode;
9674 if (isHidden) {
9675
9676 } else {
9677 unhideTextInstance(_instance3, node.memoizedProps);
9678 }
9679 } else if (node.tag === SuspenseComponent && node.memoizedState !== null) {
9680 // Found a nested Suspense component that timed out. Skip over the
9681 var fallbackChildFragment = node.child.sibling;
9682 fallbackChildFragment.return = node;
9683 node = fallbackChildFragment;
9684 continue;
9685 } else if (node.child !== null) {
9686 node.child.return = node;
9687 node = node.child;
9688 continue;
9689 }
9690 if (node === finishedWork) {
9691 return;
9692 }
9693 while (node.sibling === null) {
9694 if (node.return === null || node.return === finishedWork) {
9695 return;
9696 }
9697 node = node.return;
9698 }
9699 node.sibling.return = node.return;
9700 node = node.sibling;
9701 }
9702 }
9703}
9704
9705function commitAttachRef(finishedWork) {
9706 var ref = finishedWork.ref;
9707 if (ref !== null) {
9708 var instance = finishedWork.stateNode;
9709 var instanceToUse = void 0;
9710 switch (finishedWork.tag) {
9711 case HostComponent:
9712 instanceToUse = getPublicInstance(instance);
9713 break;
9714 default:
9715 instanceToUse = instance;
9716 }
9717 if (typeof ref === 'function') {
9718 ref(instanceToUse);
9719 } else {
9720 {
9721 if (!ref.hasOwnProperty('current')) {
9722 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
9723 }
9724 }
9725
9726 ref.current = instanceToUse;
9727 }
9728 }
9729}
9730
9731function commitDetachRef(current) {
9732 var currentRef = current.ref;
9733 if (currentRef !== null) {
9734 if (typeof currentRef === 'function') {
9735 currentRef(null);
9736 } else {
9737 currentRef.current = null;
9738 }
9739 }
9740}
9741
9742// User-originating errors (lifecycles and refs) should not interrupt
9743// deletion, so don't let them throw. Host-originating errors should
9744// interrupt deletion, so it's okay
9745function commitUnmount(current) {
9746 onCommitUnmount(current);
9747
9748 switch (current.tag) {
9749 case FunctionComponent:
9750 case ForwardRef:
9751 case MemoComponent:
9752 case SimpleMemoComponent:
9753 {
9754 var updateQueue = current.updateQueue;
9755 if (updateQueue !== null) {
9756 var lastEffect = updateQueue.lastEffect;
9757 if (lastEffect !== null) {
9758 var firstEffect = lastEffect.next;
9759 var effect = firstEffect;
9760 do {
9761 var destroy = effect.destroy;
9762 if (destroy !== undefined) {
9763 safelyCallDestroy(current, destroy);
9764 }
9765 effect = effect.next;
9766 } while (effect !== firstEffect);
9767 }
9768 }
9769 break;
9770 }
9771 case ClassComponent:
9772 {
9773 safelyDetachRef(current);
9774 var instance = current.stateNode;
9775 if (typeof instance.componentWillUnmount === 'function') {
9776 safelyCallComponentWillUnmount(current, instance);
9777 }
9778 return;
9779 }
9780 case HostComponent:
9781 {
9782 safelyDetachRef(current);
9783 return;
9784 }
9785 case HostPortal:
9786 {
9787 // TODO: this is recursive.
9788 // We are also not using this parent because
9789 // the portal will get pushed immediately.
9790 if (supportsMutation) {
9791 unmountHostComponents(current);
9792 } else if (supportsPersistence) {
9793 emptyPortalContainer(current);
9794 }
9795 return;
9796 }
9797 }
9798}
9799
9800function commitNestedUnmounts(root) {
9801 // While we're inside a removed host node we don't want to call
9802 // removeChild on the inner nodes because they're removed by the top
9803 // call anyway. We also want to call componentWillUnmount on all
9804 // composites before this host node is removed from the tree. Therefore
9805 var node = root;
9806 while (true) {
9807 commitUnmount(node);
9808 // Visit children because they may contain more composite or host nodes.
9809 // Skip portals because commitUnmount() currently visits them recursively.
9810 if (node.child !== null && (
9811 // If we use mutation we drill down into portals using commitUnmount above.
9812 // If we don't use mutation we drill down into portals here instead.
9813 !supportsMutation || node.tag !== HostPortal)) {
9814 node.child.return = node;
9815 node = node.child;
9816 continue;
9817 }
9818 if (node === root) {
9819 return;
9820 }
9821 while (node.sibling === null) {
9822 if (node.return === null || node.return === root) {
9823 return;
9824 }
9825 node = node.return;
9826 }
9827 node.sibling.return = node.return;
9828 node = node.sibling;
9829 }
9830}
9831
9832function detachFiber(current) {
9833 // Cut off the return pointers to disconnect it from the tree. Ideally, we
9834 // should clear the child pointer of the parent alternate to let this
9835 // get GC:ed but we don't know which for sure which parent is the current
9836 // one so we'll settle for GC:ing the subtree of this child. This child
9837 // itself will be GC:ed when the parent updates the next time.
9838 current.return = null;
9839 current.child = null;
9840 current.memoizedState = null;
9841 current.updateQueue = null;
9842 var alternate = current.alternate;
9843 if (alternate !== null) {
9844 alternate.return = null;
9845 alternate.child = null;
9846 alternate.memoizedState = null;
9847 alternate.updateQueue = null;
9848 }
9849}
9850
9851function emptyPortalContainer(current) {
9852 if (!supportsPersistence) {
9853 return;
9854 }
9855
9856 var portal = current.stateNode;
9857 var containerInfo = portal.containerInfo;
9858
9859 var emptyChildSet = createContainerChildSet(containerInfo);
9860 replaceContainerChildren(containerInfo, emptyChildSet);
9861}
9862
9863function commitContainer(finishedWork) {
9864 if (!supportsPersistence) {
9865 return;
9866 }
9867
9868 switch (finishedWork.tag) {
9869 case ClassComponent:
9870 {
9871 return;
9872 }
9873 case HostComponent:
9874 {
9875 return;
9876 }
9877 case HostText:
9878 {
9879 return;
9880 }
9881 case HostRoot:
9882 case HostPortal:
9883 {
9884 var portalOrRoot = finishedWork.stateNode;
9885 var containerInfo = portalOrRoot.containerInfo,
9886 _pendingChildren = portalOrRoot.pendingChildren;
9887
9888 replaceContainerChildren(containerInfo, _pendingChildren);
9889 return;
9890 }
9891 default:
9892 {
9893 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.');
9894 }
9895 }
9896}
9897
9898function getHostParentFiber(fiber) {
9899 var parent = fiber.return;
9900 while (parent !== null) {
9901 if (isHostParent(parent)) {
9902 return parent;
9903 }
9904 parent = parent.return;
9905 }
9906 invariant(false, 'Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.');
9907}
9908
9909function isHostParent(fiber) {
9910 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
9911}
9912
9913function getHostSibling(fiber) {
9914 // We're going to search forward into the tree until we find a sibling host
9915 // node. Unfortunately, if multiple insertions are done in a row we have to
9916 // search past them. This leads to exponential search for the next sibling.
9917 var node = fiber;
9918 siblings: while (true) {
9919 // If we didn't find anything, let's try the next sibling.
9920 while (node.sibling === null) {
9921 if (node.return === null || isHostParent(node.return)) {
9922 // If we pop out of the root or hit the parent the fiber we are the
9923 // last sibling.
9924 return null;
9925 }
9926 node = node.return;
9927 }
9928 node.sibling.return = node.return;
9929 node = node.sibling;
9930 while (node.tag !== HostComponent && node.tag !== HostText) {
9931 // If it is not host node and, we might have a host node inside it.
9932 // Try to search down until we find one.
9933 if (node.effectTag & Placement) {
9934 // If we don't have a child, try the siblings instead.
9935 continue siblings;
9936 }
9937 // If we don't have a child, try the siblings instead.
9938 // We also skip portals because they are not part of this host tree.
9939 if (node.child === null || node.tag === HostPortal) {
9940 continue siblings;
9941 } else {
9942 node.child.return = node;
9943 node = node.child;
9944 }
9945 }
9946 // Check if this host node is stable or about to be placed.
9947 if (!(node.effectTag & Placement)) {
9948 // Found it!
9949 return node.stateNode;
9950 }
9951 }
9952}
9953
9954function commitPlacement(finishedWork) {
9955 if (!supportsMutation) {
9956 return;
9957 }
9958
9959 // Recursively insert all host nodes into the parent.
9960 var parentFiber = getHostParentFiber(finishedWork);
9961
9962 // Note: these two variables *must* always be updated together.
9963 var parent = void 0;
9964 var isContainer = void 0;
9965
9966 switch (parentFiber.tag) {
9967 case HostComponent:
9968 parent = parentFiber.stateNode;
9969 isContainer = false;
9970 break;
9971 case HostRoot:
9972 parent = parentFiber.stateNode.containerInfo;
9973 isContainer = true;
9974 break;
9975 case HostPortal:
9976 parent = parentFiber.stateNode.containerInfo;
9977 isContainer = true;
9978 break;
9979 default:
9980 invariant(false, 'Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.');
9981 }
9982 if (parentFiber.effectTag & ContentReset) {
9983 // Reset the text content of the parent before doing any insertions
9984 parentFiber.effectTag &= ~ContentReset;
9985 }
9986
9987 var before = getHostSibling(finishedWork);
9988 // We only have the top Fiber that was inserted but we need recurse down its
9989 // children to find all the terminal nodes.
9990 var node = finishedWork;
9991 while (true) {
9992 if (node.tag === HostComponent || node.tag === HostText) {
9993 if (before) {
9994 if (isContainer) {
9995 insertInContainerBefore(parent, node.stateNode, before);
9996 } else {
9997 insertBefore(parent, node.stateNode, before);
9998 }
9999 } else {
10000 if (isContainer) {
10001 appendChildToContainer(parent, node.stateNode);
10002 } else {
10003 appendChild(parent, node.stateNode);
10004 }
10005 }
10006 } else if (node.tag === HostPortal) {
10007 // If the insertion itself is a portal, then we don't want to traverse
10008 // down its children. Instead, we'll get insertions from each child in
10009 // the portal directly.
10010 } else if (node.child !== null) {
10011 node.child.return = node;
10012 node = node.child;
10013 continue;
10014 }
10015 if (node === finishedWork) {
10016 return;
10017 }
10018 while (node.sibling === null) {
10019 if (node.return === null || node.return === finishedWork) {
10020 return;
10021 }
10022 node = node.return;
10023 }
10024 node.sibling.return = node.return;
10025 node = node.sibling;
10026 }
10027}
10028
10029function unmountHostComponents(current) {
10030 // We only have the top Fiber that was deleted but we need recurse down its
10031 var node = current;
10032
10033 // Each iteration, currentParent is populated with node's host parent if not
10034 // currentParentIsValid.
10035 var currentParentIsValid = false;
10036
10037 // Note: these two variables *must* always be updated together.
10038 var currentParent = void 0;
10039 var currentParentIsContainer = void 0;
10040
10041 while (true) {
10042 if (!currentParentIsValid) {
10043 var parent = node.return;
10044 findParent: while (true) {
10045 !(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;
10046 switch (parent.tag) {
10047 case HostComponent:
10048 currentParent = parent.stateNode;
10049 currentParentIsContainer = false;
10050 break findParent;
10051 case HostRoot:
10052 currentParent = parent.stateNode.containerInfo;
10053 currentParentIsContainer = true;
10054 break findParent;
10055 case HostPortal:
10056 currentParent = parent.stateNode.containerInfo;
10057 currentParentIsContainer = true;
10058 break findParent;
10059 }
10060 parent = parent.return;
10061 }
10062 currentParentIsValid = true;
10063 }
10064
10065 if (node.tag === HostComponent || node.tag === HostText) {
10066 commitNestedUnmounts(node);
10067 // After all the children have unmounted, it is now safe to remove the
10068 // node from the tree.
10069 if (currentParentIsContainer) {
10070 removeChildFromContainer(currentParent, node.stateNode);
10071 } else {
10072 removeChild(currentParent, node.stateNode);
10073 }
10074 // Don't visit children because we already visited them.
10075 } else if (node.tag === HostPortal) {
10076 // When we go into a portal, it becomes the parent to remove from.
10077 // We will reassign it back when we pop the portal on the way up.
10078 currentParent = node.stateNode.containerInfo;
10079 currentParentIsContainer = true;
10080 // Visit children because portals might contain host components.
10081 if (node.child !== null) {
10082 node.child.return = node;
10083 node = node.child;
10084 continue;
10085 }
10086 } else {
10087 commitUnmount(node);
10088 // Visit children because we may find more host components below.
10089 if (node.child !== null) {
10090 node.child.return = node;
10091 node = node.child;
10092 continue;
10093 }
10094 }
10095 if (node === current) {
10096 return;
10097 }
10098 while (node.sibling === null) {
10099 if (node.return === null || node.return === current) {
10100 return;
10101 }
10102 node = node.return;
10103 if (node.tag === HostPortal) {
10104 // When we go out of the portal, we need to restore the parent.
10105 // Since we don't keep a stack of them, we will search for it.
10106 currentParentIsValid = false;
10107 }
10108 }
10109 node.sibling.return = node.return;
10110 node = node.sibling;
10111 }
10112}
10113
10114function commitDeletion(current) {
10115 if (supportsMutation) {
10116 // Recursively delete all host nodes from the parent.
10117 // Detach refs and call componentWillUnmount() on the whole subtree.
10118 unmountHostComponents(current);
10119 } else {
10120 // Detach refs and call componentWillUnmount() on the whole subtree.
10121 commitNestedUnmounts(current);
10122 }
10123 detachFiber(current);
10124}
10125
10126function commitWork(current, finishedWork) {
10127 if (!supportsMutation) {
10128 switch (finishedWork.tag) {
10129 case FunctionComponent:
10130 case ForwardRef:
10131 case MemoComponent:
10132 case SimpleMemoComponent:
10133 {
10134 // Note: We currently never use MountMutation, but useLayout uses
10135 // UnmountMutation.
10136 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10137 return;
10138 }
10139 }
10140
10141 commitContainer(finishedWork);
10142 return;
10143 }
10144
10145 switch (finishedWork.tag) {
10146 case FunctionComponent:
10147 case ForwardRef:
10148 case MemoComponent:
10149 case SimpleMemoComponent:
10150 {
10151 // Note: We currently never use MountMutation, but useLayout uses
10152 // UnmountMutation.
10153 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
10154 return;
10155 }
10156 case ClassComponent:
10157 {
10158 return;
10159 }
10160 case HostComponent:
10161 {
10162 var instance = finishedWork.stateNode;
10163 if (instance != null) {
10164 // Commit the work prepared earlier.
10165 var newProps = finishedWork.memoizedProps;
10166 // For hydration we reuse the update path but we treat the oldProps
10167 // as the newProps. The updatePayload will contain the real change in
10168 // this case.
10169 var oldProps = current !== null ? current.memoizedProps : newProps;
10170 var type = finishedWork.type;
10171 // TODO: Type the updateQueue to be specific to host components.
10172 var updatePayload = finishedWork.updateQueue;
10173 finishedWork.updateQueue = null;
10174 if (updatePayload !== null) {
10175 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
10176 }
10177 }
10178 return;
10179 }
10180 case HostText:
10181 {
10182 !(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;
10183 var textInstance = finishedWork.stateNode;
10184 var newText = finishedWork.memoizedProps;
10185 // For hydration we reuse the update path but we treat the oldProps
10186 // as the newProps. The updatePayload will contain the real change in
10187 // this case.
10188 var oldText = current !== null ? current.memoizedProps : newText;
10189 return;
10190 }
10191 case HostRoot:
10192 {
10193 return;
10194 }
10195 case Profiler:
10196 {
10197 return;
10198 }
10199 case SuspenseComponent:
10200 {
10201 var newState = finishedWork.memoizedState;
10202
10203 var newDidTimeout = void 0;
10204 var primaryChildParent = finishedWork;
10205 if (newState === null) {
10206 newDidTimeout = false;
10207 } else {
10208 newDidTimeout = true;
10209 primaryChildParent = finishedWork.child;
10210 if (newState.timedOutAt === NoWork) {
10211 // If the children had not already timed out, record the time.
10212 // This is used to compute the elapsed time during subsequent
10213 // attempts to render the children.
10214 newState.timedOutAt = requestCurrentTime();
10215 }
10216 }
10217
10218 if (primaryChildParent !== null) {
10219 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
10220 }
10221
10222 // If this boundary just timed out, then it will have a set of thenables.
10223 // For each thenable, attach a listener so that when it resolves, React
10224 // attempts to re-render the boundary in the primary (pre-timeout) state.
10225 var thenables = finishedWork.updateQueue;
10226 if (thenables !== null) {
10227 finishedWork.updateQueue = null;
10228 var retryCache = finishedWork.stateNode;
10229 if (retryCache === null) {
10230 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
10231 }
10232 thenables.forEach(function (thenable) {
10233 // Memoize using the boundary fiber to prevent redundant listeners.
10234 var retry = retryTimedOutBoundary.bind(null, finishedWork, thenable);
10235 if (enableSchedulerTracing) {
10236 retry = unstable_wrap(retry);
10237 }
10238 if (!retryCache.has(thenable)) {
10239 retryCache.add(thenable);
10240 thenable.then(retry, retry);
10241 }
10242 });
10243 }
10244
10245 return;
10246 }
10247 case IncompleteClassComponent:
10248 {
10249 return;
10250 }
10251 default:
10252 {
10253 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.');
10254 }
10255 }
10256}
10257
10258function commitResetTextContent(current) {
10259 if (!supportsMutation) {
10260 return;
10261 }
10262 resetTextContent(current.stateNode);
10263}
10264
10265var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
10266
10267function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
10268 var update = createUpdate(expirationTime);
10269 // Unmount the root by rendering null.
10270 update.tag = CaptureUpdate;
10271 // Caution: React DevTools currently depends on this property
10272 // being called "element".
10273 update.payload = { element: null };
10274 var error = errorInfo.value;
10275 update.callback = function () {
10276 onUncaughtError(error);
10277 logError(fiber, errorInfo);
10278 };
10279 return update;
10280}
10281
10282function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
10283 var update = createUpdate(expirationTime);
10284 update.tag = CaptureUpdate;
10285 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
10286 if (typeof getDerivedStateFromError === 'function') {
10287 var error = errorInfo.value;
10288 update.payload = function () {
10289 return getDerivedStateFromError(error);
10290 };
10291 }
10292
10293 var inst = fiber.stateNode;
10294 if (inst !== null && typeof inst.componentDidCatch === 'function') {
10295 update.callback = function callback() {
10296 if (typeof getDerivedStateFromError !== 'function') {
10297 // To preserve the preexisting retry behavior of error boundaries,
10298 // we keep track of which ones already failed during this batch.
10299 // This gets reset before we yield back to the browser.
10300 // TODO: Warn in strict mode if getDerivedStateFromError is
10301 // not defined.
10302 markLegacyErrorBoundaryAsFailed(this);
10303 }
10304 var error = errorInfo.value;
10305 var stack = errorInfo.stack;
10306 logError(fiber, errorInfo);
10307 this.componentDidCatch(error, {
10308 componentStack: stack !== null ? stack : ''
10309 });
10310 {
10311 if (typeof getDerivedStateFromError !== 'function') {
10312 // If componentDidCatch is the only error boundary method defined,
10313 // then it needs to call setState to recover from errors.
10314 // If no state update is scheduled then the boundary will swallow the error.
10315 !(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;
10316 }
10317 }
10318 };
10319 }
10320 return update;
10321}
10322
10323function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
10324 // The source fiber did not complete.
10325 sourceFiber.effectTag |= Incomplete;
10326 // Its effect list is no longer valid.
10327 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
10328
10329 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
10330 // This is a thenable.
10331 var thenable = value;
10332
10333 // Find the earliest timeout threshold of all the placeholders in the
10334 // ancestor path. We could avoid this traversal by storing the thresholds on
10335 // the stack, but we choose not to because we only hit this path if we're
10336 // IO-bound (i.e. if something suspends). Whereas the stack is used even in
10337 // the non-IO- bound case.
10338 var _workInProgress = returnFiber;
10339 var earliestTimeoutMs = -1;
10340 var startTimeMs = -1;
10341 do {
10342 if (_workInProgress.tag === SuspenseComponent) {
10343 var current = _workInProgress.alternate;
10344 if (current !== null) {
10345 var currentState = current.memoizedState;
10346 if (currentState !== null) {
10347 // Reached a boundary that already timed out. Do not search
10348 // any further.
10349 var timedOutAt = currentState.timedOutAt;
10350 startTimeMs = expirationTimeToMs(timedOutAt);
10351 // Do not search any further.
10352 break;
10353 }
10354 }
10355 var timeoutPropMs = _workInProgress.pendingProps.maxDuration;
10356 if (typeof timeoutPropMs === 'number') {
10357 if (timeoutPropMs <= 0) {
10358 earliestTimeoutMs = 0;
10359 } else if (earliestTimeoutMs === -1 || timeoutPropMs < earliestTimeoutMs) {
10360 earliestTimeoutMs = timeoutPropMs;
10361 }
10362 }
10363 }
10364 _workInProgress = _workInProgress.return;
10365 } while (_workInProgress !== null);
10366
10367 // Schedule the nearest Suspense to re-render the timed out view.
10368 _workInProgress = returnFiber;
10369 do {
10370 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress)) {
10371 // Found the nearest boundary.
10372
10373 // Stash the promise on the boundary fiber. If the boundary times out, we'll
10374 var thenables = _workInProgress.updateQueue;
10375 if (thenables === null) {
10376 var updateQueue = new Set();
10377 updateQueue.add(thenable);
10378 _workInProgress.updateQueue = updateQueue;
10379 } else {
10380 thenables.add(thenable);
10381 }
10382
10383 // If the boundary is outside of concurrent mode, we should *not*
10384 // suspend the commit. Pretend as if the suspended component rendered
10385 // null and keep rendering. In the commit phase, we'll schedule a
10386 // subsequent synchronous update to re-render the Suspense.
10387 //
10388 // Note: It doesn't matter whether the component that suspended was
10389 // inside a concurrent mode tree. If the Suspense is outside of it, we
10390 // should *not* suspend the commit.
10391 if ((_workInProgress.mode & ConcurrentMode) === NoEffect) {
10392 _workInProgress.effectTag |= DidCapture;
10393
10394 // We're going to commit this fiber even though it didn't complete.
10395 // But we shouldn't call any lifecycle methods or callbacks. Remove
10396 // all lifecycle effect tags.
10397 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
10398
10399 if (sourceFiber.tag === ClassComponent) {
10400 var currentSourceFiber = sourceFiber.alternate;
10401 if (currentSourceFiber === null) {
10402 // This is a new mount. Change the tag so it's not mistaken for a
10403 // completed class component. For example, we should not call
10404 // componentWillUnmount if it is deleted.
10405 sourceFiber.tag = IncompleteClassComponent;
10406 } else {
10407 // When we try rendering again, we should not reuse the current fiber,
10408 // since it's known to be in an inconsistent state. Use a force updte to
10409 // prevent a bail out.
10410 var update = createUpdate(Sync);
10411 update.tag = ForceUpdate;
10412 enqueueUpdate(sourceFiber, update);
10413 }
10414 }
10415
10416 // The source fiber did not complete. Mark it with Sync priority to
10417 // indicate that it still has pending work.
10418 sourceFiber.expirationTime = Sync;
10419
10420 // Exit without suspending.
10421 return;
10422 }
10423
10424 // Confirmed that the boundary is in a concurrent mode tree. Continue
10425 // with the normal suspend path.
10426
10427 // Attach a listener to the promise to "ping" the root and retry. But
10428 // only if one does not already exist for the current render expiration
10429 // time (which acts like a "thread ID" here).
10430 var pingCache = root.pingCache;
10431 var threadIDs = void 0;
10432 if (pingCache === null) {
10433 pingCache = root.pingCache = new PossiblyWeakMap();
10434 threadIDs = new Set();
10435 pingCache.set(thenable, threadIDs);
10436 } else {
10437 threadIDs = pingCache.get(thenable);
10438 if (threadIDs === undefined) {
10439 threadIDs = new Set();
10440 pingCache.set(thenable, threadIDs);
10441 }
10442 }
10443 if (!threadIDs.has(renderExpirationTime)) {
10444 // Memoize using the thread ID to prevent redundant listeners.
10445 threadIDs.add(renderExpirationTime);
10446 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
10447 if (enableSchedulerTracing) {
10448 ping = unstable_wrap(ping);
10449 }
10450 thenable.then(ping, ping);
10451 }
10452
10453 var absoluteTimeoutMs = void 0;
10454 if (earliestTimeoutMs === -1) {
10455 // If no explicit threshold is given, default to an arbitrarily large
10456 // value. The actual size doesn't matter because the threshold for the
10457 // whole tree will be clamped to the expiration time.
10458 absoluteTimeoutMs = maxSigned31BitInt;
10459 } else {
10460 if (startTimeMs === -1) {
10461 // This suspend happened outside of any already timed-out
10462 // placeholders. We don't know exactly when the update was
10463 // scheduled, but we can infer an approximate start time from the
10464 // expiration time. First, find the earliest uncommitted expiration
10465 // time in the tree, including work that is suspended. Then subtract
10466 // the offset used to compute an async update's expiration time.
10467 // This will cause high priority (interactive) work to expire
10468 // earlier than necessary, but we can account for this by adjusting
10469 // for the Just Noticeable Difference.
10470 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, renderExpirationTime);
10471 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
10472 startTimeMs = earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
10473 }
10474 absoluteTimeoutMs = startTimeMs + earliestTimeoutMs;
10475 }
10476
10477 // Mark the earliest timeout in the suspended fiber's ancestor path.
10478 // After completing the root, we'll take the largest of all the
10479 // suspended fiber's timeouts and use it to compute a timeout for the
10480 // whole tree.
10481 renderDidSuspend(root, absoluteTimeoutMs, renderExpirationTime);
10482
10483 _workInProgress.effectTag |= ShouldCapture;
10484 _workInProgress.expirationTime = renderExpirationTime;
10485 return;
10486 }
10487 // This boundary already captured during this render. Continue to the next
10488 // boundary.
10489 _workInProgress = _workInProgress.return;
10490 } while (_workInProgress !== null);
10491 // No boundary was found. Fallthrough to error mode.
10492 // TODO: Use invariant so the message is stripped in prod?
10493 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));
10494 }
10495
10496 // We didn't find a boundary that could handle this type of exception. Start
10497 // over and traverse parent path again, this time treating the exception
10498 // as an error.
10499 renderDidError();
10500 value = createCapturedValue(value, sourceFiber);
10501 var workInProgress = returnFiber;
10502 do {
10503 switch (workInProgress.tag) {
10504 case HostRoot:
10505 {
10506 var _errorInfo = value;
10507 workInProgress.effectTag |= ShouldCapture;
10508 workInProgress.expirationTime = renderExpirationTime;
10509 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
10510 enqueueCapturedUpdate(workInProgress, _update);
10511 return;
10512 }
10513 case ClassComponent:
10514 // Capture and retry
10515 var errorInfo = value;
10516 var ctor = workInProgress.type;
10517 var instance = workInProgress.stateNode;
10518 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
10519 workInProgress.effectTag |= ShouldCapture;
10520 workInProgress.expirationTime = renderExpirationTime;
10521 // Schedule the error boundary to re-render using updated state
10522 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
10523 enqueueCapturedUpdate(workInProgress, _update2);
10524 return;
10525 }
10526 break;
10527 default:
10528 break;
10529 }
10530 workInProgress = workInProgress.return;
10531 } while (workInProgress !== null);
10532}
10533
10534function unwindWork(workInProgress, renderExpirationTime) {
10535 switch (workInProgress.tag) {
10536 case ClassComponent:
10537 {
10538 var Component = workInProgress.type;
10539 if (isContextProvider(Component)) {
10540 popContext(workInProgress);
10541 }
10542 var effectTag = workInProgress.effectTag;
10543 if (effectTag & ShouldCapture) {
10544 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
10545 return workInProgress;
10546 }
10547 return null;
10548 }
10549 case HostRoot:
10550 {
10551 popHostContainer(workInProgress);
10552 popTopLevelContextObject(workInProgress);
10553 var _effectTag = workInProgress.effectTag;
10554 !((_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;
10555 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
10556 return workInProgress;
10557 }
10558 case HostComponent:
10559 {
10560 popHostContext(workInProgress);
10561 return null;
10562 }
10563 case SuspenseComponent:
10564 {
10565 var _effectTag2 = workInProgress.effectTag;
10566 if (_effectTag2 & ShouldCapture) {
10567 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture;
10568 // Captured a suspense effect. Re-render the boundary.
10569 return workInProgress;
10570 }
10571 return null;
10572 }
10573 case HostPortal:
10574 popHostContainer(workInProgress);
10575 return null;
10576 case ContextProvider:
10577 popProvider(workInProgress);
10578 return null;
10579 default:
10580 return null;
10581 }
10582}
10583
10584function unwindInterruptedWork(interruptedWork) {
10585 switch (interruptedWork.tag) {
10586 case ClassComponent:
10587 {
10588 var childContextTypes = interruptedWork.type.childContextTypes;
10589 if (childContextTypes !== null && childContextTypes !== undefined) {
10590 popContext(interruptedWork);
10591 }
10592 break;
10593 }
10594 case HostRoot:
10595 {
10596 popHostContainer(interruptedWork);
10597 popTopLevelContextObject(interruptedWork);
10598 break;
10599 }
10600 case HostComponent:
10601 {
10602 popHostContext(interruptedWork);
10603 break;
10604 }
10605 case HostPortal:
10606 popHostContainer(interruptedWork);
10607 break;
10608 case ContextProvider:
10609 popProvider(interruptedWork);
10610 break;
10611 default:
10612 break;
10613 }
10614}
10615
10616var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
10617var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
10618
10619
10620var didWarnAboutStateTransition = void 0;
10621var didWarnSetStateChildContext = void 0;
10622var warnAboutUpdateOnUnmounted = void 0;
10623var warnAboutInvalidUpdates = void 0;
10624
10625if (enableSchedulerTracing) {
10626 // Provide explicit error message when production+profiling bundle of e.g. react-dom
10627 // is used with production (non-profiling) bundle of scheduler/tracing
10628 !(__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;
10629}
10630
10631{
10632 didWarnAboutStateTransition = false;
10633 didWarnSetStateChildContext = false;
10634 var didWarnStateUpdateForUnmountedComponent = {};
10635
10636 warnAboutUpdateOnUnmounted = function (fiber, isClass) {
10637 // We show the whole stack but dedupe on the top component's name because
10638 // the problematic code almost always lies inside that component.
10639 var componentName = getComponentName(fiber.type) || 'ReactComponent';
10640 if (didWarnStateUpdateForUnmountedComponent[componentName]) {
10641 return;
10642 }
10643 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));
10644 didWarnStateUpdateForUnmountedComponent[componentName] = true;
10645 };
10646
10647 warnAboutInvalidUpdates = function (instance) {
10648 switch (phase) {
10649 case 'getChildContext':
10650 if (didWarnSetStateChildContext) {
10651 return;
10652 }
10653 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
10654 didWarnSetStateChildContext = true;
10655 break;
10656 case 'render':
10657 if (didWarnAboutStateTransition) {
10658 return;
10659 }
10660 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.');
10661 didWarnAboutStateTransition = true;
10662 break;
10663 }
10664 };
10665}
10666
10667// Represents the expiration time that incoming updates should use. (If this
10668// is NoWork, use the default strategy: async updates in async mode, sync
10669// updates in sync mode.)
10670var expirationContext = NoWork;
10671
10672var isWorking = false;
10673
10674// The next work in progress fiber that we're currently working on.
10675var nextUnitOfWork = null;
10676var nextRoot = null;
10677// The time at which we're currently rendering work.
10678var nextRenderExpirationTime = NoWork;
10679var nextLatestAbsoluteTimeoutMs = -1;
10680var nextRenderDidError = false;
10681
10682// The next fiber with an effect that we're currently committing.
10683var nextEffect = null;
10684
10685var isCommitting$1 = false;
10686var rootWithPendingPassiveEffects = null;
10687var passiveEffectCallbackHandle = null;
10688var passiveEffectCallback = null;
10689
10690var legacyErrorBoundariesThatAlreadyFailed = null;
10691
10692// Used for performance tracking.
10693var interruptedBy = null;
10694
10695var stashedWorkInProgressProperties = void 0;
10696var replayUnitOfWork = void 0;
10697var mayReplayFailedUnitOfWork = void 0;
10698var isReplayingFailedUnitOfWork = void 0;
10699var originalReplayError = void 0;
10700var rethrowOriginalError = void 0;
10701if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
10702 stashedWorkInProgressProperties = null;
10703 mayReplayFailedUnitOfWork = true;
10704 isReplayingFailedUnitOfWork = false;
10705 originalReplayError = null;
10706 replayUnitOfWork = function (failedUnitOfWork, thrownValue, isYieldy) {
10707 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
10708 // Don't replay promises. Treat everything else like an error.
10709 // TODO: Need to figure out a different strategy if/when we add
10710 // support for catching other types.
10711 return;
10712 }
10713
10714 // Restore the original state of the work-in-progress
10715 if (stashedWorkInProgressProperties === null) {
10716 // This should never happen. Don't throw because this code is DEV-only.
10717 warningWithoutStack$1(false, 'Could not replay rendering after an error. This is likely a bug in React. ' + 'Please file an issue.');
10718 return;
10719 }
10720 assignFiberPropertiesInDEV(failedUnitOfWork, stashedWorkInProgressProperties);
10721
10722 switch (failedUnitOfWork.tag) {
10723 case HostRoot:
10724 popHostContainer(failedUnitOfWork);
10725 popTopLevelContextObject(failedUnitOfWork);
10726 break;
10727 case HostComponent:
10728 popHostContext(failedUnitOfWork);
10729 break;
10730 case ClassComponent:
10731 {
10732 var Component = failedUnitOfWork.type;
10733 if (isContextProvider(Component)) {
10734 popContext(failedUnitOfWork);
10735 }
10736 break;
10737 }
10738 case HostPortal:
10739 popHostContainer(failedUnitOfWork);
10740 break;
10741 case ContextProvider:
10742 popProvider(failedUnitOfWork);
10743 break;
10744 }
10745 // Replay the begin phase.
10746 isReplayingFailedUnitOfWork = true;
10747 originalReplayError = thrownValue;
10748 invokeGuardedCallback(null, workLoop, null, isYieldy);
10749 isReplayingFailedUnitOfWork = false;
10750 originalReplayError = null;
10751 if (hasCaughtError()) {
10752 var replayError = clearCaughtError();
10753 if (replayError != null && thrownValue != null) {
10754 try {
10755 // Reading the expando property is intentionally
10756 // inside `try` because it might be a getter or Proxy.
10757 if (replayError._suppressLogging) {
10758 // Also suppress logging for the original error.
10759 thrownValue._suppressLogging = true;
10760 }
10761 } catch (inner) {
10762 // Ignore.
10763 }
10764 }
10765 } else {
10766 // If the begin phase did not fail the second time, set this pointer
10767 // back to the original value.
10768 nextUnitOfWork = failedUnitOfWork;
10769 }
10770 };
10771 rethrowOriginalError = function () {
10772 throw originalReplayError;
10773 };
10774}
10775
10776function resetStack() {
10777 if (nextUnitOfWork !== null) {
10778 var interruptedWork = nextUnitOfWork.return;
10779 while (interruptedWork !== null) {
10780 unwindInterruptedWork(interruptedWork);
10781 interruptedWork = interruptedWork.return;
10782 }
10783 }
10784
10785 {
10786 ReactStrictModeWarnings.discardPendingWarnings();
10787 checkThatStackIsEmpty();
10788 }
10789
10790 nextRoot = null;
10791 nextRenderExpirationTime = NoWork;
10792 nextLatestAbsoluteTimeoutMs = -1;
10793 nextRenderDidError = false;
10794 nextUnitOfWork = null;
10795}
10796
10797function commitAllHostEffects() {
10798 while (nextEffect !== null) {
10799 {
10800 setCurrentFiber(nextEffect);
10801 }
10802 recordEffect();
10803
10804 var effectTag = nextEffect.effectTag;
10805
10806 if (effectTag & ContentReset) {
10807 commitResetTextContent(nextEffect);
10808 }
10809
10810 if (effectTag & Ref) {
10811 var current = nextEffect.alternate;
10812 if (current !== null) {
10813 commitDetachRef(current);
10814 }
10815 }
10816
10817 // The following switch statement is only concerned about placement,
10818 // updates, and deletions. To avoid needing to add a case for every
10819 // possible bitmap value, we remove the secondary effects from the
10820 // effect tag and switch on that value.
10821 var primaryEffectTag = effectTag & (Placement | Update | Deletion);
10822 switch (primaryEffectTag) {
10823 case Placement:
10824 {
10825 commitPlacement(nextEffect);
10826 // Clear the "placement" from effect tag so that we know that this is inserted, before
10827 // any life-cycles like componentDidMount gets called.
10828 // TODO: findDOMNode doesn't rely on this any more but isMounted
10829 // does and isMounted is deprecated anyway so we should be able
10830 // to kill this.
10831 nextEffect.effectTag &= ~Placement;
10832 break;
10833 }
10834 case PlacementAndUpdate:
10835 {
10836 // Placement
10837 commitPlacement(nextEffect);
10838 // Clear the "placement" from effect tag so that we know that this is inserted, before
10839 // any life-cycles like componentDidMount gets called.
10840 nextEffect.effectTag &= ~Placement;
10841
10842 // Update
10843 var _current = nextEffect.alternate;
10844 commitWork(_current, nextEffect);
10845 break;
10846 }
10847 case Update:
10848 {
10849 var _current2 = nextEffect.alternate;
10850 commitWork(_current2, nextEffect);
10851 break;
10852 }
10853 case Deletion:
10854 {
10855 commitDeletion(nextEffect);
10856 break;
10857 }
10858 }
10859 nextEffect = nextEffect.nextEffect;
10860 }
10861
10862 {
10863 resetCurrentFiber();
10864 }
10865}
10866
10867function commitBeforeMutationLifecycles() {
10868 while (nextEffect !== null) {
10869 {
10870 setCurrentFiber(nextEffect);
10871 }
10872
10873 var effectTag = nextEffect.effectTag;
10874 if (effectTag & Snapshot) {
10875 recordEffect();
10876 var current = nextEffect.alternate;
10877 commitBeforeMutationLifeCycles(current, nextEffect);
10878 }
10879
10880 nextEffect = nextEffect.nextEffect;
10881 }
10882
10883 {
10884 resetCurrentFiber();
10885 }
10886}
10887
10888function commitAllLifeCycles(finishedRoot, committedExpirationTime) {
10889 {
10890 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
10891 ReactStrictModeWarnings.flushLegacyContextWarning();
10892
10893 if (warnAboutDeprecatedLifecycles) {
10894 ReactStrictModeWarnings.flushPendingDeprecationWarnings();
10895 }
10896 }
10897 while (nextEffect !== null) {
10898 {
10899 setCurrentFiber(nextEffect);
10900 }
10901 var effectTag = nextEffect.effectTag;
10902
10903 if (effectTag & (Update | Callback)) {
10904 recordEffect();
10905 var current = nextEffect.alternate;
10906 commitLifeCycles(finishedRoot, current, nextEffect, committedExpirationTime);
10907 }
10908
10909 if (effectTag & Ref) {
10910 recordEffect();
10911 commitAttachRef(nextEffect);
10912 }
10913
10914 if (effectTag & Passive) {
10915 rootWithPendingPassiveEffects = finishedRoot;
10916 }
10917
10918 nextEffect = nextEffect.nextEffect;
10919 }
10920 {
10921 resetCurrentFiber();
10922 }
10923}
10924
10925function commitPassiveEffects(root, firstEffect) {
10926 rootWithPendingPassiveEffects = null;
10927 passiveEffectCallbackHandle = null;
10928 passiveEffectCallback = null;
10929
10930 // Set this to true to prevent re-entrancy
10931 var previousIsRendering = isRendering;
10932 isRendering = true;
10933
10934 var effect = firstEffect;
10935 do {
10936 {
10937 setCurrentFiber(effect);
10938 }
10939
10940 if (effect.effectTag & Passive) {
10941 var didError = false;
10942 var error = void 0;
10943 {
10944 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
10945 if (hasCaughtError()) {
10946 didError = true;
10947 error = clearCaughtError();
10948 }
10949 }
10950 if (didError) {
10951 captureCommitPhaseError(effect, error);
10952 }
10953 }
10954 effect = effect.nextEffect;
10955 } while (effect !== null);
10956 {
10957 resetCurrentFiber();
10958 }
10959
10960 isRendering = previousIsRendering;
10961
10962 // Check if work was scheduled by one of the effects
10963 var rootExpirationTime = root.expirationTime;
10964 if (rootExpirationTime !== NoWork) {
10965 requestWork(root, rootExpirationTime);
10966 }
10967}
10968
10969function isAlreadyFailedLegacyErrorBoundary(instance) {
10970 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
10971}
10972
10973function markLegacyErrorBoundaryAsFailed(instance) {
10974 if (legacyErrorBoundariesThatAlreadyFailed === null) {
10975 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
10976 } else {
10977 legacyErrorBoundariesThatAlreadyFailed.add(instance);
10978 }
10979}
10980
10981function flushPassiveEffects() {
10982 if (passiveEffectCallbackHandle !== null) {
10983 cancelPassiveEffects(passiveEffectCallbackHandle);
10984 }
10985 if (passiveEffectCallback !== null) {
10986 // We call the scheduled callback instead of commitPassiveEffects directly
10987 // to ensure tracing works correctly.
10988 passiveEffectCallback();
10989 }
10990}
10991
10992function commitRoot(root, finishedWork) {
10993 isWorking = true;
10994 isCommitting$1 = true;
10995 startCommitTimer();
10996
10997 !(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;
10998 var committedExpirationTime = root.pendingCommitExpirationTime;
10999 !(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;
11000 root.pendingCommitExpirationTime = NoWork;
11001
11002 // Update the pending priority levels to account for the work that we are
11003 // about to commit. This needs to happen before calling the lifecycles, since
11004 // they may schedule additional updates.
11005 var updateExpirationTimeBeforeCommit = finishedWork.expirationTime;
11006 var childExpirationTimeBeforeCommit = finishedWork.childExpirationTime;
11007 var earliestRemainingTimeBeforeCommit = childExpirationTimeBeforeCommit > updateExpirationTimeBeforeCommit ? childExpirationTimeBeforeCommit : updateExpirationTimeBeforeCommit;
11008 markCommittedPriorityLevels(root, earliestRemainingTimeBeforeCommit);
11009
11010 var prevInteractions = null;
11011 if (enableSchedulerTracing) {
11012 // Restore any pending interactions at this point,
11013 // So that cascading work triggered during the render phase will be accounted for.
11014 prevInteractions = __interactionsRef.current;
11015 __interactionsRef.current = root.memoizedInteractions;
11016 }
11017
11018 // Reset this to null before calling lifecycles
11019 ReactCurrentOwner$1.current = null;
11020
11021 var firstEffect = void 0;
11022 if (finishedWork.effectTag > PerformedWork) {
11023 // A fiber's effect list consists only of its children, not itself. So if
11024 // the root has an effect, we need to add it to the end of the list. The
11025 // resulting list is the set that would belong to the root's parent, if
11026 // it had one; that is, all the effects in the tree including the root.
11027 if (finishedWork.lastEffect !== null) {
11028 finishedWork.lastEffect.nextEffect = finishedWork;
11029 firstEffect = finishedWork.firstEffect;
11030 } else {
11031 firstEffect = finishedWork;
11032 }
11033 } else {
11034 // There is no effect on the root.
11035 firstEffect = finishedWork.firstEffect;
11036 }
11037
11038 prepareForCommit(root.containerInfo);
11039
11040 // Invoke instances of getSnapshotBeforeUpdate before mutation.
11041 nextEffect = firstEffect;
11042 startCommitSnapshotEffectsTimer();
11043 while (nextEffect !== null) {
11044 var didError = false;
11045 var error = void 0;
11046 {
11047 invokeGuardedCallback(null, commitBeforeMutationLifecycles, null);
11048 if (hasCaughtError()) {
11049 didError = true;
11050 error = clearCaughtError();
11051 }
11052 }
11053 if (didError) {
11054 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11055 captureCommitPhaseError(nextEffect, error);
11056 // Clean-up
11057 if (nextEffect !== null) {
11058 nextEffect = nextEffect.nextEffect;
11059 }
11060 }
11061 }
11062 stopCommitSnapshotEffectsTimer();
11063
11064 if (enableProfilerTimer) {
11065 // Mark the current commit time to be shared by all Profilers in this batch.
11066 // This enables them to be grouped later.
11067 recordCommitTime();
11068 }
11069
11070 // Commit all the side-effects within a tree. We'll do this in two passes.
11071 // The first pass performs all the host insertions, updates, deletions and
11072 // ref unmounts.
11073 nextEffect = firstEffect;
11074 startCommitHostEffectsTimer();
11075 while (nextEffect !== null) {
11076 var _didError = false;
11077 var _error = void 0;
11078 {
11079 invokeGuardedCallback(null, commitAllHostEffects, null);
11080 if (hasCaughtError()) {
11081 _didError = true;
11082 _error = clearCaughtError();
11083 }
11084 }
11085 if (_didError) {
11086 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11087 captureCommitPhaseError(nextEffect, _error);
11088 // Clean-up
11089 if (nextEffect !== null) {
11090 nextEffect = nextEffect.nextEffect;
11091 }
11092 }
11093 }
11094 stopCommitHostEffectsTimer();
11095
11096 resetAfterCommit(root.containerInfo);
11097
11098 // The work-in-progress tree is now the current tree. This must come after
11099 // the first pass of the commit phase, so that the previous tree is still
11100 // current during componentWillUnmount, but before the second pass, so that
11101 // the finished work is current during componentDidMount/Update.
11102 root.current = finishedWork;
11103
11104 // In the second pass we'll perform all life-cycles and ref callbacks.
11105 // Life-cycles happen as a separate pass so that all placements, updates,
11106 // and deletions in the entire tree have already been invoked.
11107 // This pass also triggers any renderer-specific initial effects.
11108 nextEffect = firstEffect;
11109 startCommitLifeCyclesTimer();
11110 while (nextEffect !== null) {
11111 var _didError2 = false;
11112 var _error2 = void 0;
11113 {
11114 invokeGuardedCallback(null, commitAllLifeCycles, null, root, committedExpirationTime);
11115 if (hasCaughtError()) {
11116 _didError2 = true;
11117 _error2 = clearCaughtError();
11118 }
11119 }
11120 if (_didError2) {
11121 !(nextEffect !== null) ? invariant(false, 'Should have next effect. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11122 captureCommitPhaseError(nextEffect, _error2);
11123 if (nextEffect !== null) {
11124 nextEffect = nextEffect.nextEffect;
11125 }
11126 }
11127 }
11128
11129 if (firstEffect !== null && rootWithPendingPassiveEffects !== null) {
11130 // This commit included a passive effect. These do not need to fire until
11131 // after the next paint. Schedule an callback to fire them in an async
11132 // event. To ensure serial execution, the callback will be flushed early if
11133 // we enter rootWithPendingPassiveEffects commit phase before then.
11134 var callback = commitPassiveEffects.bind(null, root, firstEffect);
11135 if (enableSchedulerTracing) {
11136 // TODO: Avoid this extra callback by mutating the tracing ref directly,
11137 // like we do at the beginning of commitRoot. I've opted not to do that
11138 // here because that code is still in flux.
11139 callback = unstable_wrap(callback);
11140 }
11141 passiveEffectCallbackHandle = schedulePassiveEffects(callback);
11142 passiveEffectCallback = callback;
11143 }
11144
11145 isCommitting$1 = false;
11146 isWorking = false;
11147 stopCommitLifeCyclesTimer();
11148 stopCommitTimer();
11149 onCommitRoot(finishedWork.stateNode);
11150 if (true && ReactFiberInstrumentation_1.debugTool) {
11151 ReactFiberInstrumentation_1.debugTool.onCommitWork(finishedWork);
11152 }
11153
11154 var updateExpirationTimeAfterCommit = finishedWork.expirationTime;
11155 var childExpirationTimeAfterCommit = finishedWork.childExpirationTime;
11156 var earliestRemainingTimeAfterCommit = childExpirationTimeAfterCommit > updateExpirationTimeAfterCommit ? childExpirationTimeAfterCommit : updateExpirationTimeAfterCommit;
11157 if (earliestRemainingTimeAfterCommit === NoWork) {
11158 // If there's no remaining work, we can clear the set of already failed
11159 // error boundaries.
11160 legacyErrorBoundariesThatAlreadyFailed = null;
11161 }
11162 onCommit(root, earliestRemainingTimeAfterCommit);
11163
11164 if (enableSchedulerTracing) {
11165 __interactionsRef.current = prevInteractions;
11166
11167 var subscriber = void 0;
11168
11169 try {
11170 subscriber = __subscriberRef.current;
11171 if (subscriber !== null && root.memoizedInteractions.size > 0) {
11172 var threadID = computeThreadID(committedExpirationTime, root.interactionThreadID);
11173 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
11174 }
11175 } catch (error) {
11176 // It's not safe for commitRoot() to throw.
11177 // Store the error for now and we'll re-throw in finishRendering().
11178 if (!hasUnhandledError) {
11179 hasUnhandledError = true;
11180 unhandledError = error;
11181 }
11182 } finally {
11183 // Clear completed interactions from the pending Map.
11184 // Unless the render was suspended or cascading work was scheduled,
11185 // In which case– leave pending interactions until the subsequent render.
11186 var pendingInteractionMap = root.pendingInteractionMap;
11187 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11188 // Only decrement the pending interaction count if we're done.
11189 // If there's still work at the current priority,
11190 // That indicates that we are waiting for suspense data.
11191 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
11192 pendingInteractionMap.delete(scheduledExpirationTime);
11193
11194 scheduledInteractions.forEach(function (interaction) {
11195 interaction.__count--;
11196
11197 if (subscriber !== null && interaction.__count === 0) {
11198 try {
11199 subscriber.onInteractionScheduledWorkCompleted(interaction);
11200 } catch (error) {
11201 // It's not safe for commitRoot() to throw.
11202 // Store the error for now and we'll re-throw in finishRendering().
11203 if (!hasUnhandledError) {
11204 hasUnhandledError = true;
11205 unhandledError = error;
11206 }
11207 }
11208 }
11209 });
11210 }
11211 });
11212 }
11213 }
11214}
11215
11216function resetChildExpirationTime(workInProgress, renderTime) {
11217 if (renderTime !== Never && workInProgress.childExpirationTime === Never) {
11218 // The children of this component are hidden. Don't bubble their
11219 // expiration times.
11220 return;
11221 }
11222
11223 var newChildExpirationTime = NoWork;
11224
11225 // Bubble up the earliest expiration time.
11226 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11227 // We're in profiling mode.
11228 // Let's use this same traversal to update the render durations.
11229 var actualDuration = workInProgress.actualDuration;
11230 var treeBaseDuration = workInProgress.selfBaseDuration;
11231
11232 // When a fiber is cloned, its actualDuration is reset to 0.
11233 // This value will only be updated if work is done on the fiber (i.e. it doesn't bailout).
11234 // When work is done, it should bubble to the parent's actualDuration.
11235 // If the fiber has not been cloned though, (meaning no work was done),
11236 // Then this value will reflect the amount of time spent working on a previous render.
11237 // In that case it should not bubble.
11238 // We determine whether it was cloned by comparing the child pointer.
11239 var shouldBubbleActualDurations = workInProgress.alternate === null || workInProgress.child !== workInProgress.alternate.child;
11240
11241 var child = workInProgress.child;
11242 while (child !== null) {
11243 var childUpdateExpirationTime = child.expirationTime;
11244 var childChildExpirationTime = child.childExpirationTime;
11245 if (childUpdateExpirationTime > newChildExpirationTime) {
11246 newChildExpirationTime = childUpdateExpirationTime;
11247 }
11248 if (childChildExpirationTime > newChildExpirationTime) {
11249 newChildExpirationTime = childChildExpirationTime;
11250 }
11251 if (shouldBubbleActualDurations) {
11252 actualDuration += child.actualDuration;
11253 }
11254 treeBaseDuration += child.treeBaseDuration;
11255 child = child.sibling;
11256 }
11257 workInProgress.actualDuration = actualDuration;
11258 workInProgress.treeBaseDuration = treeBaseDuration;
11259 } else {
11260 var _child = workInProgress.child;
11261 while (_child !== null) {
11262 var _childUpdateExpirationTime = _child.expirationTime;
11263 var _childChildExpirationTime = _child.childExpirationTime;
11264 if (_childUpdateExpirationTime > newChildExpirationTime) {
11265 newChildExpirationTime = _childUpdateExpirationTime;
11266 }
11267 if (_childChildExpirationTime > newChildExpirationTime) {
11268 newChildExpirationTime = _childChildExpirationTime;
11269 }
11270 _child = _child.sibling;
11271 }
11272 }
11273
11274 workInProgress.childExpirationTime = newChildExpirationTime;
11275}
11276
11277function completeUnitOfWork(workInProgress) {
11278 // Attempt to complete the current unit of work, then move to the
11279 // next sibling. If there are no more siblings, return to the
11280 // parent fiber.
11281 while (true) {
11282 // The current, flushed, state of this fiber is the alternate.
11283 // Ideally nothing should rely on this, but relying on it here
11284 // means that we don't need an additional field on the work in
11285 // progress.
11286 var current = workInProgress.alternate;
11287 {
11288 setCurrentFiber(workInProgress);
11289 }
11290
11291 var returnFiber = workInProgress.return;
11292 var siblingFiber = workInProgress.sibling;
11293
11294 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
11295 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11296 // Don't replay if it fails during completion phase.
11297 mayReplayFailedUnitOfWork = false;
11298 }
11299 // This fiber completed.
11300 // Remember we're completing this unit so we can find a boundary if it fails.
11301 nextUnitOfWork = workInProgress;
11302 if (enableProfilerTimer) {
11303 if (workInProgress.mode & ProfileMode) {
11304 startProfilerTimer(workInProgress);
11305 }
11306 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11307 if (workInProgress.mode & ProfileMode) {
11308 // Update render duration assuming we didn't error.
11309 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11310 }
11311 } else {
11312 nextUnitOfWork = completeWork(current, workInProgress, nextRenderExpirationTime);
11313 }
11314 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11315 // We're out of completion phase so replaying is fine now.
11316 mayReplayFailedUnitOfWork = true;
11317 }
11318 stopWorkTimer(workInProgress);
11319 resetChildExpirationTime(workInProgress, nextRenderExpirationTime);
11320 {
11321 resetCurrentFiber();
11322 }
11323
11324 if (nextUnitOfWork !== null) {
11325 // Completing this fiber spawned new work. Work on that next.
11326 return nextUnitOfWork;
11327 }
11328
11329 if (returnFiber !== null &&
11330 // Do not append effects to parents if a sibling failed to complete
11331 (returnFiber.effectTag & Incomplete) === NoEffect) {
11332 // Append all the effects of the subtree and this fiber onto the effect
11333 // list of the parent. The completion order of the children affects the
11334 // side-effect order.
11335 if (returnFiber.firstEffect === null) {
11336 returnFiber.firstEffect = workInProgress.firstEffect;
11337 }
11338 if (workInProgress.lastEffect !== null) {
11339 if (returnFiber.lastEffect !== null) {
11340 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
11341 }
11342 returnFiber.lastEffect = workInProgress.lastEffect;
11343 }
11344
11345 // If this fiber had side-effects, we append it AFTER the children's
11346 // side-effects. We can perform certain side-effects earlier if
11347 // needed, by doing multiple passes over the effect list. We don't want
11348 // to schedule our own side-effect on our own list because if end up
11349 // reusing children we'll schedule this effect onto itself since we're
11350 // at the end.
11351 var effectTag = workInProgress.effectTag;
11352 // Skip both NoWork and PerformedWork tags when creating the effect list.
11353 // PerformedWork effect is read by React DevTools but shouldn't be committed.
11354 if (effectTag > PerformedWork) {
11355 if (returnFiber.lastEffect !== null) {
11356 returnFiber.lastEffect.nextEffect = workInProgress;
11357 } else {
11358 returnFiber.firstEffect = workInProgress;
11359 }
11360 returnFiber.lastEffect = workInProgress;
11361 }
11362 }
11363
11364 if (true && ReactFiberInstrumentation_1.debugTool) {
11365 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11366 }
11367
11368 if (siblingFiber !== null) {
11369 // If there is more work to do in this returnFiber, do that next.
11370 return siblingFiber;
11371 } else if (returnFiber !== null) {
11372 // If there's no more work in this returnFiber. Complete the returnFiber.
11373 workInProgress = returnFiber;
11374 continue;
11375 } else {
11376 // We've reached the root.
11377 return null;
11378 }
11379 } else {
11380 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
11381 // Record the render duration for the fiber that errored.
11382 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
11383
11384 // Include the time spent working on failed children before continuing.
11385 var actualDuration = workInProgress.actualDuration;
11386 var child = workInProgress.child;
11387 while (child !== null) {
11388 actualDuration += child.actualDuration;
11389 child = child.sibling;
11390 }
11391 workInProgress.actualDuration = actualDuration;
11392 }
11393
11394 // This fiber did not complete because something threw. Pop values off
11395 // the stack without entering the complete phase. If this is a boundary,
11396 // capture values if possible.
11397 var next = unwindWork(workInProgress, nextRenderExpirationTime);
11398 // Because this fiber did not complete, don't reset its expiration time.
11399 if (workInProgress.effectTag & DidCapture) {
11400 // Restarting an error boundary
11401 stopFailedWorkTimer(workInProgress);
11402 } else {
11403 stopWorkTimer(workInProgress);
11404 }
11405
11406 {
11407 resetCurrentFiber();
11408 }
11409
11410 if (next !== null) {
11411 stopWorkTimer(workInProgress);
11412 if (true && ReactFiberInstrumentation_1.debugTool) {
11413 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11414 }
11415
11416 // If completing this work spawned new work, do that next. We'll come
11417 // back here again.
11418 // Since we're restarting, remove anything that is not a host effect
11419 // from the effect tag.
11420 next.effectTag &= HostEffectMask;
11421 return next;
11422 }
11423
11424 if (returnFiber !== null) {
11425 // Mark the parent fiber as incomplete and clear its effect list.
11426 returnFiber.firstEffect = returnFiber.lastEffect = null;
11427 returnFiber.effectTag |= Incomplete;
11428 }
11429
11430 if (true && ReactFiberInstrumentation_1.debugTool) {
11431 ReactFiberInstrumentation_1.debugTool.onCompleteWork(workInProgress);
11432 }
11433
11434 if (siblingFiber !== null) {
11435 // If there is more work to do in this returnFiber, do that next.
11436 return siblingFiber;
11437 } else if (returnFiber !== null) {
11438 // If there's no more work in this returnFiber. Complete the returnFiber.
11439 workInProgress = returnFiber;
11440 continue;
11441 } else {
11442 return null;
11443 }
11444 }
11445 }
11446
11447 // Without this explicit null return Flow complains of invalid return type
11448 // TODO Remove the above while(true) loop
11449 // eslint-disable-next-line no-unreachable
11450 return null;
11451}
11452
11453function performUnitOfWork(workInProgress) {
11454 // The current, flushed, state of this fiber is the alternate.
11455 // Ideally nothing should rely on this, but relying on it here
11456 // means that we don't need an additional field on the work in
11457 // progress.
11458 var current = workInProgress.alternate;
11459
11460 // See if beginning this work spawns more work.
11461 startWorkTimer(workInProgress);
11462 {
11463 setCurrentFiber(workInProgress);
11464 }
11465
11466 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11467 stashedWorkInProgressProperties = assignFiberPropertiesInDEV(stashedWorkInProgressProperties, workInProgress);
11468 }
11469
11470 var next = void 0;
11471 if (enableProfilerTimer) {
11472 if (workInProgress.mode & ProfileMode) {
11473 startProfilerTimer(workInProgress);
11474 }
11475
11476 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11477 workInProgress.memoizedProps = workInProgress.pendingProps;
11478
11479 if (workInProgress.mode & ProfileMode) {
11480 // Record the render duration assuming we didn't bailout (or error).
11481 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
11482 }
11483 } else {
11484 next = beginWork(current, workInProgress, nextRenderExpirationTime);
11485 workInProgress.memoizedProps = workInProgress.pendingProps;
11486 }
11487
11488 {
11489 resetCurrentFiber();
11490 if (isReplayingFailedUnitOfWork) {
11491 // Currently replaying a failed unit of work. This should be unreachable,
11492 // because the render phase is meant to be idempotent, and it should
11493 // have thrown again. Since it didn't, rethrow the original error, so
11494 // React's internal stack is not misaligned.
11495 rethrowOriginalError();
11496 }
11497 }
11498 if (true && ReactFiberInstrumentation_1.debugTool) {
11499 ReactFiberInstrumentation_1.debugTool.onBeginWork(workInProgress);
11500 }
11501
11502 if (next === null) {
11503 // If this doesn't spawn new work, complete the current work.
11504 next = completeUnitOfWork(workInProgress);
11505 }
11506
11507 ReactCurrentOwner$1.current = null;
11508
11509 return next;
11510}
11511
11512function workLoop(isYieldy) {
11513 if (!isYieldy) {
11514 // Flush work without yielding
11515 while (nextUnitOfWork !== null) {
11516 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11517 }
11518 } else {
11519 // Flush asynchronous work until there's a higher priority event
11520 while (nextUnitOfWork !== null && !shouldYieldToRenderer()) {
11521 nextUnitOfWork = performUnitOfWork(nextUnitOfWork);
11522 }
11523 }
11524}
11525
11526function renderRoot(root, isYieldy) {
11527 !!isWorking ? invariant(false, 'renderRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
11528
11529 flushPassiveEffects();
11530
11531 isWorking = true;
11532 var previousDispatcher = ReactCurrentDispatcher.current;
11533 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
11534
11535 var expirationTime = root.nextExpirationTimeToWorkOn;
11536
11537 // Check if we're starting from a fresh stack, or if we're resuming from
11538 // previously yielded work.
11539 if (expirationTime !== nextRenderExpirationTime || root !== nextRoot || nextUnitOfWork === null) {
11540 // Reset the stack and start working from the root.
11541 resetStack();
11542 nextRoot = root;
11543 nextRenderExpirationTime = expirationTime;
11544 nextUnitOfWork = createWorkInProgress(nextRoot.current, null, nextRenderExpirationTime);
11545 root.pendingCommitExpirationTime = NoWork;
11546
11547 if (enableSchedulerTracing) {
11548 // Determine which interactions this batch of work currently includes,
11549 // So that we can accurately attribute time spent working on it,
11550 var interactions = new Set();
11551 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
11552 if (scheduledExpirationTime >= expirationTime) {
11553 scheduledInteractions.forEach(function (interaction) {
11554 return interactions.add(interaction);
11555 });
11556 }
11557 });
11558
11559 // Store the current set of interactions on the FiberRoot for a few reasons:
11560 // We can re-use it in hot functions like renderRoot() without having to recalculate it.
11561 // We will also use it in commitWork() to pass to any Profiler onRender() hooks.
11562 // This also provides DevTools with a way to access it when the onCommitRoot() hook is called.
11563 root.memoizedInteractions = interactions;
11564
11565 if (interactions.size > 0) {
11566 var subscriber = __subscriberRef.current;
11567 if (subscriber !== null) {
11568 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
11569 try {
11570 subscriber.onWorkStarted(interactions, threadID);
11571 } catch (error) {
11572 // Work thrown by an interaction tracing subscriber should be rethrown,
11573 // But only once it's safe (to avoid leaving the scheduler in an invalid state).
11574 // Store the error for now and we'll re-throw in finishRendering().
11575 if (!hasUnhandledError) {
11576 hasUnhandledError = true;
11577 unhandledError = error;
11578 }
11579 }
11580 }
11581 }
11582 }
11583 }
11584
11585 var prevInteractions = null;
11586 if (enableSchedulerTracing) {
11587 // We're about to start new traced work.
11588 // Restore pending interactions so cascading work triggered during the render phase will be accounted for.
11589 prevInteractions = __interactionsRef.current;
11590 __interactionsRef.current = root.memoizedInteractions;
11591 }
11592
11593 var didFatal = false;
11594
11595 startWorkLoopTimer(nextUnitOfWork);
11596
11597 do {
11598 try {
11599 workLoop(isYieldy);
11600 } catch (thrownValue) {
11601 resetContextDependences();
11602 resetHooks();
11603
11604 // Reset in case completion throws.
11605 // This is only used in DEV and when replaying is on.
11606 var mayReplay = void 0;
11607 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11608 mayReplay = mayReplayFailedUnitOfWork;
11609 mayReplayFailedUnitOfWork = true;
11610 }
11611
11612 if (nextUnitOfWork === null) {
11613 // This is a fatal error.
11614 didFatal = true;
11615 onUncaughtError(thrownValue);
11616 } else {
11617 if (enableProfilerTimer && nextUnitOfWork.mode & ProfileMode) {
11618 // Record the time spent rendering before an error was thrown.
11619 // This avoids inaccurate Profiler durations in the case of a suspended render.
11620 stopProfilerTimerIfRunningAndRecordDelta(nextUnitOfWork, true);
11621 }
11622
11623 {
11624 // Reset global debug state
11625 // We assume this is defined in DEV
11626 resetCurrentlyProcessingQueue();
11627 }
11628
11629 if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
11630 if (mayReplay) {
11631 var failedUnitOfWork = nextUnitOfWork;
11632 replayUnitOfWork(failedUnitOfWork, thrownValue, isYieldy);
11633 }
11634 }
11635
11636 // TODO: we already know this isn't true in some cases.
11637 // At least this shows a nicer error message until we figure out the cause.
11638 // https://github.com/facebook/react/issues/12449#issuecomment-386727431
11639 !(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;
11640
11641 var sourceFiber = nextUnitOfWork;
11642 var returnFiber = sourceFiber.return;
11643 if (returnFiber === null) {
11644 // This is the root. The root could capture its own errors. However,
11645 // we don't know if it errors before or after we pushed the host
11646 // context. This information is needed to avoid a stack mismatch.
11647 // Because we're not sure, treat this as a fatal error. We could track
11648 // which phase it fails in, but doesn't seem worth it. At least
11649 // for now.
11650 didFatal = true;
11651 onUncaughtError(thrownValue);
11652 } else {
11653 throwException(root, returnFiber, sourceFiber, thrownValue, nextRenderExpirationTime);
11654 nextUnitOfWork = completeUnitOfWork(sourceFiber);
11655 continue;
11656 }
11657 }
11658 }
11659 break;
11660 } while (true);
11661
11662 if (enableSchedulerTracing) {
11663 // Traced work is done for now; restore the previous interactions.
11664 __interactionsRef.current = prevInteractions;
11665 }
11666
11667 // We're done performing work. Time to clean up.
11668 isWorking = false;
11669 ReactCurrentDispatcher.current = previousDispatcher;
11670 resetContextDependences();
11671 resetHooks();
11672
11673 // Yield back to main thread.
11674 if (didFatal) {
11675 var _didCompleteRoot = false;
11676 stopWorkLoopTimer(interruptedBy, _didCompleteRoot);
11677 interruptedBy = null;
11678 // There was a fatal error.
11679 {
11680 resetStackAfterFatalErrorInDev();
11681 }
11682 // `nextRoot` points to the in-progress root. A non-null value indicates
11683 // that we're in the middle of an async render. Set it to null to indicate
11684 // there's no more work to be done in the current batch.
11685 nextRoot = null;
11686 onFatal(root);
11687 return;
11688 }
11689
11690 if (nextUnitOfWork !== null) {
11691 // There's still remaining async work in this tree, but we ran out of time
11692 // in the current frame. Yield back to the renderer. Unless we're
11693 // interrupted by a higher priority update, we'll continue later from where
11694 // we left off.
11695 var _didCompleteRoot2 = false;
11696 stopWorkLoopTimer(interruptedBy, _didCompleteRoot2);
11697 interruptedBy = null;
11698 onYield(root);
11699 return;
11700 }
11701
11702 // We completed the whole tree.
11703 var didCompleteRoot = true;
11704 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
11705 var rootWorkInProgress = root.current.alternate;
11706 !(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;
11707
11708 // `nextRoot` points to the in-progress root. A non-null value indicates
11709 // that we're in the middle of an async render. Set it to null to indicate
11710 // there's no more work to be done in the current batch.
11711 nextRoot = null;
11712 interruptedBy = null;
11713
11714 if (nextRenderDidError) {
11715 // There was an error
11716 if (hasLowerPriorityWork(root, expirationTime)) {
11717 // There's lower priority work. If so, it may have the effect of fixing
11718 // the exception that was just thrown. Exit without committing. This is
11719 // similar to a suspend, but without a timeout because we're not waiting
11720 // for a promise to resolve. React will restart at the lower
11721 // priority level.
11722 markSuspendedPriorityLevel(root, expirationTime);
11723 var suspendedExpirationTime = expirationTime;
11724 var rootExpirationTime = root.expirationTime;
11725 onSuspend(root, rootWorkInProgress, suspendedExpirationTime, rootExpirationTime, -1 // Indicates no timeout
11726 );
11727 return;
11728 } else if (
11729 // There's no lower priority work, but we're rendering asynchronously.
11730 // Synchronsouly attempt to render the same level one more time. This is
11731 // similar to a suspend, but without a timeout because we're not waiting
11732 // for a promise to resolve.
11733 !root.didError && isYieldy) {
11734 root.didError = true;
11735 var _suspendedExpirationTime = root.nextExpirationTimeToWorkOn = expirationTime;
11736 var _rootExpirationTime = root.expirationTime = Sync;
11737 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime, _rootExpirationTime, -1 // Indicates no timeout
11738 );
11739 return;
11740 }
11741 }
11742
11743 if (isYieldy && nextLatestAbsoluteTimeoutMs !== -1) {
11744 // The tree was suspended.
11745 var _suspendedExpirationTime2 = expirationTime;
11746 markSuspendedPriorityLevel(root, _suspendedExpirationTime2);
11747
11748 // Find the earliest uncommitted expiration time in the tree, including
11749 // work that is suspended. The timeout threshold cannot be longer than
11750 // the overall expiration.
11751 var earliestExpirationTime = findEarliestOutstandingPriorityLevel(root, expirationTime);
11752 var earliestExpirationTimeMs = expirationTimeToMs(earliestExpirationTime);
11753 if (earliestExpirationTimeMs < nextLatestAbsoluteTimeoutMs) {
11754 nextLatestAbsoluteTimeoutMs = earliestExpirationTimeMs;
11755 }
11756
11757 // Subtract the current time from the absolute timeout to get the number
11758 // of milliseconds until the timeout. In other words, convert an absolute
11759 // timestamp to a relative time. This is the value that is passed
11760 // to `setTimeout`.
11761 var currentTimeMs = expirationTimeToMs(requestCurrentTime());
11762 var msUntilTimeout = nextLatestAbsoluteTimeoutMs - currentTimeMs;
11763 msUntilTimeout = msUntilTimeout < 0 ? 0 : msUntilTimeout;
11764
11765 // TODO: Account for the Just Noticeable Difference
11766
11767 var _rootExpirationTime2 = root.expirationTime;
11768 onSuspend(root, rootWorkInProgress, _suspendedExpirationTime2, _rootExpirationTime2, msUntilTimeout);
11769 return;
11770 }
11771
11772 // Ready to commit.
11773 onComplete(root, rootWorkInProgress, expirationTime);
11774}
11775
11776function captureCommitPhaseError(sourceFiber, value) {
11777 var expirationTime = Sync;
11778 var fiber = sourceFiber.return;
11779 while (fiber !== null) {
11780 switch (fiber.tag) {
11781 case ClassComponent:
11782 var ctor = fiber.type;
11783 var instance = fiber.stateNode;
11784 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
11785 var errorInfo = createCapturedValue(value, sourceFiber);
11786 var update = createClassErrorUpdate(fiber, errorInfo, expirationTime);
11787 enqueueUpdate(fiber, update);
11788 scheduleWork(fiber, expirationTime);
11789 return;
11790 }
11791 break;
11792 case HostRoot:
11793 {
11794 var _errorInfo = createCapturedValue(value, sourceFiber);
11795 var _update = createRootErrorUpdate(fiber, _errorInfo, expirationTime);
11796 enqueueUpdate(fiber, _update);
11797 scheduleWork(fiber, expirationTime);
11798 return;
11799 }
11800 }
11801 fiber = fiber.return;
11802 }
11803
11804 if (sourceFiber.tag === HostRoot) {
11805 // Error was thrown at the root. There is no parent, so the root
11806 // itself should capture it.
11807 var rootFiber = sourceFiber;
11808 var _errorInfo2 = createCapturedValue(value, rootFiber);
11809 var _update2 = createRootErrorUpdate(rootFiber, _errorInfo2, expirationTime);
11810 enqueueUpdate(rootFiber, _update2);
11811 scheduleWork(rootFiber, expirationTime);
11812 }
11813}
11814
11815function computeThreadID(expirationTime, interactionThreadID) {
11816 // Interaction threads are unique per root and expiration time.
11817 return expirationTime * 1000 + interactionThreadID;
11818}
11819
11820function computeExpirationForFiber(currentTime, fiber) {
11821 var expirationTime = void 0;
11822 if (expirationContext !== NoWork) {
11823 // An explicit expiration context was set;
11824 expirationTime = expirationContext;
11825 } else if (isWorking) {
11826 if (isCommitting$1) {
11827 // Updates that occur during the commit phase should have sync priority
11828 // by default.
11829 expirationTime = Sync;
11830 } else {
11831 // Updates during the render phase should expire at the same time as
11832 // the work that is being rendered.
11833 expirationTime = nextRenderExpirationTime;
11834 }
11835 } else {
11836 // No explicit expiration context was set, and we're not currently
11837 // performing work. Calculate a new expiration time.
11838 if (fiber.mode & ConcurrentMode) {
11839 if (isBatchingInteractiveUpdates) {
11840 // This is an interactive update
11841 expirationTime = computeInteractiveExpiration(currentTime);
11842 } else {
11843 // This is an async update
11844 expirationTime = computeAsyncExpiration(currentTime);
11845 }
11846 // If we're in the middle of rendering a tree, do not update at the same
11847 // expiration time that is already rendering.
11848 if (nextRoot !== null && expirationTime === nextRenderExpirationTime) {
11849 expirationTime -= 1;
11850 }
11851 } else {
11852 // This is a sync update
11853 expirationTime = Sync;
11854 }
11855 }
11856 return expirationTime;
11857}
11858
11859function renderDidSuspend(root, absoluteTimeoutMs, suspendedTime) {
11860 // Schedule the timeout.
11861 if (absoluteTimeoutMs >= 0 && nextLatestAbsoluteTimeoutMs < absoluteTimeoutMs) {
11862 nextLatestAbsoluteTimeoutMs = absoluteTimeoutMs;
11863 }
11864}
11865
11866function renderDidError() {
11867 nextRenderDidError = true;
11868}
11869
11870function pingSuspendedRoot(root, thenable, pingTime) {
11871 // A promise that previously suspended React from committing has resolved.
11872 // If React is still suspended, try again at the previous level (pingTime).
11873
11874 var pingCache = root.pingCache;
11875 if (pingCache !== null) {
11876 // The thenable resolved, so we no longer need to memoize, because it will
11877 // never be thrown again.
11878 pingCache.delete(thenable);
11879 }
11880
11881 if (nextRoot !== null && nextRenderExpirationTime === pingTime) {
11882 // Received a ping at the same priority level at which we're currently
11883 // rendering. Restart from the root.
11884 nextRoot = null;
11885 } else {
11886 // Confirm that the root is still suspended at this level. Otherwise exit.
11887 if (isPriorityLevelSuspended(root, pingTime)) {
11888 // Ping at the original level
11889 markPingedPriorityLevel(root, pingTime);
11890 var rootExpirationTime = root.expirationTime;
11891 if (rootExpirationTime !== NoWork) {
11892 requestWork(root, rootExpirationTime);
11893 }
11894 }
11895 }
11896}
11897
11898function retryTimedOutBoundary(boundaryFiber, thenable) {
11899 // The boundary fiber (a Suspense component) previously timed out and was
11900 // rendered in its fallback state. One of the promises that suspended it has
11901 // resolved, which means at least part of the tree was likely unblocked. Try
11902 var retryCache = boundaryFiber.stateNode;
11903 if (retryCache !== null) {
11904 // The thenable resolved, so we no longer need to memoize, because it will
11905 // never be thrown again.
11906 retryCache.delete(thenable);
11907 }
11908
11909 var currentTime = requestCurrentTime();
11910 var retryTime = computeExpirationForFiber(currentTime, boundaryFiber);
11911 var root = scheduleWorkToRoot(boundaryFiber, retryTime);
11912 if (root !== null) {
11913 markPendingPriorityLevel(root, retryTime);
11914 var rootExpirationTime = root.expirationTime;
11915 if (rootExpirationTime !== NoWork) {
11916 requestWork(root, rootExpirationTime);
11917 }
11918 }
11919}
11920
11921function scheduleWorkToRoot(fiber, expirationTime) {
11922 recordScheduleUpdate();
11923
11924 {
11925 if (fiber.tag === ClassComponent) {
11926 var instance = fiber.stateNode;
11927 warnAboutInvalidUpdates(instance);
11928 }
11929 }
11930
11931 // Update the source fiber's expiration time
11932 if (fiber.expirationTime < expirationTime) {
11933 fiber.expirationTime = expirationTime;
11934 }
11935 var alternate = fiber.alternate;
11936 if (alternate !== null && alternate.expirationTime < expirationTime) {
11937 alternate.expirationTime = expirationTime;
11938 }
11939 // Walk the parent path to the root and update the child expiration time.
11940 var node = fiber.return;
11941 var root = null;
11942 if (node === null && fiber.tag === HostRoot) {
11943 root = fiber.stateNode;
11944 } else {
11945 while (node !== null) {
11946 alternate = node.alternate;
11947 if (node.childExpirationTime < expirationTime) {
11948 node.childExpirationTime = expirationTime;
11949 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
11950 alternate.childExpirationTime = expirationTime;
11951 }
11952 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
11953 alternate.childExpirationTime = expirationTime;
11954 }
11955 if (node.return === null && node.tag === HostRoot) {
11956 root = node.stateNode;
11957 break;
11958 }
11959 node = node.return;
11960 }
11961 }
11962
11963 if (enableSchedulerTracing) {
11964 if (root !== null) {
11965 var interactions = __interactionsRef.current;
11966 if (interactions.size > 0) {
11967 var pendingInteractionMap = root.pendingInteractionMap;
11968 var pendingInteractions = pendingInteractionMap.get(expirationTime);
11969 if (pendingInteractions != null) {
11970 interactions.forEach(function (interaction) {
11971 if (!pendingInteractions.has(interaction)) {
11972 // Update the pending async work count for previously unscheduled interaction.
11973 interaction.__count++;
11974 }
11975
11976 pendingInteractions.add(interaction);
11977 });
11978 } else {
11979 pendingInteractionMap.set(expirationTime, new Set(interactions));
11980
11981 // Update the pending async work count for the current interactions.
11982 interactions.forEach(function (interaction) {
11983 interaction.__count++;
11984 });
11985 }
11986
11987 var subscriber = __subscriberRef.current;
11988 if (subscriber !== null) {
11989 var threadID = computeThreadID(expirationTime, root.interactionThreadID);
11990 subscriber.onWorkScheduled(interactions, threadID);
11991 }
11992 }
11993 }
11994 }
11995 return root;
11996}
11997
11998function warnIfNotCurrentlyBatchingInDev(fiber) {
11999 {
12000 if (isRendering === false && isBatchingUpdates === false) {
12001 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', getComponentName(fiber.type));
12002 }
12003 }
12004}
12005
12006function scheduleWork(fiber, expirationTime) {
12007 var root = scheduleWorkToRoot(fiber, expirationTime);
12008 if (root === null) {
12009 {
12010 switch (fiber.tag) {
12011 case ClassComponent:
12012 warnAboutUpdateOnUnmounted(fiber, true);
12013 break;
12014 case FunctionComponent:
12015 case ForwardRef:
12016 case MemoComponent:
12017 case SimpleMemoComponent:
12018 warnAboutUpdateOnUnmounted(fiber, false);
12019 break;
12020 }
12021 }
12022 return;
12023 }
12024
12025 if (!isWorking && nextRenderExpirationTime !== NoWork && expirationTime > nextRenderExpirationTime) {
12026 // This is an interruption. (Used for performance tracking.)
12027 interruptedBy = fiber;
12028 resetStack();
12029 }
12030 markPendingPriorityLevel(root, expirationTime);
12031 if (
12032 // If we're in the render phase, we don't need to schedule this root
12033 // for an update, because we'll do it before we exit...
12034 !isWorking || isCommitting$1 ||
12035 // ...unless this is a different root than the one we're rendering.
12036 nextRoot !== root) {
12037 var rootExpirationTime = root.expirationTime;
12038 requestWork(root, rootExpirationTime);
12039 }
12040 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
12041 // Reset this back to zero so subsequent updates don't throw.
12042 nestedUpdateCount = 0;
12043 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.');
12044 }
12045}
12046
12047// TODO: Everything below this is written as if it has been lifted to the
12048// renderers. I'll do this in a follow-up.
12049
12050// Linked-list of roots
12051var firstScheduledRoot = null;
12052var lastScheduledRoot = null;
12053
12054var callbackExpirationTime = NoWork;
12055var callbackID = void 0;
12056var isRendering = false;
12057var nextFlushedRoot = null;
12058var nextFlushedExpirationTime = NoWork;
12059var hasUnhandledError = false;
12060var unhandledError = null;
12061
12062var isBatchingUpdates = false;
12063var isUnbatchingUpdates = false;
12064var isBatchingInteractiveUpdates = false;
12065
12066var completedBatches = null;
12067
12068var originalStartTimeMs = unstable_now();
12069var currentRendererTime = msToExpirationTime(originalStartTimeMs);
12070var currentSchedulerTime = currentRendererTime;
12071
12072// Use these to prevent an infinite loop of nested updates
12073var NESTED_UPDATE_LIMIT = 50;
12074var nestedUpdateCount = 0;
12075var lastCommittedRootDuringThisBatch = null;
12076
12077function recomputeCurrentRendererTime() {
12078 var currentTimeMs = unstable_now() - originalStartTimeMs;
12079 currentRendererTime = msToExpirationTime(currentTimeMs);
12080}
12081
12082function scheduleCallbackWithExpirationTime(root, expirationTime) {
12083 if (callbackExpirationTime !== NoWork) {
12084 // A callback is already scheduled. Check its expiration time (timeout).
12085 if (expirationTime < callbackExpirationTime) {
12086 // Existing callback has sufficient timeout. Exit.
12087 return;
12088 } else {
12089 if (callbackID !== null) {
12090 // Existing callback has insufficient timeout. Cancel and schedule a
12091 // new one.
12092 unstable_cancelCallback(callbackID);
12093 }
12094 }
12095 // The request callback timer is already running. Don't start a new one.
12096 } else {
12097 startRequestCallbackTimer();
12098 }
12099
12100 callbackExpirationTime = expirationTime;
12101 var currentMs = unstable_now() - originalStartTimeMs;
12102 var expirationTimeMs = expirationTimeToMs(expirationTime);
12103 var timeout = expirationTimeMs - currentMs;
12104 callbackID = unstable_scheduleCallback(performAsyncWork, { timeout: timeout });
12105}
12106
12107// For every call to renderRoot, one of onFatal, onComplete, onSuspend, and
12108// onYield is called upon exiting. We use these in lieu of returning a tuple.
12109// I've also chosen not to inline them into renderRoot because these will
12110// eventually be lifted into the renderer.
12111function onFatal(root) {
12112 root.finishedWork = null;
12113}
12114
12115function onComplete(root, finishedWork, expirationTime) {
12116 root.pendingCommitExpirationTime = expirationTime;
12117 root.finishedWork = finishedWork;
12118}
12119
12120function onSuspend(root, finishedWork, suspendedExpirationTime, rootExpirationTime, msUntilTimeout) {
12121 root.expirationTime = rootExpirationTime;
12122 if (msUntilTimeout === 0 && !shouldYieldToRenderer()) {
12123 // Don't wait an additional tick. Commit the tree immediately.
12124 root.pendingCommitExpirationTime = suspendedExpirationTime;
12125 root.finishedWork = finishedWork;
12126 } else if (msUntilTimeout > 0) {
12127 // Wait `msUntilTimeout` milliseconds before committing.
12128 root.timeoutHandle = scheduleTimeout(onTimeout.bind(null, root, finishedWork, suspendedExpirationTime), msUntilTimeout);
12129 }
12130}
12131
12132function onYield(root) {
12133 root.finishedWork = null;
12134}
12135
12136function onTimeout(root, finishedWork, suspendedExpirationTime) {
12137 // The root timed out. Commit it.
12138 root.pendingCommitExpirationTime = suspendedExpirationTime;
12139 root.finishedWork = finishedWork;
12140 // Read the current time before entering the commit phase. We can be
12141 // certain this won't cause tearing related to batching of event updates
12142 // because we're at the top of a timer event.
12143 recomputeCurrentRendererTime();
12144 currentSchedulerTime = currentRendererTime;
12145 flushRoot(root, suspendedExpirationTime);
12146}
12147
12148function onCommit(root, expirationTime) {
12149 root.expirationTime = expirationTime;
12150 root.finishedWork = null;
12151}
12152
12153function requestCurrentTime() {
12154 // requestCurrentTime is called by the scheduler to compute an expiration
12155 // time.
12156 //
12157 // Expiration times are computed by adding to the current time (the start
12158 // time). However, if two updates are scheduled within the same event, we
12159 // should treat their start times as simultaneous, even if the actual clock
12160 // time has advanced between the first and second call.
12161
12162 // In other words, because expiration times determine how updates are batched,
12163 // we want all updates of like priority that occur within the same event to
12164 // receive the same expiration time. Otherwise we get tearing.
12165 //
12166 // We keep track of two separate times: the current "renderer" time and the
12167 // current "scheduler" time. The renderer time can be updated whenever; it
12168 // only exists to minimize the calls performance.now.
12169 //
12170 // But the scheduler time can only be updated if there's no pending work, or
12171 // if we know for certain that we're not in the middle of an event.
12172
12173 if (isRendering) {
12174 // We're already rendering. Return the most recently read time.
12175 return currentSchedulerTime;
12176 }
12177 // Check if there's pending work.
12178 findHighestPriorityRoot();
12179 if (nextFlushedExpirationTime === NoWork || nextFlushedExpirationTime === Never) {
12180 // If there's no pending work, or if the pending work is offscreen, we can
12181 // read the current time without risk of tearing.
12182 recomputeCurrentRendererTime();
12183 currentSchedulerTime = currentRendererTime;
12184 return currentSchedulerTime;
12185 }
12186 // There's already pending work. We might be in the middle of a browser
12187 // event. If we were to read the current time, it could cause multiple updates
12188 // within the same event to receive different expiration times, leading to
12189 // tearing. Return the last read time. During the next idle callback, the
12190 // time will be updated.
12191 return currentSchedulerTime;
12192}
12193
12194// requestWork is called by the scheduler whenever a root receives an update.
12195// It's up to the renderer to call renderRoot at some point in the future.
12196function requestWork(root, expirationTime) {
12197 addRootToSchedule(root, expirationTime);
12198 if (isRendering) {
12199 // Prevent reentrancy. Remaining work will be scheduled at the end of
12200 // the currently rendering batch.
12201 return;
12202 }
12203
12204 if (isBatchingUpdates) {
12205 // Flush work at the end of the batch.
12206 if (isUnbatchingUpdates) {
12207 // ...unless we're inside unbatchedUpdates, in which case we should
12208 // flush it now.
12209 nextFlushedRoot = root;
12210 nextFlushedExpirationTime = Sync;
12211 performWorkOnRoot(root, Sync, false);
12212 }
12213 return;
12214 }
12215
12216 // TODO: Get rid of Sync and use current time?
12217 if (expirationTime === Sync) {
12218 performSyncWork();
12219 } else {
12220 scheduleCallbackWithExpirationTime(root, expirationTime);
12221 }
12222}
12223
12224function addRootToSchedule(root, expirationTime) {
12225 // Add the root to the schedule.
12226 // Check if this root is already part of the schedule.
12227 if (root.nextScheduledRoot === null) {
12228 // This root is not already scheduled. Add it.
12229 root.expirationTime = expirationTime;
12230 if (lastScheduledRoot === null) {
12231 firstScheduledRoot = lastScheduledRoot = root;
12232 root.nextScheduledRoot = root;
12233 } else {
12234 lastScheduledRoot.nextScheduledRoot = root;
12235 lastScheduledRoot = root;
12236 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12237 }
12238 } else {
12239 // This root is already scheduled, but its priority may have increased.
12240 var remainingExpirationTime = root.expirationTime;
12241 if (expirationTime > remainingExpirationTime) {
12242 // Update the priority.
12243 root.expirationTime = expirationTime;
12244 }
12245 }
12246}
12247
12248function findHighestPriorityRoot() {
12249 var highestPriorityWork = NoWork;
12250 var highestPriorityRoot = null;
12251 if (lastScheduledRoot !== null) {
12252 var previousScheduledRoot = lastScheduledRoot;
12253 var root = firstScheduledRoot;
12254 while (root !== null) {
12255 var remainingExpirationTime = root.expirationTime;
12256 if (remainingExpirationTime === NoWork) {
12257 // This root no longer has work. Remove it from the scheduler.
12258
12259 // TODO: This check is redudant, but Flow is confused by the branch
12260 // below where we set lastScheduledRoot to null, even though we break
12261 // from the loop right after.
12262 !(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;
12263 if (root === root.nextScheduledRoot) {
12264 // This is the only root in the list.
12265 root.nextScheduledRoot = null;
12266 firstScheduledRoot = lastScheduledRoot = null;
12267 break;
12268 } else if (root === firstScheduledRoot) {
12269 // This is the first root in the list.
12270 var next = root.nextScheduledRoot;
12271 firstScheduledRoot = next;
12272 lastScheduledRoot.nextScheduledRoot = next;
12273 root.nextScheduledRoot = null;
12274 } else if (root === lastScheduledRoot) {
12275 // This is the last root in the list.
12276 lastScheduledRoot = previousScheduledRoot;
12277 lastScheduledRoot.nextScheduledRoot = firstScheduledRoot;
12278 root.nextScheduledRoot = null;
12279 break;
12280 } else {
12281 previousScheduledRoot.nextScheduledRoot = root.nextScheduledRoot;
12282 root.nextScheduledRoot = null;
12283 }
12284 root = previousScheduledRoot.nextScheduledRoot;
12285 } else {
12286 if (remainingExpirationTime > highestPriorityWork) {
12287 // Update the priority, if it's higher
12288 highestPriorityWork = remainingExpirationTime;
12289 highestPriorityRoot = root;
12290 }
12291 if (root === lastScheduledRoot) {
12292 break;
12293 }
12294 if (highestPriorityWork === Sync) {
12295 // Sync is highest priority by definition so
12296 // we can stop searching.
12297 break;
12298 }
12299 previousScheduledRoot = root;
12300 root = root.nextScheduledRoot;
12301 }
12302 }
12303 }
12304
12305 nextFlushedRoot = highestPriorityRoot;
12306 nextFlushedExpirationTime = highestPriorityWork;
12307}
12308
12309// TODO: This wrapper exists because many of the older tests (the ones that use
12310// flushDeferredPri) rely on the number of times `shouldYield` is called. We
12311// should get rid of it.
12312var didYield = false;
12313function shouldYieldToRenderer() {
12314 if (didYield) {
12315 return true;
12316 }
12317 if (unstable_shouldYield()) {
12318 didYield = true;
12319 return true;
12320 }
12321 return false;
12322}
12323
12324function performAsyncWork() {
12325 try {
12326 if (!shouldYieldToRenderer()) {
12327 // The callback timed out. That means at least one update has expired.
12328 // Iterate through the root schedule. If they contain expired work, set
12329 // the next render expiration time to the current time. This has the effect
12330 // of flushing all expired work in a single batch, instead of flushing each
12331 // level one at a time.
12332 if (firstScheduledRoot !== null) {
12333 recomputeCurrentRendererTime();
12334 var root = firstScheduledRoot;
12335 do {
12336 didExpireAtExpirationTime(root, currentRendererTime);
12337 // The root schedule is circular, so this is never null.
12338 root = root.nextScheduledRoot;
12339 } while (root !== firstScheduledRoot);
12340 }
12341 }
12342 performWork(NoWork, true);
12343 } finally {
12344 didYield = false;
12345 }
12346}
12347
12348function performSyncWork() {
12349 performWork(Sync, false);
12350}
12351
12352function performWork(minExpirationTime, isYieldy) {
12353 // Keep working on roots until there's no more work, or until there's a higher
12354 // priority event.
12355 findHighestPriorityRoot();
12356
12357 if (isYieldy) {
12358 recomputeCurrentRendererTime();
12359 currentSchedulerTime = currentRendererTime;
12360
12361 if (enableUserTimingAPI) {
12362 var didExpire = nextFlushedExpirationTime > currentRendererTime;
12363 var timeout = expirationTimeToMs(nextFlushedExpirationTime);
12364 stopRequestCallbackTimer(didExpire, timeout);
12365 }
12366
12367 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime && !(didYield && currentRendererTime > nextFlushedExpirationTime)) {
12368 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, currentRendererTime > nextFlushedExpirationTime);
12369 findHighestPriorityRoot();
12370 recomputeCurrentRendererTime();
12371 currentSchedulerTime = currentRendererTime;
12372 }
12373 } else {
12374 while (nextFlushedRoot !== null && nextFlushedExpirationTime !== NoWork && minExpirationTime <= nextFlushedExpirationTime) {
12375 performWorkOnRoot(nextFlushedRoot, nextFlushedExpirationTime, false);
12376 findHighestPriorityRoot();
12377 }
12378 }
12379
12380 // We're done flushing work. Either we ran out of time in this callback,
12381 // or there's no more work left with sufficient priority.
12382
12383 // If we're inside a callback, set this to false since we just completed it.
12384 if (isYieldy) {
12385 callbackExpirationTime = NoWork;
12386 callbackID = null;
12387 }
12388 // If there's work left over, schedule a new callback.
12389 if (nextFlushedExpirationTime !== NoWork) {
12390 scheduleCallbackWithExpirationTime(nextFlushedRoot, nextFlushedExpirationTime);
12391 }
12392
12393 // Clean-up.
12394 finishRendering();
12395}
12396
12397function flushRoot(root, expirationTime) {
12398 !!isRendering ? invariant(false, 'work.commit(): Cannot commit while already rendering. This likely means you attempted to commit from inside a lifecycle method.') : void 0;
12399 // Perform work on root as if the given expiration time is the current time.
12400 // This has the effect of synchronously flushing all work up to and
12401 // including the given time.
12402 nextFlushedRoot = root;
12403 nextFlushedExpirationTime = expirationTime;
12404 performWorkOnRoot(root, expirationTime, false);
12405 // Flush any sync work that was scheduled by lifecycles
12406 performSyncWork();
12407}
12408
12409function finishRendering() {
12410 nestedUpdateCount = 0;
12411 lastCommittedRootDuringThisBatch = null;
12412
12413 if (completedBatches !== null) {
12414 var batches = completedBatches;
12415 completedBatches = null;
12416 for (var i = 0; i < batches.length; i++) {
12417 var batch = batches[i];
12418 try {
12419 batch._onComplete();
12420 } catch (error) {
12421 if (!hasUnhandledError) {
12422 hasUnhandledError = true;
12423 unhandledError = error;
12424 }
12425 }
12426 }
12427 }
12428
12429 if (hasUnhandledError) {
12430 var error = unhandledError;
12431 unhandledError = null;
12432 hasUnhandledError = false;
12433 throw error;
12434 }
12435}
12436
12437function performWorkOnRoot(root, expirationTime, isYieldy) {
12438 !!isRendering ? invariant(false, 'performWorkOnRoot was called recursively. This error is likely caused by a bug in React. Please file an issue.') : void 0;
12439
12440 isRendering = true;
12441
12442 // Check if this is async work or sync/expired work.
12443 if (!isYieldy) {
12444 // Flush work without yielding.
12445 // TODO: Non-yieldy work does not necessarily imply expired work. A renderer
12446 // may want to perform some work without yielding, but also without
12447 // requiring the root to complete (by triggering placeholders).
12448
12449 var finishedWork = root.finishedWork;
12450 if (finishedWork !== null) {
12451 // This root is already complete. We can commit it.
12452 completeRoot(root, finishedWork, expirationTime);
12453 } else {
12454 root.finishedWork = null;
12455 // If this root previously suspended, clear its existing timeout, since
12456 // we're about to try rendering again.
12457 var timeoutHandle = root.timeoutHandle;
12458 if (timeoutHandle !== noTimeout) {
12459 root.timeoutHandle = noTimeout;
12460 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12461 cancelTimeout(timeoutHandle);
12462 }
12463 renderRoot(root, isYieldy);
12464 finishedWork = root.finishedWork;
12465 if (finishedWork !== null) {
12466 // We've completed the root. Commit it.
12467 completeRoot(root, finishedWork, expirationTime);
12468 }
12469 }
12470 } else {
12471 // Flush async work.
12472 var _finishedWork = root.finishedWork;
12473 if (_finishedWork !== null) {
12474 // This root is already complete. We can commit it.
12475 completeRoot(root, _finishedWork, expirationTime);
12476 } else {
12477 root.finishedWork = null;
12478 // If this root previously suspended, clear its existing timeout, since
12479 // we're about to try rendering again.
12480 var _timeoutHandle = root.timeoutHandle;
12481 if (_timeoutHandle !== noTimeout) {
12482 root.timeoutHandle = noTimeout;
12483 // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
12484 cancelTimeout(_timeoutHandle);
12485 }
12486 renderRoot(root, isYieldy);
12487 _finishedWork = root.finishedWork;
12488 if (_finishedWork !== null) {
12489 // We've completed the root. Check the if we should yield one more time
12490 // before committing.
12491 if (!shouldYieldToRenderer()) {
12492 // Still time left. Commit the root.
12493 completeRoot(root, _finishedWork, expirationTime);
12494 } else {
12495 // There's no time left. Mark this root as complete. We'll come
12496 // back and commit it later.
12497 root.finishedWork = _finishedWork;
12498 }
12499 }
12500 }
12501 }
12502
12503 isRendering = false;
12504}
12505
12506function completeRoot(root, finishedWork, expirationTime) {
12507 // Check if there's a batch that matches this expiration time.
12508 var firstBatch = root.firstBatch;
12509 if (firstBatch !== null && firstBatch._expirationTime >= expirationTime) {
12510 if (completedBatches === null) {
12511 completedBatches = [firstBatch];
12512 } else {
12513 completedBatches.push(firstBatch);
12514 }
12515 if (firstBatch._defer) {
12516 // This root is blocked from committing by a batch. Unschedule it until
12517 // we receive another update.
12518 root.finishedWork = finishedWork;
12519 root.expirationTime = NoWork;
12520 return;
12521 }
12522 }
12523
12524 // Commit the root.
12525 root.finishedWork = null;
12526
12527 // Check if this is a nested update (a sync update scheduled during the
12528 // commit phase).
12529 if (root === lastCommittedRootDuringThisBatch) {
12530 // If the next root is the same as the previous root, this is a nested
12531 // update. To prevent an infinite loop, increment the nested update count.
12532 nestedUpdateCount++;
12533 } else {
12534 // Reset whenever we switch roots.
12535 lastCommittedRootDuringThisBatch = root;
12536 nestedUpdateCount = 0;
12537 }
12538 commitRoot(root, finishedWork);
12539}
12540
12541function onUncaughtError(error) {
12542 !(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;
12543 // Unschedule this root so we don't work on it again until there's
12544 // another update.
12545 nextFlushedRoot.expirationTime = NoWork;
12546 if (!hasUnhandledError) {
12547 hasUnhandledError = true;
12548 unhandledError = error;
12549 }
12550}
12551
12552// 0 is PROD, 1 is DEV.
12553// Might add PROFILE later.
12554
12555
12556var didWarnAboutNestedUpdates = void 0;
12557{
12558 didWarnAboutNestedUpdates = false;
12559
12560}
12561
12562function getContextForSubtree(parentComponent) {
12563 if (!parentComponent) {
12564 return emptyContextObject;
12565 }
12566
12567 var fiber = get(parentComponent);
12568 var parentContext = findCurrentUnmaskedContext(fiber);
12569
12570 if (fiber.tag === ClassComponent) {
12571 var Component = fiber.type;
12572 if (isContextProvider(Component)) {
12573 return processChildContext(fiber, Component, parentContext);
12574 }
12575 }
12576
12577 return parentContext;
12578}
12579
12580function scheduleRootUpdate(current$$1, element, expirationTime, callback) {
12581 {
12582 if (phase === 'render' && current$1 !== null && !didWarnAboutNestedUpdates) {
12583 didWarnAboutNestedUpdates = true;
12584 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');
12585 }
12586 }
12587
12588 var update = createUpdate(expirationTime);
12589 // Caution: React DevTools currently depends on this property
12590 // being called "element".
12591 update.payload = { element: element };
12592
12593 callback = callback === undefined ? null : callback;
12594 if (callback !== null) {
12595 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
12596 update.callback = callback;
12597 }
12598
12599 flushPassiveEffects();
12600 enqueueUpdate(current$$1, update);
12601 scheduleWork(current$$1, expirationTime);
12602
12603 return expirationTime;
12604}
12605
12606function updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback) {
12607 // TODO: If this is a nested container, this won't be the root.
12608 var current$$1 = container.current;
12609
12610 {
12611 if (ReactFiberInstrumentation_1.debugTool) {
12612 if (current$$1.alternate === null) {
12613 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
12614 } else if (element === null) {
12615 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
12616 } else {
12617 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
12618 }
12619 }
12620 }
12621
12622 var context = getContextForSubtree(parentComponent);
12623 if (container.context === null) {
12624 container.context = context;
12625 } else {
12626 container.pendingContext = context;
12627 }
12628
12629 return scheduleRootUpdate(current$$1, element, expirationTime, callback);
12630}
12631
12632function createContainer(containerInfo, isConcurrent, hydrate) {
12633 return createFiberRoot(containerInfo, isConcurrent, hydrate);
12634}
12635
12636function updateContainer(element, container, parentComponent, callback) {
12637 var current$$1 = container.current;
12638 var currentTime = requestCurrentTime();
12639 var expirationTime = computeExpirationForFiber(currentTime, current$$1);
12640 return updateContainerAtExpirationTime(element, container, parentComponent, expirationTime, callback);
12641}
12642
12643
12644
12645
12646
12647var overrideProps = null;
12648
12649{
12650 var copyWithSetImpl = function (obj, path, idx, value) {
12651 if (idx >= path.length) {
12652 return value;
12653 }
12654 var key = path[idx];
12655 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj);
12656 // $FlowFixMe number or string is fine here
12657 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
12658 return updated;
12659 };
12660
12661 var copyWithSet = function (obj, path, value) {
12662 return copyWithSetImpl(obj, path, 0, value);
12663 };
12664
12665 // Support DevTools props for function components, forwardRef, memo, host components, etc.
12666 overrideProps = function (fiber, path, value) {
12667 flushPassiveEffects();
12668 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
12669 if (fiber.alternate) {
12670 fiber.alternate.pendingProps = fiber.pendingProps;
12671 }
12672 scheduleWork(fiber, Sync);
12673 };
12674}
12675
12676function injectIntoDevTools(devToolsConfig) {
12677 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
12678 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
12679
12680
12681 return injectInternals(_assign({}, devToolsConfig, {
12682 overrideProps: overrideProps,
12683 currentDispatcherRef: ReactCurrentDispatcher,
12684 findHostInstanceByFiber: function (fiber) {
12685 var hostFiber = findCurrentHostFiber(fiber);
12686 if (hostFiber === null) {
12687 return null;
12688 }
12689 return hostFiber.stateNode;
12690 },
12691 findFiberByHostInstance: function (instance) {
12692 if (!findFiberByHostInstance) {
12693 // Might not be implemented by the renderer.
12694 return null;
12695 }
12696 return findFiberByHostInstance(instance);
12697 }
12698 }));
12699}
12700
12701// This file intentionally does *not* have the Flow annotation.
12702// Don't add it. See `./inline-typed.js` for an explanation.
12703
12704var container = _class({
12705
12706 grab: function(){
12707 for (var i = 0; i < arguments.length; i++) arguments[i].inject(this);
12708 return this;
12709 },
12710
12711 empty: function(){
12712 var node;
12713 while (node = this.firstChild) node.eject();
12714 return this;
12715 }
12716
12717});
12718
12719function elementFrom(node){
12720 if (node.toElement) return node.toElement();
12721 if (node.getDOMNode) return node.getDOMNode();
12722 if (node.getNode) return node.getNode();
12723 return node;
12724}
12725
12726var native_1 = _class({
12727
12728 // conventions
12729
12730 toElement: function(){
12731 return this.element;
12732 },
12733
12734 getDOMNode: function(){
12735 return this.toElement();
12736 },
12737
12738 getNode: function(){
12739 return this.toElement();
12740 },
12741
12742 // placement
12743
12744 inject: function(container){
12745 (container.containerElement || elementFrom(container))
12746 .appendChild(this.element);
12747 return this;
12748 },
12749
12750 injectBefore: function(sibling){
12751 var element = elementFrom(sibling);
12752 element.parentNode.insertBefore(this.element, element);
12753 return this;
12754 },
12755
12756 eject: function(){
12757 var element = this.element, parent = element.parentNode;
12758 if (parent) parent.removeChild(element); // TODO: VML Nodes are dead after being ejected
12759 return this;
12760 },
12761
12762 // events
12763
12764 subscribe: function(type, fn, bind){
12765 if (typeof type != 'string'){ // listen type / fn with object
12766 var subscriptions = [];
12767 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
12768 return function(){ // unsubscribe
12769 for (var i = 0, l = subscriptions.length; i < l; i++)
12770 subscriptions[i]();
12771 return this;
12772 };
12773 } else { // listen to one
12774 if (!bind) bind = this;
12775 var bound;
12776 if (typeof fn === 'function'){
12777 bound = fn.bind ? fn.bind(bind)
12778 : function(){ return fn.apply(bind, arguments); };
12779 } else {
12780 bound = fn;
12781 }
12782 var element = this.element;
12783 if (element.addEventListener){
12784 element.addEventListener(type, bound, false);
12785 return function(){ // unsubscribe
12786 element.removeEventListener(type, bound, false);
12787 return this;
12788 };
12789 } else {
12790 element.attachEvent('on' + type, bound);
12791 return function(){ // unsubscribe
12792 element.detachEvent('on' + type, bound);
12793 return this;
12794 };
12795 }
12796 }
12797 }
12798
12799});
12800
12801var fps = 1000 / 60;
12802var invalids = [];
12803var renderTimer;
12804var renderInvalids = function(){
12805 clearTimeout(renderTimer);
12806 renderTimer = null;
12807 var canvases = invalids;
12808 invalids = [];
12809 for (var i = 0, l = canvases.length; i < l; i++){
12810 var c = canvases[i];
12811 c._valid = true;
12812 c.render();
12813 }
12814};
12815
12816var resolution = typeof window !== 'undefined' && window.devicePixelRatio || 1;
12817
12818var previousHit = null;
12819var previousHitSurface = null;
12820
12821var CanvasSurface = _class(native_1, container, {
12822
12823 initialize: function(width, height, existingElement){
12824 var element = this.element = existingElement || document.createElement('canvas');
12825 var context = this.context = element.getContext('2d');
12826 this._valid = true;
12827 if (width != null && height != null) this.resize(width, height);
12828
12829 element.addEventListener('mousemove', this, false);
12830 element.addEventListener('mouseout', this, false);
12831 element.addEventListener('mouseover', this, false);
12832 element.addEventListener('mouseup', this, false);
12833 element.addEventListener('mousedown', this, false);
12834 element.addEventListener('click', this, false);
12835 },
12836
12837 handleEvent: function(event){
12838 if (event.clientX == null) return;
12839 var element = this.element,
12840 rect = element.getBoundingClientRect(),
12841 x = event.clientX - rect.left - element.clientLeft,
12842 y = event.clientY - rect.top - element.clientTop,
12843 hit = this.hitTest(x, y);
12844
12845 if (hit !== previousHit){
12846 if (previousHit){
12847 previousHit.dispatch({
12848 type: 'mouseout',
12849 target: previousHit,
12850 relatedTarget: hit,
12851 sourceEvent: event
12852 });
12853 }
12854 if (hit){
12855 hit.dispatch({
12856 type: 'mouseover',
12857 target: hit,
12858 relatedTarget: previousHit,
12859 sourceEvent: event
12860 });
12861 }
12862 previousHit = hit;
12863 previousHitSurface = this;
12864 this.refreshCursor();
12865 }
12866
12867 if (hit) hit.dispatch(event);
12868 },
12869
12870 refreshCursor: function(){
12871 if (previousHitSurface !== this) return;
12872 var hit = previousHit, hitCursor = '', hitTooltip = '';
12873 while (hit){
12874 if (!hitCursor && hit._cursor){
12875 hitCursor = hit._cursor;
12876 if (hitTooltip) break;
12877 }
12878 if (!hitTooltip && hit._tooltip){
12879 hitTooltip = hit._tooltip;
12880 if (hitCursor) break;
12881 }
12882 hit = hit.parentNode;
12883 }
12884 // TODO: No way to set cursor/title on the surface
12885 this.element.style.cursor = hitCursor;
12886 this.element.title = hitTooltip;
12887 },
12888
12889 resize: function(width, height){
12890 var element = this.element;
12891 element.setAttribute('width', width * resolution);
12892 element.setAttribute('height', height * resolution);
12893 element.style.width = width + 'px';
12894 element.style.height = height + 'px';
12895 this.width = width;
12896 this.height = height;
12897 return this;
12898 },
12899
12900 invalidate: function(left, top, width, height){
12901 if (this._valid){
12902 this._valid = false;
12903 invalids.push(this);
12904 if (!renderTimer){
12905 if (window.mozRequestAnimationFrame){
12906 renderTimer = true;
12907 window.mozRequestAnimationFrame(renderInvalids);
12908 } else {
12909 renderTimer = setTimeout(renderInvalids, fps);
12910 }
12911 }
12912 }
12913 return this;
12914 },
12915
12916 hitTest: function(x, y){
12917 if (x < 0 || y < 0 || x > this.width || y > this.height) return null;
12918 var node = this.lastChild;
12919 while (node){
12920 var hit = node.hitTest(x, y);
12921 if (hit) return hit;
12922 node = node.previousSibling;
12923 }
12924 return null;
12925 },
12926
12927 render: function(){
12928 var node = this.firstChild, context = this.context;
12929 context.setTransform(resolution, 0, 0, resolution, 0, 0);
12930 context.clearRect(0, 0, this.width, this.height);
12931 while (node){
12932 node.renderTo(context, resolution, 0, 0, resolution, 0, 0);
12933 node = node.nextSibling;
12934 }
12935 this.refreshCursor();
12936 }
12937
12938});
12939
12940CanvasSurface.tagName = 'canvas';
12941
12942var surface = CanvasSurface;
12943
12944var path$2 = _class({
12945
12946 initialize: function(path){
12947 this.reset().push(path);
12948 },
12949
12950 /* parser */
12951
12952 push: function(){
12953 var p = Array.prototype.join.call(arguments, ' ')
12954 .match(/[a-df-z]|[\-+]?(?:[\d\.]e[\-+]?|[^\s\-+,a-z])+/ig);
12955 if (!p) return this;
12956
12957 var last, cmd = p[0], i = 1;
12958 while (cmd){
12959 switch (cmd){
12960 case 'm': this.move(p[i++], p[i++]); break;
12961 case 'l': this.line(p[i++], p[i++]); break;
12962 case 'c': this.curve(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
12963 case 's': this.curve(p[i++], p[i++], null, null, p[i++], p[i++]); break;
12964 case 'q': this.curve(p[i++], p[i++], p[i++], p[i++]); break;
12965 case 't': this.curve(p[i++], p[i++]); break;
12966 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;
12967 case 'h': this.line(p[i++], 0); break;
12968 case 'v': this.line(0, p[i++]); break;
12969
12970 case 'M': this.moveTo(p[i++], p[i++]); break;
12971 case 'L': this.lineTo(p[i++], p[i++]); break;
12972 case 'C': this.curveTo(p[i++], p[i++], p[i++], p[i++], p[i++], p[i++]); break;
12973 case 'S': this.curveTo(p[i++], p[i++], null, null, p[i++], p[i++]); break;
12974 case 'Q': this.curveTo(p[i++], p[i++], p[i++], p[i++]); break;
12975 case 'T': this.curveTo(p[i++], p[i++]); break;
12976 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;
12977 case 'H': this.lineTo(p[i++], this.penY); break;
12978 case 'V': this.lineTo(this.penX, p[i++]); break;
12979
12980 case 'Z': case 'z': this.close(); break;
12981 default: cmd = last; i--; continue;
12982 }
12983
12984 last = cmd;
12985 if (last == 'm') last = 'l';
12986 else if (last == 'M') last = 'L';
12987 cmd = p[i++];
12988 }
12989 return this;
12990 },
12991
12992 /* utility methods */
12993
12994 reset: function(){
12995 this.penX = this.penY = 0;
12996 this.penDownX = this.penDownY = null;
12997 this._pivotX = this._pivotY = 0;
12998 this.onReset();
12999 return this;
13000 },
13001
13002 move: function(x,y){
13003 this.onMove(this.penX, this.penY, this._pivotX = this.penX += (+x), this._pivotY = this.penY += (+y));
13004 return this;
13005 },
13006 moveTo: function(x,y){
13007 this.onMove(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13008 return this;
13009 },
13010
13011 line: function(x,y){
13012 return this.lineTo(this.penX + (+x), this.penY + (+y));
13013 },
13014 lineTo: function(x,y){
13015 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13016 this.onLine(this.penX, this.penY, this._pivotX = this.penX = (+x), this._pivotY = this.penY = (+y));
13017 return this;
13018 },
13019
13020 curve: function(c1x, c1y, c2x, c2y, ex, ey){
13021 var x = this.penX, y = this.penY;
13022 return this.curveTo(
13023 x + (+c1x), y + (+c1y),
13024 c2x == null ? null : x + (+c2x),
13025 c2y == null ? null : y + (+c2y),
13026 ex == null ? null : x + (+ex),
13027 ey == null ? null : y + (+ey)
13028 );
13029 },
13030 curveTo: function(c1x, c1y, c2x, c2y, ex, ey){
13031 var x = this.penX, y = this.penY;
13032 if (c2x == null){
13033 c2x = +c1x; c2y = +c1y;
13034 c1x = (x * 2) - (this._pivotX || 0); c1y = (y * 2) - (this._pivotY || 0);
13035 }
13036 if (ex == null){
13037 this._pivotX = +c1x; this._pivotY = +c1y;
13038 ex = +c2x; ey = +c2y;
13039 c2x = (ex + (+c1x) * 2) / 3; c2y = (ey + (+c1y) * 2) / 3;
13040 c1x = (x + (+c1x) * 2) / 3; c1y = (y + (+c1y) * 2) / 3;
13041 } else {
13042 this._pivotX = +c2x; this._pivotY = +c2y;
13043 }
13044 if (this.penDownX == null){ this.penDownX = x; this.penDownY = y; }
13045 this.onBezierCurve(x, y, +c1x, +c1y, +c2x, +c2y, this.penX = +ex, this.penY = +ey);
13046 return this;
13047 },
13048
13049 arc: function(x, y, rx, ry, outer, counterClockwise, rotation){
13050 return this.arcTo(this.penX + (+x), this.penY + (+y), rx, ry, outer, counterClockwise, rotation);
13051 },
13052 arcTo: function(x, y, rx, ry, outer, counterClockwise, rotation){
13053 ry = Math.abs(+ry || +rx || (+y - this.penY));
13054 rx = Math.abs(+rx || (+x - this.penX));
13055
13056 if (!rx || !ry || (x == this.penX && y == this.penY)) return this.lineTo(x, y);
13057
13058 var tX = this.penX, tY = this.penY, clockwise = !+counterClockwise, large = !!+outer;
13059
13060 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad);
13061 x -= tX; y -= tY;
13062
13063 // Ellipse Center
13064 var cx = cos * x / 2 + sin * y / 2,
13065 cy = -sin * x / 2 + cos * y / 2,
13066 rxry = rx * rx * ry * ry,
13067 rycx = ry * ry * cx * cx,
13068 rxcy = rx * rx * cy * cy,
13069 a = rxry - rxcy - rycx;
13070
13071 if (a < 0){
13072 a = Math.sqrt(1 - a / rxry);
13073 rx *= a; ry *= a;
13074 cx = x / 2; cy = y / 2;
13075 } else {
13076 a = Math.sqrt(a / (rxcy + rycx));
13077 if (large == clockwise) a = -a;
13078 var cxd = -a * cy * rx / ry,
13079 cyd = a * cx * ry / rx;
13080 cx = cos * cxd - sin * cyd + x / 2;
13081 cy = sin * cxd + cos * cyd + y / 2;
13082 }
13083
13084 // Rotation + Scale Transform
13085 var xx = cos / rx, yx = sin / rx,
13086 xy = -sin / ry, yy = cos / ry;
13087
13088 // Start and End Angle
13089 var sa = Math.atan2(xy * -cx + yy * -cy, xx * -cx + yx * -cy),
13090 ea = Math.atan2(xy * (x - cx) + yy * (y - cy), xx * (x - cx) + yx * (y - cy));
13091
13092 cx += tX; cy += tY;
13093 x += tX; y += tY;
13094
13095 // Circular Arc
13096 if (this.penDownX == null){ this.penDownX = this.penX; this.penDownY = this.penY; }
13097 this.onArc(
13098 tX, tY, this._pivotX = this.penX = x, this._pivotY = this.penY = y,
13099 cx, cy, rx, ry, sa, ea, !clockwise, rotation
13100 );
13101 return this;
13102 },
13103
13104 counterArc: function(x, y, rx, ry, outer){
13105 return this.arc(x, y, rx, ry, outer, true);
13106 },
13107 counterArcTo: function(x, y, rx, ry, outer){
13108 return this.arcTo(x, y, rx, ry, outer, true);
13109 },
13110
13111 close: function(){
13112 if (this.penDownX != null){
13113 this.onClose(this.penX, this.penY, this.penX = this.penDownX, this.penY = this.penDownY);
13114 this.penDownX = null;
13115 }
13116 return this;
13117 },
13118
13119 /* overridable handlers */
13120
13121 onReset: function(){
13122 },
13123
13124 onMove: function(sx, sy, ex, ey){
13125 },
13126
13127 onLine: function(sx, sy, ex, ey){
13128 this.onBezierCurve(sx, sy, sx, sy, ex, ey, ex, ey);
13129 },
13130
13131 onBezierCurve: function(sx, sy, c1x, c1y, c2x, c2y, ex, ey){
13132 var gx = ex - sx, gy = ey - sy,
13133 g = gx * gx + gy * gy,
13134 v1, v2, cx, cy, u;
13135
13136 cx = c1x - sx; cy = c1y - sy;
13137 u = cx * gx + cy * gy;
13138
13139 if (u > g){
13140 cx -= gx;
13141 cy -= gy;
13142 } else if (u > 0 && g != 0){
13143 cx -= u/g * gx;
13144 cy -= u/g * gy;
13145 }
13146
13147 v1 = cx * cx + cy * cy;
13148
13149 cx = c2x - sx; cy = c2y - sy;
13150 u = cx * gx + cy * gy;
13151
13152 if (u > g){
13153 cx -= gx;
13154 cy -= gy;
13155 } else if (u > 0 && g != 0){
13156 cx -= u/g * gx;
13157 cy -= u/g * gy;
13158 }
13159
13160 v2 = cx * cx + cy * cy;
13161
13162 if (v1 < 0.01 && v2 < 0.01){
13163 this.onLine(sx, sy, ex, ey);
13164 return;
13165 }
13166
13167 // Avoid infinite recursion
13168 if (isNaN(v1) || isNaN(v2)){
13169 throw new Error('Bad input');
13170 }
13171
13172 // Split curve
13173 var s1x = (c1x + c2x) * 0.5, s1y = (c1y + c2y) * 0.5,
13174 l1x = (c1x + sx) * 0.5, l1y = (c1y + sy) * 0.5,
13175 l2x = (l1x + s1x) * 0.5, l2y = (l1y + s1y) * 0.5,
13176 r2x = (ex + c2x) * 0.5, r2y = (ey + c2y) * 0.5,
13177 r1x = (r2x + s1x) * 0.5, r1y = (r2y + s1y) * 0.5,
13178 l2r1x = (l2x + r1x) * 0.5, l2r1y = (l2y + r1y) * 0.5;
13179
13180 // TODO: Manual stack if necessary. Currently recursive without tail optimization.
13181 this.onBezierCurve(sx, sy, l1x, l1y, l2x, l2y, l2r1x, l2r1y);
13182 this.onBezierCurve(l2r1x, l2r1y, r1x, r1y, r2x, r2y, ex, ey);
13183 },
13184
13185 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13186 // Inverse Rotation + Scale Transform
13187 var rad = rotation ? rotation * Math.PI / 180 : 0, cos = Math.cos(rad), sin = Math.sin(rad),
13188 xx = cos * rx, yx = -sin * ry,
13189 xy = sin * rx, yy = cos * ry;
13190
13191 // Bezier Curve Approximation
13192 var arc = ea - sa;
13193 if (arc < 0 && !ccw) arc += Math.PI * 2;
13194 else if (arc > 0 && ccw) arc -= Math.PI * 2;
13195
13196 var n = Math.ceil(Math.abs(arc / (Math.PI / 2))),
13197 step = arc / n,
13198 k = (4 / 3) * Math.tan(step / 4);
13199
13200 var x = Math.cos(sa), y = Math.sin(sa);
13201
13202 for (var i = 0; i < n; i++){
13203 var cp1x = x - k * y, cp1y = y + k * x;
13204
13205 sa += step;
13206 x = Math.cos(sa); y = Math.sin(sa);
13207
13208 var cp2x = x + k * y, cp2y = y - k * x;
13209
13210 this.onBezierCurve(
13211 sx, sy,
13212 cx + xx * cp1x + yx * cp1y, cy + xy * cp1x + yy * cp1y,
13213 cx + xx * cp2x + yx * cp2y, cy + xy * cp2x + yy * cp2y,
13214 (sx = (cx + xx * x + yx * y)), (sy = (cy + xy * x + yy * y))
13215 );
13216 }
13217 },
13218
13219 onClose: function(sx, sy, ex, ey){
13220 this.onLine(sx, sy, ex, ey);
13221 }
13222
13223});
13224
13225var CanvasPath = _class(path$2, {
13226
13227 initialize: function(path){
13228 this.reset();
13229 if (path instanceof CanvasPath){
13230 this.path = path.path.slice(0);
13231 } else if (path){
13232 if (path.applyToPath)
13233 path.applyToPath(this);
13234 else
13235 this.push(path);
13236 }
13237 },
13238
13239 onReset: function(){
13240 this.path = [];
13241 },
13242
13243 onMove: function(sx, sy, x, y){
13244 this.path.push(function(context){
13245 context.moveTo(x, y);
13246 });
13247 },
13248
13249 onLine: function(sx, sy, x, y){
13250 this.path.push(function(context){
13251 context.lineTo(x, y);
13252 });
13253 },
13254
13255 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
13256 this.path.push(function(context){
13257 context.bezierCurveTo(p1x, p1y, p2x, p2y, x, y);
13258 });
13259 },
13260
13261 _arcToBezier: path$2.prototype.onArc,
13262
13263 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
13264 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
13265 this.path.push(function(context){
13266 context.arc(cx, cy, rx, sa, ea, ccw);
13267 });
13268 },
13269
13270 onClose: function(){
13271 this.path.push(function(context){
13272 context.closePath();
13273 });
13274 },
13275
13276 toCommands: function(){
13277 return this.path.slice(0);
13278 }
13279
13280});
13281
13282var path = CanvasPath;
13283
13284var colors = {
13285 maroon: '#800000', red: '#ff0000', orange: '#ffA500', yellow: '#ffff00', olive: '#808000',
13286 purple: '#800080', fuchsia: "#ff00ff", white: '#ffffff', lime: '#00ff00', green: '#008000',
13287 navy: '#000080', blue: '#0000ff', aqua: '#00ffff', teal: '#008080',
13288 black: '#000000', silver: '#c0c0c0', gray: '#808080'
13289};
13290
13291var map = function(array, fn){
13292 var results = [];
13293 for (var i = 0, l = array.length; i < l; i++)
13294 results[i] = fn(array[i], i);
13295 return results;
13296};
13297
13298var Color = function(color, type){
13299
13300 if (color.isColor){
13301
13302 this.red = color.red;
13303 this.green = color.green;
13304 this.blue = color.blue;
13305 this.alpha = color.alpha;
13306
13307 } else {
13308
13309 var namedColor = colors[color];
13310 if (namedColor){
13311 color = namedColor;
13312 type = 'hex';
13313 }
13314
13315 switch (typeof color){
13316 case 'string': if (!type) type = (type = color.match(/^rgb|^hsb|^hsl/)) ? type[0] : 'hex'; break;
13317 case 'object': type = type || 'rgb'; color = color.toString(); break;
13318 case 'number': type = 'hex'; color = color.toString(16); break;
13319 }
13320
13321 color = Color['parse' + type.toUpperCase()](color);
13322 this.red = color[0];
13323 this.green = color[1];
13324 this.blue = color[2];
13325 this.alpha = color[3];
13326 }
13327
13328 this.isColor = true;
13329
13330};
13331
13332var limit = function(number, min, max){
13333 return Math.min(max, Math.max(min, number));
13334};
13335
13336var listMatch = /([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,\s*([-.\d]+\%?)\s*,?\s*([-.\d]*\%?)/;
13337var hexMatch = /^#?([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{1,2})([a-f0-9]{0,2})$/i;
13338
13339Color.parseRGB = function(color){
13340 return map(color.match(listMatch).slice(1), function(bit, i){
13341 if (bit) bit = parseFloat(bit) * (bit[bit.length - 1] == '%' ? 2.55 : 1);
13342 return (i < 3) ? Math.round(((bit %= 256) < 0) ? bit + 256 : bit) : limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13343 });
13344};
13345
13346Color.parseHEX = function(color){
13347 if (color.length == 1) color = color + color + color;
13348 return map(color.match(hexMatch).slice(1), function(bit, i){
13349 if (i == 3) return (bit) ? parseInt(bit, 16) / 255 : 1;
13350 return parseInt((bit.length == 1) ? bit + bit : bit, 16);
13351 });
13352};
13353
13354Color.parseHSB = function(color){
13355 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13356 if (bit) bit = parseFloat(bit);
13357 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13358 else if (i < 3) return limit(Math.round(bit), 0, 100);
13359 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13360 });
13361
13362 var a = hsb[3];
13363 var br = Math.round(hsb[2] / 100 * 255);
13364 if (hsb[1] == 0) return [br, br, br, a];
13365
13366 var hue = hsb[0];
13367 var f = hue % 60;
13368 var p = Math.round((hsb[2] * (100 - hsb[1])) / 10000 * 255);
13369 var q = Math.round((hsb[2] * (6000 - hsb[1] * f)) / 600000 * 255);
13370 var t = Math.round((hsb[2] * (6000 - hsb[1] * (60 - f))) / 600000 * 255);
13371
13372 switch (Math.floor(hue / 60)){
13373 case 0: return [br, t, p, a];
13374 case 1: return [q, br, p, a];
13375 case 2: return [p, br, t, a];
13376 case 3: return [p, q, br, a];
13377 case 4: return [t, p, br, a];
13378 default: return [br, p, q, a];
13379 }
13380};
13381
13382Color.parseHSL = function(color){
13383 var hsb = map(color.match(listMatch).slice(1), function(bit, i){
13384 if (bit) bit = parseFloat(bit);
13385 if (i === 0) return Math.round(((bit %= 360) < 0) ? (bit + 360) : bit);
13386 else if (i < 3) return limit(Math.round(bit), 0, 100);
13387 else return limit(((bit === '') ? 1 : Number(bit)), 0, 1);
13388 });
13389
13390 var h = hsb[0] / 60;
13391 var s = hsb[1] / 100;
13392 var l = hsb[2] / 100;
13393 var a = hsb[3];
13394
13395 var c = (1 - Math.abs(2 * l - 1)) * s;
13396 var x = c * (1 - Math.abs(h % 2 - 1));
13397 var m = l - c / 2;
13398
13399 var p = Math.round((c + m) * 255);
13400 var q = Math.round((x + m) * 255);
13401 var t = Math.round((m) * 255);
13402
13403 switch (Math.floor(h)){
13404 case 0: return [p, q, t, a];
13405 case 1: return [q, p, t, a];
13406 case 2: return [t, p, q, a];
13407 case 3: return [t, q, p, a];
13408 case 4: return [q, t, p, a];
13409 default: return [p, t, q, a];
13410 }
13411};
13412
13413var toString = function(type, array){
13414 if (array[3] != 1) type += 'a';
13415 else array.pop();
13416 return type + '(' + array.join(', ') + ')';
13417};
13418
13419Color.prototype = {
13420
13421 toHSB: function(array){
13422 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13423
13424 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13425 var hue = 0, saturation = (delta != 0) ? delta / max : 0, brightness = max / 255;
13426 if (saturation){
13427 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13428 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13429 if ((hue /= 6) < 0) hue++;
13430 }
13431
13432 var hsb = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100), alpha];
13433
13434 return (array) ? hsb : toString('hsb', hsb);
13435 },
13436
13437 toHSL: function(array){
13438 var red = this.red, green = this.green, blue = this.blue, alpha = this.alpha;
13439
13440 var max = Math.max(red, green, blue), min = Math.min(red, green, blue), delta = max - min;
13441 var hue = 0, saturation = (delta != 0) ? delta / (255 - Math.abs((max + min) - 255)) : 0, lightness = (max + min) / 512;
13442 if (saturation){
13443 var rr = (max - red) / delta, gr = (max - green) / delta, br = (max - blue) / delta;
13444 hue = (red == max) ? br - gr : (green == max) ? 2 + rr - br : 4 + gr - rr;
13445 if ((hue /= 6) < 0) hue++;
13446 }
13447
13448 var hsl = [Math.round(hue * 360), Math.round(saturation * 100), Math.round(lightness * 100), alpha];
13449
13450 return (array) ? hsl : toString('hsl', hsl);
13451 },
13452
13453 toHEX: function(array){
13454
13455 var a = this.alpha;
13456 var alpha = ((a = Math.round((a * 255)).toString(16)).length == 1) ? a + a : a;
13457
13458 var hex = map([this.red, this.green, this.blue], function(bit){
13459 bit = bit.toString(16);
13460 return (bit.length == 1) ? '0' + bit : bit;
13461 });
13462
13463 return (array) ? hex.concat(alpha) : '#' + hex.join('') + ((alpha == 'ff') ? '' : alpha);
13464 },
13465
13466 toRGB: function(array){
13467 var rgb = [this.red, this.green, this.blue, this.alpha];
13468 return (array) ? rgb : toString('rgb', rgb);
13469 }
13470
13471};
13472
13473Color.prototype.toString = Color.prototype.toRGB;
13474
13475Color.hex = function(hex){
13476 return new Color(hex, 'hex');
13477};
13478
13479if (commonjsGlobal.hex == null) commonjsGlobal.hex = Color.hex;
13480
13481Color.hsb = function(h, s, b, a){
13482 return new Color([h || 0, s || 0, b || 0, (a == null) ? 1 : a], 'hsb');
13483};
13484
13485if (commonjsGlobal.hsb == null) commonjsGlobal.hsb = Color.hsb;
13486
13487Color.hsl = function(h, s, l, a){
13488 return new Color([h || 0, s || 0, l || 0, (a == null) ? 1 : a], 'hsl');
13489};
13490
13491if (commonjsGlobal.hsl == null) commonjsGlobal.hsl = Color.hsl;
13492
13493Color.rgb = function(r, g, b, a){
13494 return new Color([r || 0, g || 0, b || 0, (a == null) ? 1 : a], 'rgb');
13495};
13496
13497if (commonjsGlobal.rgb == null) commonjsGlobal.rgb = Color.rgb;
13498
13499Color.detach = function(color){
13500 color = new Color(color);
13501 return [Color.rgb(color.red, color.green, color.blue).toString(), color.alpha];
13502};
13503
13504var color = Color;
13505
13506var dummy = _class({
13507
13508 // placement
13509
13510 _resetPlacement: function(){
13511 var container = this.parentNode;
13512 if (container){
13513 var previous = this.previousSibling, next = this.nextSibling;
13514 if (previous){
13515 previous.nextSibling = next;
13516 } else {
13517 container.firstChild = next;
13518 }
13519 if (next){
13520 next.previousSibling = previous;
13521 } else {
13522 container.lastChild = this.previousSibling;
13523 }
13524 }
13525 this.previousSibling = null;
13526 this.nextSibling = null;
13527 this.parentNode = null;
13528 return this;
13529 },
13530
13531 inject: function(container){
13532 this._resetPlacement();
13533 var last = container.lastChild;
13534 if (last){
13535 last.nextSibling = this;
13536 this.previousSibling = last;
13537 } else {
13538 container.firstChild = this;
13539 }
13540 container.lastChild = this;
13541 this.parentNode = container;
13542 this._place();
13543 return this;
13544 },
13545
13546 injectBefore: function(sibling){
13547 this._resetPlacement();
13548 var container = sibling.parentNode;
13549 if (!container) return this;
13550 var previous = sibling.previousSibling;
13551 if (previous){
13552 previous.nextSibling = this;
13553 this.previousSibling = previous;
13554 } else {
13555 container.firstChild = this;
13556 }
13557 sibling.previousSibling = this;
13558 this.nextSibling = sibling;
13559 this.parentNode = container;
13560 this._place();
13561 return this;
13562 },
13563
13564 eject: function(){
13565 this._resetPlacement();
13566 this._place();
13567 return this;
13568 },
13569
13570 _place: function(){},
13571
13572 // events
13573
13574 dispatch: function(event){
13575 var events = this._events,
13576 listeners = events && events[event.type];
13577 if (listeners){
13578 listeners = listeners.slice(0);
13579 for (var i = 0, l = listeners.length; i < l; i++){
13580 var fn = listeners[i], result;
13581 if (typeof fn == 'function')
13582 result = fn.call(this, event);
13583 else
13584 result = fn.handleEvent(event);
13585 if (result === false) event.preventDefault();
13586 }
13587 }
13588 if (this.parentNode && this.parentNode.dispatch){
13589 this.parentNode.dispatch(event);
13590 }
13591 },
13592
13593 subscribe: function(type, fn, bind){
13594 if (typeof type != 'string'){ // listen type / fn with object
13595 var subscriptions = [];
13596 for (var t in type) subscriptions.push(this.subscribe(t, type[t]));
13597 return function(){ // unsubscribe
13598 for (var i = 0, l = subscriptions.length; i < l; i++)
13599 subscriptions[i]();
13600 return this;
13601 };
13602 } else { // listen to one
13603 var bound = typeof fn === 'function' ? fn.bind(bind || this) : fn,
13604 events = this._events || (this._events = {}),
13605 listeners = events[type] || (events[type] = []);
13606 listeners.push(bound);
13607 return function(){
13608 // unsubscribe
13609 for (var i = 0, l = listeners.length; i < l; i++){
13610 if (listeners[i] === bound){
13611 listeners.splice(i, 1);
13612 break;
13613 }
13614 }
13615 }
13616 }
13617 }
13618
13619});
13620
13621var CanvasNode = _class(transform, dummy, {
13622
13623 invalidate: function(){
13624 if (this.parentNode) this.parentNode.invalidate();
13625 if (this._layer) this._layerCache = null;
13626 return this;
13627 },
13628
13629 _place: function(){
13630 this.invalidate();
13631 },
13632
13633 _transform: function(){
13634 this.invalidate();
13635 },
13636
13637 blend: function(opacity){
13638 if (opacity >= 1 && this._layer) this._layer = null;
13639 this._opacity = opacity;
13640 if (this.parentNode) this.parentNode.invalidate();
13641 return this;
13642 },
13643
13644 // visibility
13645
13646 hide: function(){
13647 this._invisible = true;
13648 if (this.parentNode) this.parentNode.invalidate();
13649 return this;
13650 },
13651
13652 show: function(){
13653 this._invisible = false;
13654 if (this.parentNode) this.parentNode.invalidate();
13655 return this;
13656 },
13657
13658 // interaction
13659
13660 indicate: function(cursor, tooltip){
13661 this._cursor = cursor;
13662 this._tooltip = tooltip;
13663 return this.invalidate();
13664 },
13665
13666 hitTest: function(x, y){
13667 if (this._invisible) return null;
13668 var point = this.inversePoint(x, y);
13669 if (!point) return null;
13670 return this.localHitTest(point.x, point.y);
13671 },
13672
13673 // rendering
13674
13675 renderTo: function(context, xx, yx, xy, yy, x, y){
13676 var opacity = this._opacity;
13677 if (opacity == null || opacity >= 1){
13678 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
13679 }
13680
13681 // Render to a compositing layer and cache it
13682
13683 var layer = this._layer, canvas, isDirty = true,
13684 w = context.canvas.width, h = context.canvas.height;
13685 if (layer){
13686 layer.setTransform(1, 0, 0, 1, 0, 0);
13687 canvas = layer.canvas;
13688 if (canvas.width < w || canvas.height < h){
13689 canvas.width = w;
13690 canvas.height = h;
13691 } else {
13692 var c = this._layerCache;
13693 if (c && c.xx === xx && c.yx === yx && c.xy === xy
13694 && c.yy === yy && c.x === x && c.y === y){
13695 isDirty = false;
13696 } else {
13697 layer.clearRect(0, 0, w, h);
13698 }
13699 }
13700 } else {
13701 canvas = document.createElement('canvas');
13702 canvas.width = w;
13703 canvas.height = h;
13704 this._layer = layer = canvas.getContext('2d');
13705 }
13706
13707 if (isDirty){
13708 this.renderLayerTo(layer, xx, yx, xy, yy, x, y);
13709 this._layerCache = {
13710 xx: xx,
13711 yx: yx,
13712 xy: xy,
13713 yy: yy,
13714 x: x,
13715 y: y
13716 };
13717 }
13718
13719 context.globalAlpha = opacity;
13720 context.setTransform(1, 0, 0, 1, 0, 0);
13721 context.drawImage(
13722 canvas,
13723 0, 0, w, h,
13724 0, 0, w, h
13725 );
13726 context.globalAlpha = 1;
13727 }
13728
13729});
13730
13731var node = CanvasNode;
13732
13733var genericCanvas = typeof document !== 'undefined' && document.createElement('canvas');
13734var genericContext = genericCanvas && genericCanvas.getContext && genericCanvas.getContext('2d');
13735
13736function recolorImage(img, color1, color2){
13737 // TODO: Fix this experimental implementation
13738 color1 = color.detach(color1);
13739 color2 = color.detach(color2);
13740 var canvas = document.createElement('canvas'),
13741 context = canvas.getContext('2d');
13742 canvas.width = img.width;
13743 canvas.height = img.height;
13744 context.fillStyle = color2[0];
13745 context.fillRect(0, 0, img.width, img.height);
13746 context.globalCompositeOperation = 'lighter';
13747 context.drawImage(img, 0, 0);
13748 return canvas;
13749}
13750
13751var Base = _class(node, {
13752
13753 initialize: function(){
13754 this._fill = null;
13755 this._pendingFill = null;
13756 this._fillTransform = null;
13757 this._stroke = null;
13758 this._strokeCap = null;
13759 this._strokeDash = null;
13760 this._strokeJoin = null;
13761 this._strokeWidth = null;
13762 },
13763
13764 /* styles */
13765
13766 _addColors: function(gradient, stops){
13767 // Enumerate stops, assumes offsets are enumerated in order
13768 // TODO: Sort. Chrome doesn't always enumerate in expected order but requires stops to be specified in order.
13769 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++)
13770 gradient.addColorStop(i / l, new color(stops[i]).toString());
13771 else for (var offset in stops)
13772 gradient.addColorStop(offset, new color(stops[offset]).toString());
13773 return gradient;
13774 },
13775
13776
13777 fill: function(color$$1){
13778 if (arguments.length > 1) return this.fillLinear(arguments);
13779 if (this._pendingFill) this._pendingFill();
13780 this._fill = color$$1 ? new color(color$$1).toString() : null;
13781 return this.invalidate();
13782 },
13783
13784 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
13785 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
13786 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
13787 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
13788 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
13789 if (centerX == null) centerX = focusX;
13790 if (centerY == null) centerY = focusY;
13791
13792 centerX += centerX - focusX;
13793 centerY += centerY - focusY;
13794
13795 if (radiusX === 0 || radiusX === '0') return this.fillLinear(stops);
13796 var ys = radiusY / radiusX;
13797
13798 if (this._pendingFill) this._pendingFill();
13799
13800 var gradient = genericContext.createRadialGradient(focusX, focusY / ys, 0, centerX, centerY / ys, radiusX * 2);
13801
13802 // Double fill radius to simulate repeating gradient
13803 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++){
13804 gradient.addColorStop(i / l / 2, new color(stops[i]).toString());
13805 gradient.addColorStop(1 - i / l / 2, new color(stops[i]).toString());
13806 } else for (var offset in stops){
13807 gradient.addColorStop(offset / 2, new color(stops[offset]).toString());
13808 gradient.addColorStop(1- offset / 2, new color(stops[offset]).toString());
13809 }
13810
13811 this._fill = gradient;
13812 this._fillTransform = new transform(1, 0, 0, ys);
13813 return this.invalidate();
13814 },
13815
13816 fillLinear: function(stops, x1, y1, x2, y2){
13817 if (arguments.length < 5){
13818 var angle = ((x1 == null) ? 270 : x1) * Math.PI / 180;
13819
13820 var x = Math.cos(angle), y = -Math.sin(angle),
13821 l = (Math.abs(x) + Math.abs(y)) / 2,
13822 w = this.width || 1, h = this.height || 1;
13823
13824 x *= l; y *= l;
13825
13826 x1 = 0.5 - x;
13827 x2 = 0.5 + x;
13828 y1 = 0.5 - y;
13829 y2 = 0.5 + y;
13830 this._fillTransform = new transform(w, 0, 0, h);
13831 } else {
13832 this._fillTransform = null;
13833 }
13834 if (this._pendingFill) this._pendingFill();
13835 var gradient = genericContext.createLinearGradient(x1, y1, x2, y2);
13836 this._addColors(gradient, stops);
13837 this._fill = gradient;
13838 return this.invalidate();
13839 },
13840
13841 fillImage: function(url, width, height, left, top, color1, color2){
13842 if (this._pendingFill) this._pendingFill();
13843 var img = url;
13844 if (!(img instanceof Image)){
13845 img = new Image();
13846 img.src = url;
13847 }
13848 if (img.width && img.height){
13849 return this._fillImage(img, width, height, left || 0, top || 0, color1, color2);
13850 }
13851
13852 // Not yet loaded
13853 this._fill = null;
13854 var self = this,
13855 callback = function(){
13856 cancel();
13857 self._fillImage(img, width, height, left || 0, top || 0, color1, color2);
13858 },
13859 cancel = function(){
13860 img.removeEventListener('load', callback, false);
13861 self._pendingFill = null;
13862 };
13863 this._pendingFill = cancel;
13864 img.addEventListener('load', callback, false);
13865 return this;
13866 },
13867
13868 _fillImage: function(img, width, height, left, top, color1, color2){
13869 var w = width ? width / img.width : 1,
13870 h = height ? height / img.height : 1;
13871 if (color1 != null) img = recolorImage(img, color1, color2);
13872 this._fill = genericContext.createPattern(img, 'repeat');
13873 this._fillTransform = new transform(w, 0, 0, h, left || 0, top || 0);
13874 return this.invalidate();
13875 },
13876
13877 stroke: function(color$$1, width, cap, join, dash){
13878 this._stroke = color$$1 ? new color(color$$1).toString() : null;
13879 this._strokeWidth = (width != null) ? width : 1;
13880 this._strokeCap = (cap != null) ? cap : 'round';
13881 this._strokeJoin = (join != null) ? join : 'round';
13882 this._strokeDash = dash;
13883 return this.invalidate();
13884 },
13885
13886 // Rendering
13887
13888 element_renderTo: node.prototype.renderTo,
13889
13890 renderTo: function(context, xx, yx, xy, yy, x, y){
13891 var opacity = this._opacity;
13892 if (opacity == null || opacity >= 1){
13893 return this.renderLayerTo(context, xx, yx, xy, yy, x, y);
13894 }
13895 if (this._fill && this._stroke){
13896 return this.element_renderTo(context, xx, yx, xy, yy, x, y);
13897 }
13898 context.globalAlpha = opacity;
13899 var r = this.renderLayerTo(context, xx, yx, xy, yy, x, y);
13900 context.globalAlpha = 1;
13901 return r;
13902 },
13903
13904 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
13905 context.setTransform(xx, yx, xy, yy, x, y);
13906 this.renderShapeTo(context);
13907 }
13908
13909});
13910
13911Base._genericContext = genericContext;
13912
13913var base = Base;
13914
13915var shape = _class(base, {
13916
13917 base_initialize: base.prototype.initialize,
13918
13919 initialize: function(path$$1, width, height){
13920 this.base_initialize();
13921 this.width = width;
13922 this.height = height;
13923 if (path$$1 != null) this.draw(path$$1);
13924 },
13925
13926 draw: function(path$$1, width, height){
13927 if (!(path$$1 instanceof path)) path$$1 = new path(path$$1);
13928 this.path = path$$1;
13929 this._commands = path$$1.toCommands();
13930 if (width != null) this.width = width;
13931 if (height != null) this.height = height;
13932 return this.invalidate();
13933 },
13934
13935 localHitTest: function(x, y){
13936 if (!this._fill) return null;
13937 if (this.width == null || this.height == null){
13938 var context = base._genericContext, commands = this._commands;
13939 if (!commands) return null;
13940 context.beginPath();
13941 for (var i = 0, l = commands.length; i < l; i++)
13942 commands[i](context);
13943 return context.isPointInPath(x, y) ? this : null;
13944 }
13945 if (x > 0 && y > 0 && x < this.width && y < this.height){
13946 return this;
13947 }
13948 return null;
13949 },
13950
13951 renderShapeTo: function(context){
13952 if (this._invisible || !this._commands || (!this._fill && !this._stroke)) {
13953 return null;
13954 }
13955 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
13956 var commands = this._commands,
13957 fill = this._fill,
13958 stroke = this._stroke,
13959 dash = this._strokeDash;
13960
13961 context.beginPath();
13962
13963 if (dash) {
13964 if (context.setLineDash) {
13965 context.setLineDash(dash);
13966 } else {
13967 // TODO: Remove when FF supports setLineDash.
13968 context.mozDash = dash;
13969 }
13970 // TODO: Create fallback to other browsers.
13971 } else {
13972 if (context.setLineDash) {
13973 context.setLineDash([]);
13974 } else {
13975 context.mozDash = null;
13976 }
13977 }
13978
13979 for (var i = 0, l = commands.length; i < l; i++)
13980 commands[i](context);
13981
13982 if (fill){
13983 var m = this._fillTransform;
13984 if (m){
13985 context.save(); // TODO: Optimize away this by restoring the transform before stroking
13986 context.transform(m.xx, m.yx, m.xy, m.yy, m.x, m.y);
13987 context.fillStyle = fill;
13988 context.fill();
13989 context.restore();
13990 } else {
13991 context.fillStyle = fill;
13992 context.fill();
13993 }
13994 }
13995 if (stroke){
13996 context.strokeStyle = stroke;
13997 context.lineWidth = this._strokeWidth;
13998 context.lineCap = this._strokeCap;
13999 context.lineJoin = this._strokeJoin;
14000 context.stroke();
14001 }
14002 }
14003
14004});
14005
14006var group = _class(node, container, {
14007
14008 initialize: function(width, height){
14009 this.width = width;
14010 this.height = height;
14011 },
14012
14013 localHitTest: function(x, y){
14014 var node$$2 = this.lastChild;
14015 while (node$$2){
14016 var hit = node$$2.hitTest(x, y);
14017 if (hit) return hit;
14018 node$$2 = node$$2.previousSibling;
14019 }
14020 return null;
14021 },
14022
14023 renderLayerTo: function(context, xx, yx, xy, yy, x, y){
14024 if (this._invisible) return;
14025
14026 x = xx * this.x + xy * this.y + x;
14027 y = yx * this.x + yy * this.y + y;
14028
14029 var t = xx;
14030 xx = t * this.xx + xy * this.yx;
14031 xy = t * this.xy + xy * this.yy;
14032 t = yx;
14033 yx = t * this.xx + yy * this.yx;
14034 yy = t * this.xy + yy * this.yy;
14035
14036 var node$$2 = this.firstChild;
14037 while (node$$2){
14038 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14039 node$$2 = node$$2.nextSibling;
14040 }
14041 }
14042
14043});
14044
14045var clippingrectangle = _class(node, container, {
14046
14047 initialize: function(width, height){
14048 this.width = width;
14049 this.height = height;
14050 },
14051
14052 localHitTest: function(x, y) {
14053 var node$$2 = this.lastChild;
14054 while (node$$2){
14055 var hit = node$$2.hitTest(x, y);
14056 if (hit) return hit;
14057 node$$2 = node$$2.previousSibling;
14058 }
14059 return null;
14060 },
14061
14062 renderLayerTo: function(context, xx, yx, xy, yy, x, y) {
14063 context.setTransform(xx, yx, xy, yy, x, y);
14064 context.save();
14065 // Need beginPath to fix Firefox bug. See 3354054.
14066 context.beginPath();
14067 context.rect(this.x, this.y, this.width, this.height);
14068 context.clip();
14069
14070 var node$$2 = this.firstChild;
14071 while(node$$2) {
14072 node$$2.renderTo(context, xx, yx, xy, yy, x, y);
14073 node$$2 = node$$2.nextSibling;
14074 }
14075 context.restore();
14076 }
14077});
14078
14079var fontAnchors = { middle: 'center' };
14080
14081var text = _class(base, {
14082
14083 base_initialize: base.prototype.initialize,
14084
14085 initialize: function(text, font, alignment, path){
14086 this.base_initialize();
14087 this.draw.apply(this, arguments);
14088 },
14089
14090 draw: function(text, font, alignment, path){
14091 var em;
14092 if (typeof font == 'string'){
14093 em = Number(/(\d+)/.exec(font)[0]);
14094 } else if (font){
14095 em = parseFloat(font.fontSize || font['font-size'] || '12');
14096 font = (font.fontStyle || font['font-style'] || '') + ' ' +
14097 (font.fontVariant || font['font-variant'] || '') + ' ' +
14098 (font.fontWeight || font['font-weight'] || '') + ' ' +
14099 em + 'px ' +
14100 (font.fontFamily || font['font-family'] || 'Arial');
14101 } else {
14102 font = this._font;
14103 }
14104
14105 var lines = text && text.split(/\r?\n/);
14106 this._font = font;
14107 this._fontSize = em;
14108 this._text = lines;
14109 this._alignment = fontAnchors[alignment] || alignment || 'left';
14110
14111 var context = base._genericContext;
14112
14113 context.font = this._font;
14114 context.textAlign = this._alignment;
14115 context.textBaseline = 'middle';
14116
14117 lines = this._text;
14118 var l = lines.length, width = 0;
14119 for (var i = 0; i < l; i++){
14120 var w = context.measureText(lines[i]).width;
14121 if (w > width) width = w;
14122 }
14123 this.width = width;
14124 this.height = l ? l * 1.1 * em : 0;
14125 return this.invalidate();
14126 },
14127
14128 // Interaction
14129
14130 localHitTest: function(x, y){
14131 if (!this._fill) return null;
14132 if (x > 0 && y > 0 && x < this.width && y < this.height){
14133 return this;
14134 }
14135 return null;
14136 },
14137
14138 // Rendering
14139
14140 renderShapeTo: function(context){
14141 if (this._invisible || !this._text || (!this._fill && !this._stroke)) {
14142 return null;
14143 }
14144 context.transform(this.xx, this.yx, this.xy, this.yy, this.x, this.y);
14145 var fill = this._fill,
14146 stroke = this._stroke,
14147 text = this._text,
14148 dash = this._strokeDash;
14149
14150 context.font = this._font;
14151 context.textAlign = this._alignment;
14152 context.textBaseline = 'middle';
14153
14154 var em = this._fontSize,
14155 y = em / 2,
14156 lineHeight = 1.1 * em,
14157 lines = text,
14158 l = lines.length;
14159
14160 if (fill){
14161 context.fillStyle = fill;
14162 for (var i = 0; i < l; i++)
14163 context.fillText(lines[i], 0, y + i * lineHeight);
14164 }
14165 if (stroke){
14166 if (dash) {
14167 if (context.setLineDash) {
14168 context.setLineDash(dash);
14169 } else {
14170 // TODO: Remove when FF supports setLineDash.
14171 context.mozDash = dash;
14172 }
14173 // TODO: Create fallback to other browsers.
14174 } else {
14175 if (context.setLineDash) {
14176 context.setLineDash([]);
14177 } else {
14178 context.mozDash = null;
14179 }
14180 }
14181
14182 context.strokeStyle = stroke;
14183 context.lineWidth = this._strokeWidth;
14184 context.lineCap = this._strokeCap;
14185 context.lineJoin = this._strokeJoin;
14186 for (i = 0; i < l; i++)
14187 context.strokeText(lines[i], 0, y + i * lineHeight);
14188 }
14189 }
14190
14191});
14192
14193var VMLCSS = 'behavior:url(#default#VML);display:inline-block;position:absolute;left:0px;top:0px;';
14194
14195var styleSheet;
14196var styledTags = {};
14197var styleTag = function(tag){
14198 if (styleSheet) styledTags[tag] = styleSheet.addRule('av\\:' + tag, VMLCSS);
14199};
14200
14201var init = function(document){
14202
14203 var namespaces;
14204 try { // IE9 workaround: sometimes it throws here
14205 namespaces = document.namespaces;
14206 } catch (e) {
14207 }
14208 if (!namespaces) return false;
14209
14210 namespaces.add('av', 'urn:schemas-microsoft-com:vml');
14211 namespaces.add('ao', 'urn:schemas-microsoft-com:office:office');
14212
14213 styleSheet = document.createStyleSheet();
14214 styleSheet.addRule('vml', 'display:inline-block;position:relative;overflow:hidden;');
14215/* styleTag('skew');
14216 styleTag('fill');
14217 styleTag('stroke');
14218 styleTag('path');
14219 styleTag('textpath');
14220 styleTag('group');*/
14221
14222 styleTag('vml');
14223
14224 return true;
14225
14226};
14227
14228var createElement = function(tag){
14229 if (!(tag in styledTags)) styleTag(tag);
14230 return document.createElement('av:' + tag);
14231};
14232
14233var dom = {
14234 init: init,
14235 createElement: createElement
14236};
14237
14238var precision = 100;
14239
14240var VMLSurface = _class(native_1, container, {
14241
14242 initialize: function VMLSurface(width, height, existingElement){
14243 this.element = existingElement || document.createElement('vml');
14244 this.containerElement = dom.createElement('group');
14245 this.element.appendChild(this.containerElement);
14246 if (width != null && height != null) this.resize(width, height);
14247 },
14248
14249 resize: function(width, height){
14250 this.width = width;
14251 this.height = height;
14252
14253 var style = this.element.style;
14254 style.pixelWidth = width;
14255 style.pixelHeight = height;
14256
14257 style = this.containerElement.style;
14258 style.width = width;
14259 style.height = height;
14260
14261 var halfPixel = (0.5 * precision);
14262
14263 this.containerElement.coordorigin = halfPixel + ',' + halfPixel;
14264 this.containerElement.coordsize = (width * precision) + ',' + (height * precision);
14265
14266 return this;
14267 }
14268
14269});
14270
14271VMLSurface.tagName = 'av:vml';
14272
14273var surface$2 = VMLSurface;
14274
14275var precision$1 = 100;
14276
14277var round = Math.round;
14278
14279var VMLPath = _class(path$2, {
14280
14281 initialize: function(path){
14282 this.reset();
14283 if (path instanceof VMLPath){
14284 this.path = [Array.prototype.join.call(path.path, ' ')];
14285 } else if (path){
14286 if (path.applyToPath)
14287 path.applyToPath(this);
14288 else
14289 this.push(path);
14290 }
14291 },
14292
14293 onReset: function(){
14294 this.path = [];
14295 },
14296
14297 onMove: function(sx, sy, x, y){
14298 this.path.push('m', round(x * precision$1), round(y * precision$1));
14299 },
14300
14301 onLine: function(sx, sy, x, y){
14302 this.path.push('l', round(x * precision$1), round(y * precision$1));
14303 },
14304
14305 onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y){
14306 this.path.push('c',
14307 round(p1x * precision$1), round(p1y * precision$1),
14308 round(p2x * precision$1), round(p2y * precision$1),
14309 round(x * precision$1), round(y * precision$1)
14310 );
14311 },
14312
14313 _arcToBezier: path$2.prototype.onArc,
14314
14315 onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation){
14316 if (rx != ry || rotation) return this._arcToBezier(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation);
14317 cx *= precision$1;
14318 cy *= precision$1;
14319 rx *= precision$1;
14320 this.path.push(ccw ? 'at' : 'wa',
14321 round(cx - rx), round(cy - rx),
14322 round(cx + rx), round(cy + rx),
14323 round(sx * precision$1), round(sy * precision$1),
14324 round(ex * precision$1), round(ey * precision$1)
14325 );
14326 },
14327
14328 onClose: function(){
14329 this.path.push('x');
14330 },
14331
14332 toVML: function(){
14333 return this.path.join(' ');
14334 }
14335
14336});
14337
14338VMLPath.prototype.toString = VMLPath.prototype.toVML;
14339
14340var path$4 = VMLPath;
14341
14342var shadow = _class(dummy, native_1, {
14343
14344 dummy_inject: dummy.prototype.inject,
14345 dummy_injectBefore: dummy.prototype.injectBefore,
14346 dummy_eject: dummy.prototype.eject,
14347 native_inject: native_1.prototype.inject,
14348 native_injectBefore: native_1.prototype.injectBefore,
14349 native_eject: native_1.prototype.eject,
14350
14351 inject: function(container){
14352 this.dummy_inject(container);
14353 this.native_inject(container);
14354 return this;
14355 },
14356
14357 injectBefore: function(sibling){
14358 this.dummy_injectBefore(sibling);
14359 this.native_injectBefore(sibling);
14360 return this;
14361 },
14362
14363 eject: function(){
14364 this.dummy_eject();
14365 this.native_eject();
14366 return this;
14367 }
14368
14369});
14370
14371var node$2 = _class(shadow, transform, {
14372
14373 initialize: function(tag){
14374 //this.uid = uniqueID();
14375 var element = this.element = dom.createElement(tag);
14376 //element.setAttribute('id', 'e' + this.uid);
14377 },
14378
14379 _place: function(){
14380 if (this.parentNode){
14381 this._transform();
14382 }
14383 },
14384
14385 // visibility
14386
14387 hide: function(){
14388 this.element.style.display = 'none';
14389 return this;
14390 },
14391
14392 show: function(){
14393 this.element.style.display = '';
14394 return this;
14395 },
14396
14397 // interaction
14398
14399 indicate: function(cursor, tooltip){
14400 if (cursor) this.element.style.cursor = cursor;
14401 if (tooltip) this.element.title = tooltip;
14402 return this;
14403 }
14404
14405});
14406
14407var precision$3 = 100;
14408
14409var defaultBox = { left: 0, top: 0, width: 500, height: 500 };
14410
14411var base$2 = _class(node$2, {
14412
14413 element_initialize: node$2.prototype.initialize,
14414
14415 initialize: function(tag){
14416 this.element_initialize(tag);
14417 var element = this.element;
14418
14419 var skew = this.skewElement = dom.createElement('skew');
14420 skew.on = true;
14421 element.appendChild(skew);
14422
14423 var fill = this.fillElement = dom.createElement('fill');
14424 fill.on = false;
14425 element.appendChild(fill);
14426
14427 var stroke = this.strokeElement = dom.createElement('stroke');
14428 stroke.on = false;
14429 element.appendChild(stroke);
14430 },
14431
14432 /* transform */
14433
14434 _transform: function(){
14435 var container = this.parentNode;
14436
14437 // Active Transformation Matrix
14438 var m = container ? new transform(container._activeTransform).transform(this) : this;
14439
14440 // Box in shape user space
14441
14442 var box = this._boxCoords || this._size || defaultBox;
14443
14444 var originX = box.left || 0,
14445 originY = box.top || 0,
14446 width = box.width || 1,
14447 height = box.height || 1;
14448
14449 // Flipped
14450 var flip = m.yx / m.xx > m.yy / m.xy;
14451 if (m.xx < 0 ? m.xy >= 0 : m.xy < 0) flip = !flip;
14452 flip = flip ? -1 : 1;
14453
14454 m = new transform().scale(flip, 1).transform(m);
14455
14456 // Rotation is approximated based on the transform
14457 var rotation = Math.atan2(-m.xy, m.yy) * 180 / Math.PI;
14458
14459 // Reverse the rotation, leaving the final transform in box space
14460 var rad = rotation * Math.PI / 180, sin = Math.sin(rad), cos = Math.cos(rad);
14461
14462 var transform$$2 = new transform(
14463 (m.xx * cos - m.xy * sin),
14464 (m.yx * cos - m.yy * sin) * flip,
14465 (m.xy * cos + m.xx * sin) * flip,
14466 (m.yy * cos + m.yx * sin)
14467 );
14468
14469 var rotationTransform = new transform().rotate(rotation, 0, 0);
14470
14471 var shapeToBox = new transform().rotate(-rotation, 0, 0).transform(m).moveTo(0,0);
14472
14473 // Scale box after reversing rotation
14474 width *= Math.abs(shapeToBox.xx);
14475 height *= Math.abs(shapeToBox.yy);
14476
14477 // Place box
14478 var left = m.x, top = m.y;
14479
14480 // Compensate for offset by center origin rotation
14481 var vx = -width / 2, vy = -height / 2;
14482 var point = rotationTransform.point(vx, vy);
14483 left -= point.x - vx;
14484 top -= point.y - vy;
14485
14486 // Adjust box position based on offset
14487 var rsm = new transform(m).moveTo(0,0);
14488 point = rsm.point(originX, originY);
14489 left += point.x;
14490 top += point.y;
14491
14492 if (flip < 0) left = -left - width;
14493
14494 // Place transformation origin
14495 var point0 = rsm.point(-originX, -originY);
14496 var point1 = rotationTransform.point(width, height);
14497 var point2 = rotationTransform.point(width, 0);
14498 var point3 = rotationTransform.point(0, height);
14499
14500 var minX = Math.min(0, point1.x, point2.x, point3.x),
14501 maxX = Math.max(0, point1.x, point2.x, point3.x),
14502 minY = Math.min(0, point1.y, point2.y, point3.y),
14503 maxY = Math.max(0, point1.y, point2.y, point3.y);
14504
14505 var transformOriginX = (point0.x - point1.x / 2) / (maxX - minX) * flip,
14506 transformOriginY = (point0.y - point1.y / 2) / (maxY - minY);
14507
14508 // Adjust the origin
14509 point = shapeToBox.point(originX, originY);
14510 originX = point.x;
14511 originY = point.y;
14512
14513 // Scale stroke
14514 var strokeWidth = this._strokeWidth;
14515 if (strokeWidth){
14516 // Scale is the hypothenus between the two vectors
14517 // TODO: Use area calculation instead
14518 var vx = m.xx + m.xy, vy = m.yy + m.yx;
14519 strokeWidth *= Math.sqrt(vx * vx + vy * vy) / Math.sqrt(2);
14520 }
14521
14522 // convert to multiplied precision space
14523 originX *= precision$3;
14524 originY *= precision$3;
14525 left *= precision$3;
14526 top *= precision$3;
14527 width *= precision$3;
14528 height *= precision$3;
14529
14530 // Set box
14531 var element = this.element;
14532 element.coordorigin = originX + ',' + originY;
14533 element.coordsize = width + ',' + height;
14534 element.style.left = left + 'px';
14535 element.style.top = top + 'px';
14536 element.style.width = width;
14537 element.style.height = height;
14538 element.style.rotation = rotation.toFixed(8);
14539 element.style.flip = flip < 0 ? 'x' : '';
14540
14541 // Set transform
14542 var skew = this.skewElement;
14543 skew.matrix = [transform$$2.xx.toFixed(4), transform$$2.xy.toFixed(4), transform$$2.yx.toFixed(4), transform$$2.yy.toFixed(4), 0, 0];
14544 skew.origin = transformOriginX + ',' + transformOriginY;
14545
14546 // Set stroke
14547 this.strokeElement.weight = strokeWidth + 'px';
14548 },
14549
14550 /* styles */
14551
14552 _createGradient: function(style, stops){
14553 var fill = this.fillElement;
14554
14555 // Temporarily eject the fill from the DOM
14556 this.element.removeChild(fill);
14557
14558 fill.type = style;
14559 fill.method = 'none';
14560 fill.rotate = true;
14561
14562 var colors = [], color1, color2;
14563
14564 var addColor = function(offset, color$$2){
14565 color$$2 = color.detach(color$$2);
14566 if (color1 == null) color1 = color2 = color$$2;
14567 else color2 = color$$2;
14568 colors.push(offset + ' ' + color$$2[0]);
14569 };
14570
14571 // Enumerate stops, assumes offsets are enumerated in order
14572 if ('length' in stops) for (var i = 0, l = stops.length - 1; i <= l; i++) addColor(i / l, stops[i]);
14573 else for (var offset in stops) addColor(offset, stops[offset]);
14574
14575 fill.color = color1[0];
14576 fill.color2 = color2[0];
14577
14578 //if (fill.colors) fill.colors.value = colors; else
14579 fill.colors = colors;
14580
14581 // Opacity order gets flipped when color stops are specified
14582 fill.opacity = color2[1];
14583 fill['ao:opacity2'] = color1[1];
14584
14585 fill.on = true;
14586 this.element.appendChild(fill);
14587 return fill;
14588 },
14589
14590 _setColor: function(type, color$$2){
14591 var element = type == 'fill' ? this.fillElement : this.strokeElement;
14592 if (color$$2 == null){
14593 element.on = false;
14594 } else {
14595 color$$2 = color.detach(color$$2);
14596 element.color = color$$2[0];
14597 element.opacity = color$$2[1];
14598 element.on = true;
14599 }
14600 },
14601
14602 fill: function(color$$2){
14603 if (arguments.length > 1){
14604 this.fillLinear(arguments);
14605 } else {
14606 this._boxCoords = defaultBox;
14607 var fill = this.fillElement;
14608 fill.type = 'solid';
14609 fill.color2 = '';
14610 fill['ao:opacity2'] = '';
14611 if (fill.colors) fill.colors.value = '';
14612 this._setColor('fill', color$$2);
14613 }
14614 return this;
14615 },
14616
14617 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14618 var fill = this._createGradient('gradientradial', stops);
14619 if (focusX == null) focusX = this.left + this.width * 0.5;
14620 if (focusY == null) focusY = this.top + this.height * 0.5;
14621 if (radiusY == null) radiusY = radiusX || (this.height * 0.5);
14622 if (radiusX == null) radiusX = this.width * 0.5;
14623 if (centerX == null) centerX = focusX;
14624 if (centerY == null) centerY = focusY;
14625
14626 centerX += centerX - focusX;
14627 centerY += centerY - focusY;
14628
14629 var box = this._boxCoords = {
14630 left: centerX - radiusX * 2,
14631 top: centerY - radiusY * 2,
14632 width: radiusX * 4,
14633 height: radiusY * 4
14634 };
14635 focusX -= box.left;
14636 focusY -= box.top;
14637 focusX /= box.width;
14638 focusY /= box.height;
14639
14640 fill.focussize = '0 0';
14641 fill.focusposition = focusX + ',' + focusY;
14642 fill.focus = '50%';
14643
14644 this._transform();
14645
14646 return this;
14647 },
14648
14649 fillLinear: function(stops, x1, y1, x2, y2){
14650 var fill = this._createGradient('gradient', stops);
14651 fill.focus = '100%';
14652 if (arguments.length == 5){
14653 var w = Math.abs(x2 - x1), h = Math.abs(y2 - y1);
14654 this._boxCoords = {
14655 left: Math.min(x1, x2),
14656 top: Math.min(y1, y2),
14657 width: w < 1 ? h : w,
14658 height: h < 1 ? w : h
14659 };
14660 fill.angle = (360 + Math.atan2((x2 - x1) / h, (y2 - y1) / w) * 180 / Math.PI) % 360;
14661 } else {
14662 this._boxCoords = null;
14663 fill.angle = (x1 == null) ? 0 : (90 + x1) % 360;
14664 }
14665 this._transform();
14666 return this;
14667 },
14668
14669 fillImage: function(url, width, height, left, top, color1, color2){
14670 var fill = this.fillElement;
14671 if (color1 != null){
14672 color1 = color.detach(color1);
14673 if (color2 != null) color2 = color.detach(color2);
14674 fill.type = 'pattern';
14675 fill.color = color1[0];
14676 fill.color2 = color2 == null ? color1[0] : color2[0];
14677 fill.opacity = color2 == null ? 0 : color2[1];
14678 fill['ao:opacity2'] = color1[1];
14679 } else {
14680 fill.type = 'tile';
14681 fill.color = '';
14682 fill.color2 = '';
14683 fill.opacity = 1;
14684 fill['ao:opacity2'] = 1;
14685 }
14686 if (fill.colors) fill.colors.value = '';
14687 fill.rotate = true;
14688 fill.src = url;
14689
14690 fill.size = '1,1';
14691 fill.position = '0,0';
14692 fill.origin = '0,0';
14693 fill.aspect = 'ignore'; // ignore, atleast, atmost
14694 fill.on = true;
14695
14696 if (!left) left = 0;
14697 if (!top) top = 0;
14698 this._boxCoords = width ? { left: left + 0.5, top: top + 0.5, width: width, height: height } : null;
14699 this._transform();
14700 return this;
14701 },
14702
14703 /* stroke */
14704
14705 stroke: function(color$$2, width, cap, join){
14706 var stroke = this.strokeElement;
14707 this._strokeWidth = (width != null) ? width : 1;
14708 stroke.weight = (width != null) ? width + 'px' : 1;
14709 stroke.endcap = (cap != null) ? ((cap == 'butt') ? 'flat' : cap) : 'round';
14710 stroke.joinstyle = (join != null) ? join : 'round';
14711
14712 this._setColor('stroke', color$$2);
14713 return this;
14714 }
14715
14716});
14717
14718var precision$2 = 100;
14719
14720var shape$2 = _class(base$2, {
14721
14722 base_initialize: base$2.prototype.initialize,
14723
14724 initialize: function(path, width, height){
14725 this.base_initialize('shape');
14726
14727 var p = this.pathElement = dom.createElement('path');
14728 p.gradientshapeok = true;
14729 this.element.appendChild(p);
14730
14731 this.width = width;
14732 this.height = height;
14733
14734 if (path != null) this.draw(path);
14735 },
14736
14737 // SVG to VML
14738
14739 draw: function(path, width, height){
14740
14741 if (!(path instanceof path$4)) path = new path$4(path);
14742 this._vml = path.toVML();
14743 //this._size = path.measure();
14744
14745 if (width != null) this.width = width;
14746 if (height != null) this.height = height;
14747
14748 if (!this._boxCoords) this._transform();
14749 this._redraw(this._prefix, this._suffix);
14750
14751 return this;
14752 },
14753
14754 // radial gradient workaround
14755
14756 _redraw: function(prefix, suffix){
14757 var vml = this._vml || '';
14758
14759 this._prefix = prefix;
14760 this._suffix = suffix;
14761 if (prefix){
14762 vml = [
14763 prefix, vml, suffix,
14764 // Don't stroke the path with the extra ellipse, redraw the stroked path separately
14765 'ns e', vml, 'nf'
14766 ].join(' ');
14767 }
14768
14769 this.element.path = vml + 'e';
14770 },
14771
14772 fillRadial: function(stops, focusX, focusY, radiusX, radiusY, centerX, centerY){
14773 var fill = this._createGradient('gradientradial', stops);
14774 if (focusX == null) focusX = (this.left || 0) + (this.width || 0) * 0.5;
14775 if (focusY == null) focusY = (this.top || 0) + (this.height || 0) * 0.5;
14776 if (radiusY == null) radiusY = radiusX || (this.height * 0.5) || 0;
14777 if (radiusX == null) radiusX = (this.width || 0) * 0.5;
14778 if (centerX == null) centerX = focusX;
14779 if (centerY == null) centerY = focusY;
14780
14781 centerX += centerX - focusX;
14782 centerY += centerY - focusY;
14783
14784 var cx = Math.round(centerX * precision$2),
14785 cy = Math.round(centerY * precision$2),
14786
14787 rx = Math.round(radiusX * 2 * precision$2),
14788 ry = Math.round(radiusY * 2 * precision$2),
14789
14790 arc = ['wa', cx - rx, cy - ry, cx + rx, cy + ry].join(' ');
14791
14792 this._redraw(
14793 // Resolve rendering bug
14794 ['m', cx, cy - ry, 'l', cx, cy - ry].join(' '),
14795 // Draw an ellipse around the path to force an elliptical gradient on any shape
14796 [
14797 'm', cx, cy - ry,
14798 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry,
14799 arc, cx, cy - ry, cx, cy + ry, arc, cx, cy + ry, cx, cy - ry
14800 ].join(' ')
14801 );
14802
14803 this._boxCoords = { left: focusX - 2, top: focusY - 2, width: 4, height: 4 };
14804
14805 fill.focusposition = '0.5,0.5';
14806 fill.focussize = '0 0';
14807 fill.focus = '50%';
14808
14809 this._transform();
14810
14811 return this;
14812 }
14813
14814});
14815
14816var group$2 = _class(node$2, container, {
14817
14818 element_initialize: node$2.prototype.initialize,
14819
14820 initialize: function(width, height){
14821 this.element_initialize('group');
14822 this.width = width;
14823 this.height = height;
14824 },
14825
14826 _transform: function(){
14827 var element = this.element;
14828 element.coordorigin = '0,0';
14829 element.coordsize = '1000,1000';
14830 element.style.left = 0;
14831 element.style.top = 0;
14832 element.style.width = 1000;
14833 element.style.height = 1000;
14834 element.style.rotation = 0;
14835
14836 var container$$2 = this.parentNode;
14837 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
14838 var node = this.firstChild;
14839 while (node){
14840 node._transform();
14841 node = node.nextSibling;
14842 }
14843 }
14844
14845});
14846
14847var clippingrectangle$2 = _class(node$2, container, {
14848
14849 element_initialize: node$2.prototype.initialize,
14850
14851 initialize: function(width, height){
14852 this.element_initialize('clippingrectangle');
14853 this.width = width;
14854 this.height = height;
14855 },
14856
14857 _transform: function(){
14858 var element = this.element;
14859 element.clip = true;
14860 element.coordorigin = -this.x + ',' + (-1 * this.y);
14861 element.coordsize = this.width + ',' + this.height;
14862 // IE8 doesn't like clipBottom. Don't ask me why.
14863 // element.style.clipBottom = this.height + this.y;
14864 element.style.clipLeft = this.x;
14865 element.style.clipRight = this.width + this.x;
14866 element.style.clipTop = this.y;
14867 element.style.left = -this.x;
14868 element.style.top = -this.y;
14869 element.style.width = this.width + this.x;
14870 element.style.height = this.height + this.y;
14871 element.style.rotation = 0;
14872
14873 var container$$2 = this.parentNode;
14874 this._activeTransform = container$$2 ? new transform(container$$2._activeTransform).transform(this) : this;
14875 var node = this.firstChild;
14876 while (node){
14877 node._transform();
14878 node = node.nextSibling;
14879 }
14880 }
14881
14882});
14883
14884var fontAnchors$1 = { start: 'left', middle: 'center', end: 'right' };
14885
14886var text$2 = _class(base$2, {
14887
14888 base_initialize: base$2.prototype.initialize,
14889
14890 initialize: function(text, font, alignment, path){
14891 this.base_initialize('shape');
14892
14893 var p = this.pathElement = dom.createElement('path');
14894 p.textpathok = true;
14895 this.element.appendChild(p);
14896
14897 p = this.textPathElement = dom.createElement("textpath");
14898 p.on = true;
14899 p.style['v-text-align'] = 'left';
14900 this.element.appendChild(p);
14901
14902 this.draw.apply(this, arguments);
14903 },
14904
14905 draw: function(text, font, alignment, path){
14906 var element = this.element,
14907 textPath = this.textPathElement,
14908 style = textPath.style;
14909
14910 textPath.string = text;
14911
14912 if (font){
14913 if (typeof font == 'string'){
14914 style.font = font;
14915 } else {
14916 for (var key in font){
14917 var ckey = key.camelCase ? key.camelCase() : key;
14918 if (ckey == 'fontFamily') style[ckey] = "'" + font[key] + "'";
14919 // NOT UNIVERSALLY SUPPORTED OPTIONS
14920 // else if (ckey == 'kerning') style['v-text-kern'] = !!font[key];
14921 // else if (ckey == 'rotateGlyphs') style['v-rotate-letters'] = !!font[key];
14922 // else if (ckey == 'letterSpacing') style['v-text-spacing'] = Number(font[key]) + '';
14923 else style[ckey] = font[key];
14924 }
14925 }
14926 }
14927
14928 if (alignment) style['v-text-align'] = fontAnchors$1[alignment] || alignment;
14929
14930 if (path){
14931 this.currentPath = path = new path$4(path);
14932 this.element.path = path.toVML();
14933 } else if (!this.currentPath){
14934 var i = -1, offsetRows = '\n';
14935 while ((i = text.indexOf('\n', i + 1)) > -1) offsetRows += '\n';
14936 textPath.string = offsetRows + textPath.string;
14937 this.element.path = 'm0,0l1,0';
14938 }
14939
14940 // Measuring the bounding box is currently necessary for gradients etc.
14941
14942 // Clone element because the element is dead once it has been in the DOM
14943 element = element.cloneNode(true);
14944 style = element.style;
14945
14946 // Reset coordinates while measuring
14947 element.coordorigin = '0,0';
14948 element.coordsize = '10000,10000';
14949 style.left = '0px';
14950 style.top = '0px';
14951 style.width = '10000px';
14952 style.height = '10000px';
14953 style.rotation = 0;
14954 element.removeChild(element.firstChild); // Remove skew
14955
14956 // Inject the clone into the document
14957
14958 var canvas = new surface$2(1, 1),
14959 group = new group$2(), // Wrapping it in a group seems to alleviate some client rect weirdness
14960 body = element.ownerDocument.body;
14961
14962 canvas.inject(body);
14963 group.element.appendChild(element);
14964 group.inject(canvas);
14965
14966 var ebb = element.getBoundingClientRect(),
14967 cbb = canvas.toElement().getBoundingClientRect();
14968
14969 canvas.eject();
14970
14971 this.left = ebb.left - cbb.left;
14972 this.top = ebb.top - cbb.top;
14973 this.width = ebb.right - ebb.left;
14974 this.height = ebb.bottom - ebb.top;
14975 this.right = ebb.right - cbb.left;
14976 this.bottom = ebb.bottom - cbb.top;
14977
14978 this._transform();
14979
14980 //this._size = { left: this.left, top: this.top, width: this.width, height: this.height};
14981 return this;
14982 }
14983
14984});
14985
14986var fastNoSideEffects = createCommonjsModule(function (module, exports) {
14987var hasCanvas = function(){
14988
14989 var canvas = document.createElement('canvas');
14990 return canvas && !!canvas.getContext;
14991
14992};
14993
14994if (hasCanvas()) {
14995 exports.Surface = surface;
14996 exports.Path = path;
14997 exports.Shape = shape;
14998 exports.Group = group;
14999 exports.ClippingRectangle = clippingrectangle;
15000 exports.Text = text;
15001} else {
15002 exports.Surface = surface$2;
15003 exports.Path = path$4;
15004 exports.Shape = shape$2;
15005 exports.Group = group$2;
15006 exports.ClippingRectangle = clippingrectangle$2;
15007 exports.Text = text$2;
15008
15009 var DOM$$1 = dom;
15010 if (typeof document !== 'undefined') DOM$$1.init(document);
15011}
15012});
15013
15014var fastNoSideEffects_1 = fastNoSideEffects.Surface;
15015var fastNoSideEffects_2 = fastNoSideEffects.Path;
15016var fastNoSideEffects_3 = fastNoSideEffects.Shape;
15017var fastNoSideEffects_4 = fastNoSideEffects.Group;
15018var fastNoSideEffects_5 = fastNoSideEffects.ClippingRectangle;
15019var fastNoSideEffects_6 = fastNoSideEffects.Text;
15020
15021var _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; };
15022
15023function _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; }
15024
15025function _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; }
15026
15027function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
15028
15029current.setCurrent(
15030// Change to 'art/modes/dom' for easier debugging via SVG
15031fastNoSideEffects);
15032
15033/** Declarative fill-type objects; API design not finalized */
15034
15035var slice = Array.prototype.slice;
15036
15037var LinearGradient = function () {
15038 function LinearGradient(stops, x1, y1, x2, y2) {
15039 _classCallCheck(this, LinearGradient);
15040
15041 this._args = slice.call(arguments);
15042 }
15043
15044 LinearGradient.prototype.applyFill = function applyFill(node) {
15045 node.fillLinear.apply(node, this._args);
15046 };
15047
15048 return LinearGradient;
15049}();
15050
15051var RadialGradient = function () {
15052 function RadialGradient(stops, fx, fy, rx, ry, cx, cy) {
15053 _classCallCheck(this, RadialGradient);
15054
15055 this._args = slice.call(arguments);
15056 }
15057
15058 RadialGradient.prototype.applyFill = function applyFill(node) {
15059 node.fillRadial.apply(node, this._args);
15060 };
15061
15062 return RadialGradient;
15063}();
15064
15065var Pattern = function () {
15066 function Pattern(url, width, height, left, top) {
15067 _classCallCheck(this, Pattern);
15068
15069 this._args = slice.call(arguments);
15070 }
15071
15072 Pattern.prototype.applyFill = function applyFill(node) {
15073 node.fillImage.apply(node, this._args);
15074 };
15075
15076 return Pattern;
15077}();
15078
15079/** React Components */
15080
15081var Surface = function (_React$Component) {
15082 _inherits(Surface, _React$Component);
15083
15084 function Surface() {
15085 _classCallCheck(this, Surface);
15086
15087 return _possibleConstructorReturn(this, _React$Component.apply(this, arguments));
15088 }
15089
15090 Surface.prototype.componentDidMount = function componentDidMount() {
15091 var _props = this.props,
15092 height = _props.height,
15093 width = _props.width;
15094
15095
15096 this._surface = current.Surface(+width, +height, this._tagRef);
15097
15098 this._mountNode = createContainer(this._surface);
15099 updateContainer(this.props.children, this._mountNode, this);
15100 };
15101
15102 Surface.prototype.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
15103 var props = this.props;
15104
15105 if (props.height !== prevProps.height || props.width !== prevProps.width) {
15106 this._surface.resize(+props.width, +props.height);
15107 }
15108
15109 updateContainer(this.props.children, this._mountNode, this);
15110
15111 if (this._surface.render) {
15112 this._surface.render();
15113 }
15114 };
15115
15116 Surface.prototype.componentWillUnmount = function componentWillUnmount() {
15117 updateContainer(null, this._mountNode, this);
15118 };
15119
15120 Surface.prototype.render = function render() {
15121 var _this2 = this;
15122
15123 // This is going to be a placeholder because we don't know what it will
15124 // actually resolve to because ART may render canvas, vml or svg tags here.
15125 // We only allow a subset of properties since others might conflict with
15126 // ART's properties.
15127 var props = this.props;
15128
15129 // TODO: ART's Canvas Mode overrides surface title and cursor
15130 var Tag = current.Surface.tagName;
15131
15132 return React.createElement(Tag, {
15133 ref: function (ref) {
15134 return _this2._tagRef = ref;
15135 },
15136 accessKey: props.accessKey,
15137 className: props.className,
15138 draggable: props.draggable,
15139 role: props.role,
15140 style: props.style,
15141 tabIndex: props.tabIndex,
15142 title: props.title
15143 });
15144 };
15145
15146 return Surface;
15147}(React.Component);
15148
15149var Text = function (_React$Component2) {
15150 _inherits(Text, _React$Component2);
15151
15152 function Text(props) {
15153 _classCallCheck(this, Text);
15154
15155 // We allow reading these props. Ideally we could expose the Text node as
15156 // ref directly.
15157 var _this3 = _possibleConstructorReturn(this, _React$Component2.call(this, props));
15158
15159 ['height', 'width', 'x', 'y'].forEach(function (key) {
15160 Object.defineProperty(_this3, key, {
15161 get: function () {
15162 return this._text ? this._text[key] : undefined;
15163 }
15164 });
15165 });
15166 return _this3;
15167 }
15168
15169 Text.prototype.render = function render() {
15170 var _this4 = this;
15171
15172 // This means you can't have children that render into strings...
15173 var T = TYPES.TEXT;
15174 return React.createElement(
15175 T,
15176 _extends({}, this.props, { ref: function (t) {
15177 return _this4._text = t;
15178 } }),
15179 childrenAsString(this.props.children)
15180 );
15181 };
15182
15183 return Text;
15184}(React.Component);
15185
15186injectIntoDevTools({
15187 findFiberByHostInstance: function () {
15188 return null;
15189 },
15190 bundleType: 1,
15191 version: ReactVersion,
15192 rendererPackageName: 'react-art'
15193});
15194
15195/** API */
15196
15197var ClippingRectangle = TYPES.CLIPPING_RECTANGLE;
15198var Group = TYPES.GROUP;
15199var Shape = TYPES.SHAPE;
15200var Path = current.Path;
15201
15202
15203var ReactART = Object.freeze({
15204 ClippingRectangle: ClippingRectangle,
15205 Group: Group,
15206 Shape: Shape,
15207 Path: Path,
15208 LinearGradient: LinearGradient,
15209 Pattern: Pattern,
15210 RadialGradient: RadialGradient,
15211 Surface: Surface,
15212 Text: Text,
15213 Transform: transform
15214});
15215
15216var reactArt = ReactART;
15217
15218return reactArt;
15219
15220})));