UNPKG

976 kBJavaScriptView Raw
1/** @license React v16.12.0
2 * react-dom.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.ReactDOM = factory(global.React));
16}(this, (function (React) { 'use strict';
17
18// Do not require this module directly! Use normal `invariant` calls with
19// template literal strings. The messages will be replaced with error codes
20// during build.
21
22/**
23 * Use invariant() to assert state which your program assumes to be true.
24 *
25 * Provide sprintf-style format (only %s is supported) and arguments
26 * to provide information about what broke and what you were
27 * expecting.
28 *
29 * The invariant message will be stripped in production, but the invariant
30 * will remain to ensure logic does not differ in production.
31 */
32
33if (!React) {
34 {
35 throw Error("ReactDOM was loaded before React. Make sure you load the React package before loading ReactDOM.");
36 }
37}
38
39/**
40 * Injectable ordering of event plugins.
41 */
42var eventPluginOrder = null;
43/**
44 * Injectable mapping from names to event plugin modules.
45 */
46
47var namesToPlugins = {};
48/**
49 * Recomputes the plugin list using the injected plugins and plugin ordering.
50 *
51 * @private
52 */
53
54function recomputePluginOrdering() {
55 if (!eventPluginOrder) {
56 // Wait until an `eventPluginOrder` is injected.
57 return;
58 }
59
60 for (var pluginName in namesToPlugins) {
61 var pluginModule = namesToPlugins[pluginName];
62 var pluginIndex = eventPluginOrder.indexOf(pluginName);
63
64 if (!(pluginIndex > -1)) {
65 {
66 throw Error("EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `" + pluginName + "`.");
67 }
68 }
69
70 if (plugins[pluginIndex]) {
71 continue;
72 }
73
74 if (!pluginModule.extractEvents) {
75 {
76 throw Error("EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `" + pluginName + "` does not.");
77 }
78 }
79
80 plugins[pluginIndex] = pluginModule;
81 var publishedEvents = pluginModule.eventTypes;
82
83 for (var eventName in publishedEvents) {
84 if (!publishEventForPlugin(publishedEvents[eventName], pluginModule, eventName)) {
85 {
86 throw Error("EventPluginRegistry: Failed to publish event `" + eventName + "` for plugin `" + pluginName + "`.");
87 }
88 }
89 }
90 }
91}
92/**
93 * Publishes an event so that it can be dispatched by the supplied plugin.
94 *
95 * @param {object} dispatchConfig Dispatch configuration for the event.
96 * @param {object} PluginModule Plugin publishing the event.
97 * @return {boolean} True if the event was successfully published.
98 * @private
99 */
100
101
102function publishEventForPlugin(dispatchConfig, pluginModule, eventName) {
103 if (!!eventNameDispatchConfigs.hasOwnProperty(eventName)) {
104 {
105 throw Error("EventPluginHub: More than one plugin attempted to publish the same event name, `" + eventName + "`.");
106 }
107 }
108
109 eventNameDispatchConfigs[eventName] = dispatchConfig;
110 var phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
111
112 if (phasedRegistrationNames) {
113 for (var phaseName in phasedRegistrationNames) {
114 if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
115 var phasedRegistrationName = phasedRegistrationNames[phaseName];
116 publishRegistrationName(phasedRegistrationName, pluginModule, eventName);
117 }
118 }
119
120 return true;
121 } else if (dispatchConfig.registrationName) {
122 publishRegistrationName(dispatchConfig.registrationName, pluginModule, eventName);
123 return true;
124 }
125
126 return false;
127}
128/**
129 * Publishes a registration name that is used to identify dispatched events.
130 *
131 * @param {string} registrationName Registration name to add.
132 * @param {object} PluginModule Plugin publishing the event.
133 * @private
134 */
135
136
137function publishRegistrationName(registrationName, pluginModule, eventName) {
138 if (!!registrationNameModules[registrationName]) {
139 {
140 throw Error("EventPluginHub: More than one plugin attempted to publish the same registration name, `" + registrationName + "`.");
141 }
142 }
143
144 registrationNameModules[registrationName] = pluginModule;
145 registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
146
147 {
148 var lowerCasedName = registrationName.toLowerCase();
149 possibleRegistrationNames[lowerCasedName] = registrationName;
150
151 if (registrationName === 'onDoubleClick') {
152 possibleRegistrationNames.ondblclick = registrationName;
153 }
154 }
155}
156/**
157 * Registers plugins so that they can extract and dispatch events.
158 *
159 * @see {EventPluginHub}
160 */
161
162/**
163 * Ordered list of injected plugins.
164 */
165
166
167var plugins = [];
168/**
169 * Mapping from event name to dispatch config
170 */
171
172var eventNameDispatchConfigs = {};
173/**
174 * Mapping from registration name to plugin module
175 */
176
177var registrationNameModules = {};
178/**
179 * Mapping from registration name to event name
180 */
181
182var registrationNameDependencies = {};
183/**
184 * Mapping from lowercase registration names to the properly cased version,
185 * used to warn in the case of missing event handlers. Available
186 * only in true.
187 * @type {Object}
188 */
189
190var possibleRegistrationNames = {}; // Trust the developer to only use possibleRegistrationNames in true
191
192/**
193 * Injects an ordering of plugins (by plugin name). This allows the ordering
194 * to be decoupled from injection of the actual plugins so that ordering is
195 * always deterministic regardless of packaging, on-the-fly injection, etc.
196 *
197 * @param {array} InjectedEventPluginOrder
198 * @internal
199 * @see {EventPluginHub.injection.injectEventPluginOrder}
200 */
201
202function injectEventPluginOrder(injectedEventPluginOrder) {
203 if (!!eventPluginOrder) {
204 {
205 throw Error("EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React.");
206 }
207 } // Clone the ordering so it cannot be dynamically mutated.
208
209
210 eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
211 recomputePluginOrdering();
212}
213/**
214 * Injects plugins to be used by `EventPluginHub`. The plugin names must be
215 * in the ordering injected by `injectEventPluginOrder`.
216 *
217 * Plugins can be injected as part of page initialization or on-the-fly.
218 *
219 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
220 * @internal
221 * @see {EventPluginHub.injection.injectEventPluginsByName}
222 */
223
224function injectEventPluginsByName(injectedNamesToPlugins) {
225 var isOrderingDirty = false;
226
227 for (var pluginName in injectedNamesToPlugins) {
228 if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
229 continue;
230 }
231
232 var pluginModule = injectedNamesToPlugins[pluginName];
233
234 if (!namesToPlugins.hasOwnProperty(pluginName) || namesToPlugins[pluginName] !== pluginModule) {
235 if (!!namesToPlugins[pluginName]) {
236 {
237 throw Error("EventPluginRegistry: Cannot inject two different event plugins using the same name, `" + pluginName + "`.");
238 }
239 }
240
241 namesToPlugins[pluginName] = pluginModule;
242 isOrderingDirty = true;
243 }
244 }
245
246 if (isOrderingDirty) {
247 recomputePluginOrdering();
248 }
249}
250
251var invokeGuardedCallbackImpl = function (name, func, context, a, b, c, d, e, f) {
252 var funcArgs = Array.prototype.slice.call(arguments, 3);
253
254 try {
255 func.apply(context, funcArgs);
256 } catch (error) {
257 this.onError(error);
258 }
259};
260
261{
262 // In DEV mode, we swap out invokeGuardedCallback for a special version
263 // that plays more nicely with the browser's DevTools. The idea is to preserve
264 // "Pause on exceptions" behavior. Because React wraps all user-provided
265 // functions in invokeGuardedCallback, and the production version of
266 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
267 // like caught exceptions, and the DevTools won't pause unless the developer
268 // takes the extra step of enabling pause on caught exceptions. This is
269 // unintuitive, though, because even though React has caught the error, from
270 // the developer's perspective, the error is uncaught.
271 //
272 // To preserve the expected "Pause on exceptions" behavior, we don't use a
273 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
274 // DOM node, and call the user-provided callback from inside an event handler
275 // for that fake event. If the callback throws, the error is "captured" using
276 // a global event handler. But because the error happens in a different
277 // event loop context, it does not interrupt the normal program flow.
278 // Effectively, this gives us try-catch behavior without actually using
279 // try-catch. Neat!
280 // Check that the browser supports the APIs we need to implement our special
281 // DEV version of invokeGuardedCallback
282 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
283 var fakeNode = document.createElement('react');
284
285 var invokeGuardedCallbackDev = function (name, func, context, a, b, c, d, e, f) {
286 // If document doesn't exist we know for sure we will crash in this method
287 // when we call document.createEvent(). However this can cause confusing
288 // errors: https://github.com/facebookincubator/create-react-app/issues/3482
289 // So we preemptively throw with a better message instead.
290 if (!(typeof document !== 'undefined')) {
291 {
292 throw Error("The `document` global was defined when React was initialized, but is not defined anymore. This can happen in a test environment if a component schedules an update from an asynchronous callback, but the test has already finished running. To solve this, you can either unmount the component at the end of your test (and ensure that any asynchronous operations get canceled in `componentWillUnmount`), or you can change the test itself to be asynchronous.");
293 }
294 }
295
296 var evt = document.createEvent('Event'); // Keeps track of whether the user-provided callback threw an error. We
297 // set this to true at the beginning, then set it to false right after
298 // calling the function. If the function errors, `didError` will never be
299 // set to false. This strategy works even if the browser is flaky and
300 // fails to call our global error handler, because it doesn't rely on
301 // the error event at all.
302
303 var didError = true; // Keeps track of the value of window.event so that we can reset it
304 // during the callback to let user code access window.event in the
305 // browsers that support it.
306
307 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
308 // dispatching: https://github.com/facebook/react/issues/13688
309
310 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event'); // Create an event handler for our fake event. We will synchronously
311 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
312 // call the user-provided callback.
313
314 var funcArgs = Array.prototype.slice.call(arguments, 3);
315
316 function callCallback() {
317 // We immediately remove the callback from event listeners so that
318 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
319 // nested call would trigger the fake event handlers of any call higher
320 // in the stack.
321 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
322 // window.event assignment in both IE <= 10 as they throw an error
323 // "Member not found" in strict mode, and in Firefox which does not
324 // support window.event.
325
326 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
327 window.event = windowEvent;
328 }
329
330 func.apply(context, funcArgs);
331 didError = false;
332 } // Create a global error event handler. We use this to capture the value
333 // that was thrown. It's possible that this error handler will fire more
334 // than once; for example, if non-React code also calls `dispatchEvent`
335 // and a handler for that event throws. We should be resilient to most of
336 // those cases. Even if our error event handler fires more than once, the
337 // last error event is always used. If the callback actually does error,
338 // we know that the last error event is the correct one, because it's not
339 // possible for anything else to have happened in between our callback
340 // erroring and the code that follows the `dispatchEvent` call below. If
341 // the callback doesn't error, but the error event was fired, we know to
342 // ignore it because `didError` will be false, as described above.
343
344
345 var error; // Use this to track whether the error event is ever called.
346
347 var didSetError = false;
348 var isCrossOriginError = false;
349
350 function handleWindowError(event) {
351 error = event.error;
352 didSetError = true;
353
354 if (error === null && event.colno === 0 && event.lineno === 0) {
355 isCrossOriginError = true;
356 }
357
358 if (event.defaultPrevented) {
359 // Some other error handler has prevented default.
360 // Browsers silence the error report if this happens.
361 // We'll remember this to later decide whether to log it or not.
362 if (error != null && typeof error === 'object') {
363 try {
364 error._suppressLogging = true;
365 } catch (inner) {// Ignore.
366 }
367 }
368 }
369 } // Create a fake event type.
370
371
372 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
373
374 window.addEventListener('error', handleWindowError);
375 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
376 // errors, it will trigger our global error handler.
377
378 evt.initEvent(evtType, false, false);
379 fakeNode.dispatchEvent(evt);
380
381 if (windowEventDescriptor) {
382 Object.defineProperty(window, 'event', windowEventDescriptor);
383 }
384
385 if (didError) {
386 if (!didSetError) {
387 // The callback errored, but the error event never fired.
388 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.');
389 } else if (isCrossOriginError) {
390 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.');
391 }
392
393 this.onError(error);
394 } // Remove our event listeners
395
396
397 window.removeEventListener('error', handleWindowError);
398 };
399
400 invokeGuardedCallbackImpl = invokeGuardedCallbackDev;
401 }
402}
403
404var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
405
406var hasError = false;
407var caughtError = null; // Used by event system to capture/rethrow the first error.
408
409var hasRethrowError = false;
410var rethrowError = null;
411var reporter = {
412 onError: function (error) {
413 hasError = true;
414 caughtError = error;
415 }
416};
417/**
418 * Call a function while guarding against errors that happens within it.
419 * Returns an error if it throws, otherwise null.
420 *
421 * In production, this is implemented using a try-catch. The reason we don't
422 * use a try-catch directly is so that we can swap out a different
423 * implementation in DEV mode.
424 *
425 * @param {String} name of the guard to use for logging or debugging
426 * @param {Function} func The function to invoke
427 * @param {*} context The context to use when calling the function
428 * @param {...*} args Arguments for function
429 */
430
431function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
432 hasError = false;
433 caughtError = null;
434 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
435}
436/**
437 * Same as invokeGuardedCallback, but instead of returning an error, it stores
438 * it in a global so it can be rethrown by `rethrowCaughtError` later.
439 * TODO: See if caughtError and rethrowError can be unified.
440 *
441 * @param {String} name of the guard to use for logging or debugging
442 * @param {Function} func The function to invoke
443 * @param {*} context The context to use when calling the function
444 * @param {...*} args Arguments for function
445 */
446
447function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
448 invokeGuardedCallback.apply(this, arguments);
449
450 if (hasError) {
451 var error = clearCaughtError();
452
453 if (!hasRethrowError) {
454 hasRethrowError = true;
455 rethrowError = error;
456 }
457 }
458}
459/**
460 * During execution of guarded functions we will capture the first error which
461 * we will rethrow to be handled by the top level error handler.
462 */
463
464function rethrowCaughtError() {
465 if (hasRethrowError) {
466 var error = rethrowError;
467 hasRethrowError = false;
468 rethrowError = null;
469 throw error;
470 }
471}
472function hasCaughtError() {
473 return hasError;
474}
475function clearCaughtError() {
476 if (hasError) {
477 var error = caughtError;
478 hasError = false;
479 caughtError = null;
480 return error;
481 } else {
482 {
483 {
484 throw Error("clearCaughtError was called but no error was captured. This error is likely caused by a bug in React. Please file an issue.");
485 }
486 }
487 }
488}
489
490/**
491 * Similar to invariant but only logs a warning if the condition is not met.
492 * This can be used to log issues in development environments in critical
493 * paths. Removing the logging code for production environments will keep the
494 * same logic and follow the same code paths.
495 */
496var warningWithoutStack = function () {};
497
498{
499 warningWithoutStack = function (condition, format) {
500 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
501 args[_key - 2] = arguments[_key];
502 }
503
504 if (format === undefined) {
505 throw new Error('`warningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
506 }
507
508 if (args.length > 8) {
509 // Check before the condition to catch violations early.
510 throw new Error('warningWithoutStack() currently supports at most 8 arguments.');
511 }
512
513 if (condition) {
514 return;
515 }
516
517 if (typeof console !== 'undefined') {
518 var argsWithFormat = args.map(function (item) {
519 return '' + item;
520 });
521 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
522 // breaks IE9: https://github.com/facebook/react/issues/13610
523
524 Function.prototype.apply.call(console.error, console, argsWithFormat);
525 }
526
527 try {
528 // --- Welcome to debugging React ---
529 // This error was thrown as a convenience so that you can use this stack
530 // to find the callsite that caused this warning to fire.
531 var argIndex = 0;
532 var message = 'Warning: ' + format.replace(/%s/g, function () {
533 return args[argIndex++];
534 });
535 throw new Error(message);
536 } catch (x) {}
537 };
538}
539
540var warningWithoutStack$1 = warningWithoutStack;
541
542var getFiberCurrentPropsFromNode = null;
543var getInstanceFromNode = null;
544var getNodeFromInstance = null;
545function setComponentTree(getFiberCurrentPropsFromNodeImpl, getInstanceFromNodeImpl, getNodeFromInstanceImpl) {
546 getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
547 getInstanceFromNode = getInstanceFromNodeImpl;
548 getNodeFromInstance = getNodeFromInstanceImpl;
549
550 {
551 !(getNodeFromInstance && getInstanceFromNode) ? warningWithoutStack$1(false, 'EventPluginUtils.setComponentTree(...): Injected ' + 'module is missing getNodeFromInstance or getInstanceFromNode.') : void 0;
552 }
553}
554var validateEventDispatches;
555
556{
557 validateEventDispatches = function (event) {
558 var dispatchListeners = event._dispatchListeners;
559 var dispatchInstances = event._dispatchInstances;
560 var listenersIsArr = Array.isArray(dispatchListeners);
561 var listenersLen = listenersIsArr ? dispatchListeners.length : dispatchListeners ? 1 : 0;
562 var instancesIsArr = Array.isArray(dispatchInstances);
563 var instancesLen = instancesIsArr ? dispatchInstances.length : dispatchInstances ? 1 : 0;
564 !(instancesIsArr === listenersIsArr && instancesLen === listenersLen) ? warningWithoutStack$1(false, 'EventPluginUtils: Invalid `event`.') : void 0;
565 };
566}
567/**
568 * Dispatch the event to the listener.
569 * @param {SyntheticEvent} event SyntheticEvent to handle
570 * @param {function} listener Application-level callback
571 * @param {*} inst Internal component instance
572 */
573
574
575function executeDispatch(event, listener, inst) {
576 var type = event.type || 'unknown-event';
577 event.currentTarget = getNodeFromInstance(inst);
578 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
579 event.currentTarget = null;
580}
581/**
582 * Standard/simple iteration through an event's collected dispatches.
583 */
584
585function executeDispatchesInOrder(event) {
586 var dispatchListeners = event._dispatchListeners;
587 var dispatchInstances = event._dispatchInstances;
588
589 {
590 validateEventDispatches(event);
591 }
592
593 if (Array.isArray(dispatchListeners)) {
594 for (var i = 0; i < dispatchListeners.length; i++) {
595 if (event.isPropagationStopped()) {
596 break;
597 } // Listeners and Instances are two parallel arrays that are always in sync.
598
599
600 executeDispatch(event, dispatchListeners[i], dispatchInstances[i]);
601 }
602 } else if (dispatchListeners) {
603 executeDispatch(event, dispatchListeners, dispatchInstances);
604 }
605
606 event._dispatchListeners = null;
607 event._dispatchInstances = null;
608}
609/**
610 * @see executeDispatchesInOrderStopAtTrueImpl
611 */
612
613
614
615/**
616 * Execution of a "direct" dispatch - there must be at most one dispatch
617 * accumulated on the event or it is considered an error. It doesn't really make
618 * sense for an event with multiple dispatches (bubbled) to keep track of the
619 * return values at each dispatch execution, but it does tend to make sense when
620 * dealing with "direct" dispatches.
621 *
622 * @return {*} The return value of executing the single dispatch.
623 */
624
625
626/**
627 * @param {SyntheticEvent} event
628 * @return {boolean} True iff number of dispatches accumulated is greater than 0.
629 */
630
631/**
632 * Accumulates items that must not be null or undefined into the first one. This
633 * is used to conserve memory by avoiding array allocations, and thus sacrifices
634 * API cleanness. Since `current` can be null before being passed in and not
635 * null after this function, make sure to assign it back to `current`:
636 *
637 * `a = accumulateInto(a, b);`
638 *
639 * This API should be sparingly used. Try `accumulate` for something cleaner.
640 *
641 * @return {*|array<*>} An accumulation of items.
642 */
643
644function accumulateInto(current, next) {
645 if (!(next != null)) {
646 {
647 throw Error("accumulateInto(...): Accumulated items must not be null or undefined.");
648 }
649 }
650
651 if (current == null) {
652 return next;
653 } // Both are not empty. Warning: Never call x.concat(y) when you are not
654 // certain that x is an Array (x could be a string with concat method).
655
656
657 if (Array.isArray(current)) {
658 if (Array.isArray(next)) {
659 current.push.apply(current, next);
660 return current;
661 }
662
663 current.push(next);
664 return current;
665 }
666
667 if (Array.isArray(next)) {
668 // A bit too dangerous to mutate `next`.
669 return [current].concat(next);
670 }
671
672 return [current, next];
673}
674
675/**
676 * @param {array} arr an "accumulation" of items which is either an Array or
677 * a single item. Useful when paired with the `accumulate` module. This is a
678 * simple utility that allows us to reason about a collection of items, but
679 * handling the case when there is exactly one item (and we do not need to
680 * allocate an array).
681 * @param {function} cb Callback invoked with each element or a collection.
682 * @param {?} [scope] Scope used as `this` in a callback.
683 */
684function forEachAccumulated(arr, cb, scope) {
685 if (Array.isArray(arr)) {
686 arr.forEach(cb, scope);
687 } else if (arr) {
688 cb.call(scope, arr);
689 }
690}
691
692/**
693 * Internal queue of events that have accumulated their dispatches and are
694 * waiting to have their dispatches executed.
695 */
696
697var eventQueue = null;
698/**
699 * Dispatches an event and releases it back into the pool, unless persistent.
700 *
701 * @param {?object} event Synthetic event to be dispatched.
702 * @private
703 */
704
705var executeDispatchesAndRelease = function (event) {
706 if (event) {
707 executeDispatchesInOrder(event);
708
709 if (!event.isPersistent()) {
710 event.constructor.release(event);
711 }
712 }
713};
714
715var executeDispatchesAndReleaseTopLevel = function (e) {
716 return executeDispatchesAndRelease(e);
717};
718
719function runEventsInBatch(events) {
720 if (events !== null) {
721 eventQueue = accumulateInto(eventQueue, events);
722 } // Set `eventQueue` to null before processing it so that we can tell if more
723 // events get enqueued while processing.
724
725
726 var processingEventQueue = eventQueue;
727 eventQueue = null;
728
729 if (!processingEventQueue) {
730 return;
731 }
732
733 forEachAccumulated(processingEventQueue, executeDispatchesAndReleaseTopLevel);
734
735 if (!!eventQueue) {
736 {
737 throw Error("processEventQueue(): Additional events were enqueued while processing an event queue. Support for this has not yet been implemented.");
738 }
739 } // This would be a good time to rethrow if any of the event handlers threw.
740
741
742 rethrowCaughtError();
743}
744
745function isInteractive(tag) {
746 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
747}
748
749function shouldPreventMouseEvent(name, type, props) {
750 switch (name) {
751 case 'onClick':
752 case 'onClickCapture':
753 case 'onDoubleClick':
754 case 'onDoubleClickCapture':
755 case 'onMouseDown':
756 case 'onMouseDownCapture':
757 case 'onMouseMove':
758 case 'onMouseMoveCapture':
759 case 'onMouseUp':
760 case 'onMouseUpCapture':
761 return !!(props.disabled && isInteractive(type));
762
763 default:
764 return false;
765 }
766}
767/**
768 * This is a unified interface for event plugins to be installed and configured.
769 *
770 * Event plugins can implement the following properties:
771 *
772 * `extractEvents` {function(string, DOMEventTarget, string, object): *}
773 * Required. When a top-level event is fired, this method is expected to
774 * extract synthetic events that will in turn be queued and dispatched.
775 *
776 * `eventTypes` {object}
777 * Optional, plugins that fire events must publish a mapping of registration
778 * names that are used to register listeners. Values of this mapping must
779 * be objects that contain `registrationName` or `phasedRegistrationNames`.
780 *
781 * `executeDispatch` {function(object, function, string)}
782 * Optional, allows plugins to override how an event gets dispatched. By
783 * default, the listener is simply invoked.
784 *
785 * Each plugin that is injected into `EventsPluginHub` is immediately operable.
786 *
787 * @public
788 */
789
790/**
791 * Methods for injecting dependencies.
792 */
793
794
795var injection = {
796 /**
797 * @param {array} InjectedEventPluginOrder
798 * @public
799 */
800 injectEventPluginOrder: injectEventPluginOrder,
801
802 /**
803 * @param {object} injectedNamesToPlugins Map from names to plugin modules.
804 */
805 injectEventPluginsByName: injectEventPluginsByName
806};
807/**
808 * @param {object} inst The instance, which is the source of events.
809 * @param {string} registrationName Name of listener (e.g. `onClick`).
810 * @return {?function} The stored callback.
811 */
812
813function getListener(inst, registrationName) {
814 var listener; // TODO: shouldPreventMouseEvent is DOM-specific and definitely should not
815 // live here; needs to be moved to a better place soon
816
817 var stateNode = inst.stateNode;
818
819 if (!stateNode) {
820 // Work in progress (ex: onload events in incremental mode).
821 return null;
822 }
823
824 var props = getFiberCurrentPropsFromNode(stateNode);
825
826 if (!props) {
827 // Work in progress.
828 return null;
829 }
830
831 listener = props[registrationName];
832
833 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
834 return null;
835 }
836
837 if (!(!listener || typeof listener === 'function')) {
838 {
839 throw Error("Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type.");
840 }
841 }
842
843 return listener;
844}
845/**
846 * Allows registered plugins an opportunity to extract events from top-level
847 * native browser events.
848 *
849 * @return {*} An accumulation of synthetic events.
850 * @internal
851 */
852
853function extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
854 var events = null;
855
856 for (var i = 0; i < plugins.length; i++) {
857 // Not every plugin in the ordering may be loaded at runtime.
858 var possiblePlugin = plugins[i];
859
860 if (possiblePlugin) {
861 var extractedEvents = possiblePlugin.extractEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
862
863 if (extractedEvents) {
864 events = accumulateInto(events, extractedEvents);
865 }
866 }
867 }
868
869 return events;
870}
871
872function runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
873 var events = extractPluginEvents(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
874 runEventsInBatch(events);
875}
876
877var FunctionComponent = 0;
878var ClassComponent = 1;
879var IndeterminateComponent = 2; // Before we know whether it is function or class
880
881var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
882
883var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
884
885var HostComponent = 5;
886var HostText = 6;
887var Fragment = 7;
888var Mode = 8;
889var ContextConsumer = 9;
890var ContextProvider = 10;
891var ForwardRef = 11;
892var Profiler = 12;
893var SuspenseComponent = 13;
894var MemoComponent = 14;
895var SimpleMemoComponent = 15;
896var LazyComponent = 16;
897var IncompleteClassComponent = 17;
898var DehydratedFragment = 18;
899var SuspenseListComponent = 19;
900var FundamentalComponent = 20;
901var ScopeComponent = 21;
902
903var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED; // Prevent newer renderers from RTE when used with older react package versions.
904// Current owner and dispatcher used to share the same ref,
905// but PR #14548 split them out to better support the react-debug-tools package.
906
907if (!ReactSharedInternals.hasOwnProperty('ReactCurrentDispatcher')) {
908 ReactSharedInternals.ReactCurrentDispatcher = {
909 current: null
910 };
911}
912
913if (!ReactSharedInternals.hasOwnProperty('ReactCurrentBatchConfig')) {
914 ReactSharedInternals.ReactCurrentBatchConfig = {
915 suspense: null
916 };
917}
918
919var BEFORE_SLASH_RE = /^(.*)[\\\/]/;
920var describeComponentFrame = function (name, source, ownerName) {
921 var sourceInfo = '';
922
923 if (source) {
924 var path = source.fileName;
925 var fileName = path.replace(BEFORE_SLASH_RE, '');
926
927 {
928 // In DEV, include code for a common special case:
929 // prefer "folder/index.js" instead of just "index.js".
930 if (/^index\./.test(fileName)) {
931 var match = path.match(BEFORE_SLASH_RE);
932
933 if (match) {
934 var pathBeforeSlash = match[1];
935
936 if (pathBeforeSlash) {
937 var folderName = pathBeforeSlash.replace(BEFORE_SLASH_RE, '');
938 fileName = folderName + '/' + fileName;
939 }
940 }
941 }
942 }
943
944 sourceInfo = ' (at ' + fileName + ':' + source.lineNumber + ')';
945 } else if (ownerName) {
946 sourceInfo = ' (created by ' + ownerName + ')';
947 }
948
949 return '\n in ' + (name || 'Unknown') + sourceInfo;
950};
951
952// The Symbol used to tag the ReactElement-like types. If there is no native Symbol
953// nor polyfill, then a plain number is used for performance.
954var hasSymbol = typeof Symbol === 'function' && Symbol.for;
955var REACT_ELEMENT_TYPE = hasSymbol ? Symbol.for('react.element') : 0xeac7;
956var REACT_PORTAL_TYPE = hasSymbol ? Symbol.for('react.portal') : 0xeaca;
957var REACT_FRAGMENT_TYPE = hasSymbol ? Symbol.for('react.fragment') : 0xeacb;
958var REACT_STRICT_MODE_TYPE = hasSymbol ? Symbol.for('react.strict_mode') : 0xeacc;
959var REACT_PROFILER_TYPE = hasSymbol ? Symbol.for('react.profiler') : 0xead2;
960var REACT_PROVIDER_TYPE = hasSymbol ? Symbol.for('react.provider') : 0xeacd;
961var REACT_CONTEXT_TYPE = hasSymbol ? Symbol.for('react.context') : 0xeace; // TODO: We don't use AsyncMode or ConcurrentMode anymore. They were temporary
962// (unstable) APIs that have been removed. Can we remove the symbols?
963
964
965var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? Symbol.for('react.concurrent_mode') : 0xeacf;
966var REACT_FORWARD_REF_TYPE = hasSymbol ? Symbol.for('react.forward_ref') : 0xead0;
967var REACT_SUSPENSE_TYPE = hasSymbol ? Symbol.for('react.suspense') : 0xead1;
968var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? Symbol.for('react.suspense_list') : 0xead8;
969var REACT_MEMO_TYPE = hasSymbol ? Symbol.for('react.memo') : 0xead3;
970var REACT_LAZY_TYPE = hasSymbol ? Symbol.for('react.lazy') : 0xead4;
971var REACT_FUNDAMENTAL_TYPE = hasSymbol ? Symbol.for('react.fundamental') : 0xead5;
972var REACT_RESPONDER_TYPE = hasSymbol ? Symbol.for('react.responder') : 0xead6;
973var REACT_SCOPE_TYPE = hasSymbol ? Symbol.for('react.scope') : 0xead7;
974var MAYBE_ITERATOR_SYMBOL = typeof Symbol === 'function' && Symbol.iterator;
975var FAUX_ITERATOR_SYMBOL = '@@iterator';
976function getIteratorFn(maybeIterable) {
977 if (maybeIterable === null || typeof maybeIterable !== 'object') {
978 return null;
979 }
980
981 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
982
983 if (typeof maybeIterator === 'function') {
984 return maybeIterator;
985 }
986
987 return null;
988}
989
990/**
991 * Similar to invariant but only logs a warning if the condition is not met.
992 * This can be used to log issues in development environments in critical
993 * paths. Removing the logging code for production environments will keep the
994 * same logic and follow the same code paths.
995 */
996
997var warning = warningWithoutStack$1;
998
999{
1000 warning = function (condition, format) {
1001 if (condition) {
1002 return;
1003 }
1004
1005 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1006 var stack = ReactDebugCurrentFrame.getStackAddendum(); // eslint-disable-next-line react-internal/warning-and-invariant-args
1007
1008 for (var _len = arguments.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) {
1009 args[_key - 2] = arguments[_key];
1010 }
1011
1012 warningWithoutStack$1.apply(void 0, [false, format + '%s'].concat(args, [stack]));
1013 };
1014}
1015
1016var warning$1 = warning;
1017
1018var Uninitialized = -1;
1019var Pending = 0;
1020var Resolved = 1;
1021var Rejected = 2;
1022function refineResolvedLazyComponent(lazyComponent) {
1023 return lazyComponent._status === Resolved ? lazyComponent._result : null;
1024}
1025function initializeLazyComponentType(lazyComponent) {
1026 if (lazyComponent._status === Uninitialized) {
1027 lazyComponent._status = Pending;
1028 var ctor = lazyComponent._ctor;
1029 var thenable = ctor();
1030 lazyComponent._result = thenable;
1031 thenable.then(function (moduleObject) {
1032 if (lazyComponent._status === Pending) {
1033 var defaultExport = moduleObject.default;
1034
1035 {
1036 if (defaultExport === undefined) {
1037 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);
1038 }
1039 }
1040
1041 lazyComponent._status = Resolved;
1042 lazyComponent._result = defaultExport;
1043 }
1044 }, function (error) {
1045 if (lazyComponent._status === Pending) {
1046 lazyComponent._status = Rejected;
1047 lazyComponent._result = error;
1048 }
1049 });
1050 }
1051}
1052
1053function getWrappedName(outerType, innerType, wrapperName) {
1054 var functionName = innerType.displayName || innerType.name || '';
1055 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
1056}
1057
1058function getComponentName(type) {
1059 if (type == null) {
1060 // Host root, text node or just invalid type.
1061 return null;
1062 }
1063
1064 {
1065 if (typeof type.tag === 'number') {
1066 warningWithoutStack$1(false, 'Received an unexpected object in getComponentName(). ' + 'This is likely a bug in React. Please file an issue.');
1067 }
1068 }
1069
1070 if (typeof type === 'function') {
1071 return type.displayName || type.name || null;
1072 }
1073
1074 if (typeof type === 'string') {
1075 return type;
1076 }
1077
1078 switch (type) {
1079 case REACT_FRAGMENT_TYPE:
1080 return 'Fragment';
1081
1082 case REACT_PORTAL_TYPE:
1083 return 'Portal';
1084
1085 case REACT_PROFILER_TYPE:
1086 return "Profiler";
1087
1088 case REACT_STRICT_MODE_TYPE:
1089 return 'StrictMode';
1090
1091 case REACT_SUSPENSE_TYPE:
1092 return 'Suspense';
1093
1094 case REACT_SUSPENSE_LIST_TYPE:
1095 return 'SuspenseList';
1096 }
1097
1098 if (typeof type === 'object') {
1099 switch (type.$$typeof) {
1100 case REACT_CONTEXT_TYPE:
1101 return 'Context.Consumer';
1102
1103 case REACT_PROVIDER_TYPE:
1104 return 'Context.Provider';
1105
1106 case REACT_FORWARD_REF_TYPE:
1107 return getWrappedName(type, type.render, 'ForwardRef');
1108
1109 case REACT_MEMO_TYPE:
1110 return getComponentName(type.type);
1111
1112 case REACT_LAZY_TYPE:
1113 {
1114 var thenable = type;
1115 var resolvedThenable = refineResolvedLazyComponent(thenable);
1116
1117 if (resolvedThenable) {
1118 return getComponentName(resolvedThenable);
1119 }
1120
1121 break;
1122 }
1123 }
1124 }
1125
1126 return null;
1127}
1128
1129var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1130
1131function describeFiber(fiber) {
1132 switch (fiber.tag) {
1133 case HostRoot:
1134 case HostPortal:
1135 case HostText:
1136 case Fragment:
1137 case ContextProvider:
1138 case ContextConsumer:
1139 return '';
1140
1141 default:
1142 var owner = fiber._debugOwner;
1143 var source = fiber._debugSource;
1144 var name = getComponentName(fiber.type);
1145 var ownerName = null;
1146
1147 if (owner) {
1148 ownerName = getComponentName(owner.type);
1149 }
1150
1151 return describeComponentFrame(name, source, ownerName);
1152 }
1153}
1154
1155function getStackByFiberInDevAndProd(workInProgress) {
1156 var info = '';
1157 var node = workInProgress;
1158
1159 do {
1160 info += describeFiber(node);
1161 node = node.return;
1162 } while (node);
1163
1164 return info;
1165}
1166var current = null;
1167var phase = null;
1168function getCurrentFiberOwnerNameInDevOrNull() {
1169 {
1170 if (current === null) {
1171 return null;
1172 }
1173
1174 var owner = current._debugOwner;
1175
1176 if (owner !== null && typeof owner !== 'undefined') {
1177 return getComponentName(owner.type);
1178 }
1179 }
1180
1181 return null;
1182}
1183function getCurrentFiberStackInDev() {
1184 {
1185 if (current === null) {
1186 return '';
1187 } // Safe because if current fiber exists, we are reconciling,
1188 // and it is guaranteed to be the work-in-progress version.
1189
1190
1191 return getStackByFiberInDevAndProd(current);
1192 }
1193
1194 return '';
1195}
1196function resetCurrentFiber() {
1197 {
1198 ReactDebugCurrentFrame.getCurrentStack = null;
1199 current = null;
1200 phase = null;
1201 }
1202}
1203function setCurrentFiber(fiber) {
1204 {
1205 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1206 current = fiber;
1207 phase = null;
1208 }
1209}
1210function setCurrentPhase(lifeCyclePhase) {
1211 {
1212 phase = lifeCyclePhase;
1213 }
1214}
1215
1216var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
1217
1218function endsWith(subject, search) {
1219 var length = subject.length;
1220 return subject.substring(length - search.length, length) === search;
1221}
1222
1223var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1224var _assign = ReactInternals.assign;
1225
1226var PLUGIN_EVENT_SYSTEM = 1;
1227var RESPONDER_EVENT_SYSTEM = 1 << 1;
1228var IS_PASSIVE = 1 << 2;
1229var IS_ACTIVE = 1 << 3;
1230var PASSIVE_NOT_SUPPORTED = 1 << 4;
1231var IS_REPLAYED = 1 << 5;
1232
1233var restoreImpl = null;
1234var restoreTarget = null;
1235var restoreQueue = null;
1236
1237function restoreStateOfTarget(target) {
1238 // We perform this translation at the end of the event loop so that we
1239 // always receive the correct fiber here
1240 var internalInstance = getInstanceFromNode(target);
1241
1242 if (!internalInstance) {
1243 // Unmounted
1244 return;
1245 }
1246
1247 if (!(typeof restoreImpl === 'function')) {
1248 {
1249 throw Error("setRestoreImplementation() needs to be called to handle a target for controlled events. This error is likely caused by a bug in React. Please file an issue.");
1250 }
1251 }
1252
1253 var props = getFiberCurrentPropsFromNode(internalInstance.stateNode);
1254 restoreImpl(internalInstance.stateNode, internalInstance.type, props);
1255}
1256
1257function setRestoreImplementation(impl) {
1258 restoreImpl = impl;
1259}
1260function enqueueStateRestore(target) {
1261 if (restoreTarget) {
1262 if (restoreQueue) {
1263 restoreQueue.push(target);
1264 } else {
1265 restoreQueue = [target];
1266 }
1267 } else {
1268 restoreTarget = target;
1269 }
1270}
1271function needsStateRestore() {
1272 return restoreTarget !== null || restoreQueue !== null;
1273}
1274function restoreStateIfNeeded() {
1275 if (!restoreTarget) {
1276 return;
1277 }
1278
1279 var target = restoreTarget;
1280 var queuedTargets = restoreQueue;
1281 restoreTarget = null;
1282 restoreQueue = null;
1283 restoreStateOfTarget(target);
1284
1285 if (queuedTargets) {
1286 for (var i = 0; i < queuedTargets.length; i++) {
1287 restoreStateOfTarget(queuedTargets[i]);
1288 }
1289 }
1290}
1291
1292var enableUserTimingAPI = true; // Helps identify side effects in render-phase lifecycle hooks and setState
1293// reducers by double invoking them in Strict Mode.
1294
1295var debugRenderPhaseSideEffectsForStrictMode = true; // To preserve the "Pause on caught exceptions" behavior of the debugger, we
1296// replay the begin phase of a failed component inside invokeGuardedCallback.
1297
1298var replayFailedUnitOfWorkWithInvokeGuardedCallback = true; // Warn about deprecated, async-unsafe lifecycles; relates to RFC #6:
1299
1300var warnAboutDeprecatedLifecycles = true; // Gather advanced timing metrics for Profiler subtrees.
1301
1302var enableProfilerTimer = true; // Trace which interactions trigger each commit.
1303
1304var enableSchedulerTracing = true; // SSR experiments
1305
1306var enableSuspenseServerRenderer = false;
1307var enableSelectiveHydration = false; // Only used in www builds.
1308
1309 // Only used in www builds.
1310
1311 // Disable javascript: URL strings in href for XSS protection.
1312
1313var disableJavaScriptURLs = false; // React Fire: prevent the value and checked attributes from syncing
1314// with their related DOM properties
1315
1316var disableInputAttributeSyncing = false; // These APIs will no longer be "unstable" in the upcoming 16.7 release,
1317// Control this behavior with a flag to support 16.6 minor releases in the meanwhile.
1318
1319var exposeConcurrentModeAPIs = false;
1320var warnAboutShorthandPropertyCollision = false; // Experimental React Flare event system and event components support.
1321
1322var enableFlareAPI = false; // Experimental Host Component support.
1323
1324var enableFundamentalAPI = false; // Experimental Scope support.
1325
1326var enableScopeAPI = false; // New API for JSX transforms to target - https://github.com/reactjs/rfcs/pull/107
1327
1328 // We will enforce mocking scheduler with scheduler/unstable_mock at some point. (v17?)
1329// Till then, we warn about the missing mock, but still fallback to a legacy mode compatible version
1330
1331var warnAboutUnmockedScheduler = false; // For tests, we flush suspense fallbacks in an act scope;
1332// *except* in some of our own tests, where we test incremental loading states.
1333
1334var flushSuspenseFallbacksInTests = true; // Add a callback property to suspense to notify which promises are currently
1335// in the update queue. This allows reporting and tracing of what is causing
1336// the user to see a loading state.
1337// Also allows hydration callbacks to fire when a dehydrated boundary gets
1338// hydrated or deleted.
1339
1340var enableSuspenseCallback = false; // Part of the simplification of React.createElement so we can eventually move
1341// from React.createElement to React.jsx
1342// https://github.com/reactjs/rfcs/blob/createlement-rfc/text/0000-create-element-changes.md
1343
1344var warnAboutDefaultPropsOnFunctionComponents = false;
1345var warnAboutStringRefs = false;
1346var disableLegacyContext = false;
1347var disableSchedulerTimeoutBasedOnReactExpirationTime = false;
1348var enableTrustedTypesIntegration = false; // Flag to turn event.target and event.currentTarget in ReactNative from a reactTag to a component instance
1349
1350// the renderer. Such as when we're dispatching events or if third party
1351// libraries need to call batchedUpdates. Eventually, this API will go away when
1352// everything is batched by default. We'll then have a similar API to opt-out of
1353// scheduled work and instead do synchronous work.
1354// Defaults
1355
1356var batchedUpdatesImpl = function (fn, bookkeeping) {
1357 return fn(bookkeeping);
1358};
1359
1360var discreteUpdatesImpl = function (fn, a, b, c) {
1361 return fn(a, b, c);
1362};
1363
1364var flushDiscreteUpdatesImpl = function () {};
1365
1366var batchedEventUpdatesImpl = batchedUpdatesImpl;
1367var isInsideEventHandler = false;
1368var isBatchingEventUpdates = false;
1369
1370function finishEventHandler() {
1371 // Here we wait until all updates have propagated, which is important
1372 // when using controlled components within layers:
1373 // https://github.com/facebook/react/issues/1698
1374 // Then we restore state of any controlled component.
1375 var controlledComponentsHavePendingUpdates = needsStateRestore();
1376
1377 if (controlledComponentsHavePendingUpdates) {
1378 // If a controlled event was fired, we may need to restore the state of
1379 // the DOM node back to the controlled value. This is necessary when React
1380 // bails out of the update without touching the DOM.
1381 flushDiscreteUpdatesImpl();
1382 restoreStateIfNeeded();
1383 }
1384}
1385
1386function batchedUpdates(fn, bookkeeping) {
1387 if (isInsideEventHandler) {
1388 // If we are currently inside another batch, we need to wait until it
1389 // fully completes before restoring state.
1390 return fn(bookkeeping);
1391 }
1392
1393 isInsideEventHandler = true;
1394
1395 try {
1396 return batchedUpdatesImpl(fn, bookkeeping);
1397 } finally {
1398 isInsideEventHandler = false;
1399 finishEventHandler();
1400 }
1401}
1402function batchedEventUpdates(fn, a, b) {
1403 if (isBatchingEventUpdates) {
1404 // If we are currently inside another batch, we need to wait until it
1405 // fully completes before restoring state.
1406 return fn(a, b);
1407 }
1408
1409 isBatchingEventUpdates = true;
1410
1411 try {
1412 return batchedEventUpdatesImpl(fn, a, b);
1413 } finally {
1414 isBatchingEventUpdates = false;
1415 finishEventHandler();
1416 }
1417} // This is for the React Flare event system
1418
1419function executeUserEventHandler(fn, value) {
1420 var previouslyInEventHandler = isInsideEventHandler;
1421
1422 try {
1423 isInsideEventHandler = true;
1424 var type = typeof value === 'object' && value !== null ? value.type : '';
1425 invokeGuardedCallbackAndCatchFirstError(type, fn, undefined, value);
1426 } finally {
1427 isInsideEventHandler = previouslyInEventHandler;
1428 }
1429}
1430function discreteUpdates(fn, a, b, c) {
1431 var prevIsInsideEventHandler = isInsideEventHandler;
1432 isInsideEventHandler = true;
1433
1434 try {
1435 return discreteUpdatesImpl(fn, a, b, c);
1436 } finally {
1437 isInsideEventHandler = prevIsInsideEventHandler;
1438
1439 if (!isInsideEventHandler) {
1440 finishEventHandler();
1441 }
1442 }
1443}
1444var lastFlushedEventTimeStamp = 0;
1445function flushDiscreteUpdatesIfNeeded(timeStamp) {
1446 // event.timeStamp isn't overly reliable due to inconsistencies in
1447 // how different browsers have historically provided the time stamp.
1448 // Some browsers provide high-resolution time stamps for all events,
1449 // some provide low-resolution time stamps for all events. FF < 52
1450 // even mixes both time stamps together. Some browsers even report
1451 // negative time stamps or time stamps that are 0 (iOS9) in some cases.
1452 // Given we are only comparing two time stamps with equality (!==),
1453 // we are safe from the resolution differences. If the time stamp is 0
1454 // we bail-out of preventing the flush, which can affect semantics,
1455 // such as if an earlier flush removes or adds event listeners that
1456 // are fired in the subsequent flush. However, this is the same
1457 // behaviour as we had before this change, so the risks are low.
1458 if (!isInsideEventHandler && (!enableFlareAPI || timeStamp === 0 || lastFlushedEventTimeStamp !== timeStamp)) {
1459 lastFlushedEventTimeStamp = timeStamp;
1460 flushDiscreteUpdatesImpl();
1461 }
1462}
1463function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushDiscreteUpdatesImpl, _batchedEventUpdatesImpl) {
1464 batchedUpdatesImpl = _batchedUpdatesImpl;
1465 discreteUpdatesImpl = _discreteUpdatesImpl;
1466 flushDiscreteUpdatesImpl = _flushDiscreteUpdatesImpl;
1467 batchedEventUpdatesImpl = _batchedEventUpdatesImpl;
1468}
1469
1470var DiscreteEvent = 0;
1471var UserBlockingEvent = 1;
1472var ContinuousEvent = 2;
1473
1474var ReactInternals$1 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
1475var _ReactInternals$Sched = ReactInternals$1.Scheduler;
1476var unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback;
1477var unstable_now = _ReactInternals$Sched.unstable_now;
1478var unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback;
1479var unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield;
1480var unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint;
1481var unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode;
1482var unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority;
1483var unstable_next = _ReactInternals$Sched.unstable_next;
1484var unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution;
1485var unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution;
1486var unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel;
1487var unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority;
1488var unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority;
1489var unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority;
1490var unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority;
1491var unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority;
1492var unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate;
1493var unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting;
1494
1495// CommonJS interop named imports.
1496
1497var UserBlockingPriority = unstable_UserBlockingPriority;
1498var runWithPriority = unstable_runWithPriority;
1499var listenToResponderEventTypesImpl;
1500function setListenToResponderEventTypes(_listenToResponderEventTypesImpl) {
1501 listenToResponderEventTypesImpl = _listenToResponderEventTypesImpl;
1502}
1503var rootEventTypesToEventResponderInstances = new Map();
1504var DoNotPropagateToNextResponder = 0;
1505var PropagateToNextResponder = 1;
1506var currentTimeStamp = 0;
1507var currentInstance = null;
1508var currentDocument = null;
1509var currentPropagationBehavior = DoNotPropagateToNextResponder;
1510var eventResponderContext = {
1511 dispatchEvent: function (eventValue, eventListener, eventPriority) {
1512 validateResponderContext();
1513 validateEventValue(eventValue);
1514
1515 switch (eventPriority) {
1516 case DiscreteEvent:
1517 {
1518 flushDiscreteUpdatesIfNeeded(currentTimeStamp);
1519 discreteUpdates(function () {
1520 return executeUserEventHandler(eventListener, eventValue);
1521 });
1522 break;
1523 }
1524
1525 case UserBlockingEvent:
1526 {
1527 runWithPriority(UserBlockingPriority, function () {
1528 return executeUserEventHandler(eventListener, eventValue);
1529 });
1530 break;
1531 }
1532
1533 case ContinuousEvent:
1534 {
1535 executeUserEventHandler(eventListener, eventValue);
1536 break;
1537 }
1538 }
1539 },
1540 isTargetWithinResponder: function (target) {
1541 validateResponderContext();
1542
1543 if (target != null) {
1544 var fiber = getClosestInstanceFromNode(target);
1545 var responderFiber = currentInstance.fiber;
1546
1547 while (fiber !== null) {
1548 if (fiber === responderFiber || fiber.alternate === responderFiber) {
1549 return true;
1550 }
1551
1552 fiber = fiber.return;
1553 }
1554 }
1555
1556 return false;
1557 },
1558 isTargetWithinResponderScope: function (target) {
1559 validateResponderContext();
1560 var componentInstance = currentInstance;
1561 var responder = componentInstance.responder;
1562
1563 if (target != null) {
1564 var fiber = getClosestInstanceFromNode(target);
1565 var responderFiber = currentInstance.fiber;
1566
1567 while (fiber !== null) {
1568 if (fiber === responderFiber || fiber.alternate === responderFiber) {
1569 return true;
1570 }
1571
1572 if (doesFiberHaveResponder(fiber, responder)) {
1573 return false;
1574 }
1575
1576 fiber = fiber.return;
1577 }
1578 }
1579
1580 return false;
1581 },
1582 isTargetWithinNode: function (childTarget, parentTarget) {
1583 validateResponderContext();
1584 var childFiber = getClosestInstanceFromNode(childTarget);
1585 var parentFiber = getClosestInstanceFromNode(parentTarget);
1586
1587 if (childFiber != null && parentFiber != null) {
1588 var parentAlternateFiber = parentFiber.alternate;
1589 var node = childFiber;
1590
1591 while (node !== null) {
1592 if (node === parentFiber || node === parentAlternateFiber) {
1593 return true;
1594 }
1595
1596 node = node.return;
1597 }
1598
1599 return false;
1600 } // Fallback to DOM APIs
1601
1602
1603 return parentTarget.contains(childTarget);
1604 },
1605 addRootEventTypes: function (rootEventTypes) {
1606 validateResponderContext();
1607 listenToResponderEventTypesImpl(rootEventTypes, currentDocument);
1608
1609 for (var i = 0; i < rootEventTypes.length; i++) {
1610 var rootEventType = rootEventTypes[i];
1611 var eventResponderInstance = currentInstance;
1612 registerRootEventType(rootEventType, eventResponderInstance);
1613 }
1614 },
1615 removeRootEventTypes: function (rootEventTypes) {
1616 validateResponderContext();
1617
1618 for (var i = 0; i < rootEventTypes.length; i++) {
1619 var rootEventType = rootEventTypes[i];
1620 var rootEventResponders = rootEventTypesToEventResponderInstances.get(rootEventType);
1621 var rootEventTypesSet = currentInstance.rootEventTypes;
1622
1623 if (rootEventTypesSet !== null) {
1624 rootEventTypesSet.delete(rootEventType);
1625 }
1626
1627 if (rootEventResponders !== undefined) {
1628 rootEventResponders.delete(currentInstance);
1629 }
1630 }
1631 },
1632 getActiveDocument: getActiveDocument,
1633 objectAssign: _assign,
1634 getTimeStamp: function () {
1635 validateResponderContext();
1636 return currentTimeStamp;
1637 },
1638 isTargetWithinHostComponent: function (target, elementType) {
1639 validateResponderContext();
1640 var fiber = getClosestInstanceFromNode(target);
1641
1642 while (fiber !== null) {
1643 if (fiber.tag === HostComponent && fiber.type === elementType) {
1644 return true;
1645 }
1646
1647 fiber = fiber.return;
1648 }
1649
1650 return false;
1651 },
1652 continuePropagation: function () {
1653 currentPropagationBehavior = PropagateToNextResponder;
1654 },
1655 enqueueStateRestore: enqueueStateRestore,
1656 getResponderNode: function () {
1657 validateResponderContext();
1658 var responderFiber = currentInstance.fiber;
1659
1660 if (responderFiber.tag === ScopeComponent) {
1661 return null;
1662 }
1663
1664 return responderFiber.stateNode;
1665 }
1666};
1667
1668function validateEventValue(eventValue) {
1669 if (typeof eventValue === 'object' && eventValue !== null) {
1670 var target = eventValue.target,
1671 type = eventValue.type,
1672 timeStamp = eventValue.timeStamp;
1673
1674 if (target == null || type == null || timeStamp == null) {
1675 throw new Error('context.dispatchEvent: "target", "timeStamp", and "type" fields on event object are required.');
1676 }
1677
1678 var showWarning = function (name) {
1679 {
1680 warning$1(false, '%s is not available on event objects created from event responder modules (React Flare). ' + 'Try wrapping in a conditional, i.e. `if (event.type !== "press") { event.%s }`', name, name);
1681 }
1682 };
1683
1684 eventValue.isDefaultPrevented = function () {
1685 {
1686 showWarning('isDefaultPrevented()');
1687 }
1688 };
1689
1690 eventValue.isPropagationStopped = function () {
1691 {
1692 showWarning('isPropagationStopped()');
1693 }
1694 }; // $FlowFixMe: we don't need value, Flow thinks we do
1695
1696
1697 Object.defineProperty(eventValue, 'nativeEvent', {
1698 get: function () {
1699 {
1700 showWarning('nativeEvent');
1701 }
1702 }
1703 });
1704 }
1705}
1706
1707function doesFiberHaveResponder(fiber, responder) {
1708 var tag = fiber.tag;
1709
1710 if (tag === HostComponent || tag === ScopeComponent) {
1711 var dependencies = fiber.dependencies;
1712
1713 if (dependencies !== null) {
1714 var respondersMap = dependencies.responders;
1715
1716 if (respondersMap !== null && respondersMap.has(responder)) {
1717 return true;
1718 }
1719 }
1720 }
1721
1722 return false;
1723}
1724
1725function getActiveDocument() {
1726 return currentDocument;
1727}
1728
1729function createDOMResponderEvent(topLevelType, nativeEvent, nativeEventTarget, passive, passiveSupported) {
1730 var _ref = nativeEvent,
1731 buttons = _ref.buttons,
1732 pointerType = _ref.pointerType;
1733 var eventPointerType = '';
1734
1735 if (pointerType !== undefined) {
1736 eventPointerType = pointerType;
1737 } else if (nativeEvent.key !== undefined) {
1738 eventPointerType = 'keyboard';
1739 } else if (buttons !== undefined) {
1740 eventPointerType = 'mouse';
1741 } else if (nativeEvent.changedTouches !== undefined) {
1742 eventPointerType = 'touch';
1743 }
1744
1745 return {
1746 nativeEvent: nativeEvent,
1747 passive: passive,
1748 passiveSupported: passiveSupported,
1749 pointerType: eventPointerType,
1750 target: nativeEventTarget,
1751 type: topLevelType
1752 };
1753}
1754
1755function responderEventTypesContainType(eventTypes, type) {
1756 for (var i = 0, len = eventTypes.length; i < len; i++) {
1757 if (eventTypes[i] === type) {
1758 return true;
1759 }
1760 }
1761
1762 return false;
1763}
1764
1765function validateResponderTargetEventTypes(eventType, responder) {
1766 var targetEventTypes = responder.targetEventTypes; // Validate the target event type exists on the responder
1767
1768 if (targetEventTypes !== null) {
1769 return responderEventTypesContainType(targetEventTypes, eventType);
1770 }
1771
1772 return false;
1773}
1774
1775function traverseAndHandleEventResponderInstances(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags) {
1776 var isPassiveEvent = (eventSystemFlags & IS_PASSIVE) !== 0;
1777 var isPassiveSupported = (eventSystemFlags & PASSIVE_NOT_SUPPORTED) === 0;
1778 var isPassive = isPassiveEvent || !isPassiveSupported;
1779 var eventType = isPassive ? topLevelType : topLevelType + '_active'; // Trigger event responders in this order:
1780 // - Bubble target responder phase
1781 // - Root responder phase
1782
1783 var visitedResponders = new Set();
1784 var responderEvent = createDOMResponderEvent(topLevelType, nativeEvent, nativeEventTarget, isPassiveEvent, isPassiveSupported);
1785 var node = targetFiber;
1786 var insidePortal = false;
1787
1788 while (node !== null) {
1789 var _node = node,
1790 dependencies = _node.dependencies,
1791 tag = _node.tag;
1792
1793 if (tag === HostPortal) {
1794 insidePortal = true;
1795 } else if ((tag === HostComponent || tag === ScopeComponent) && dependencies !== null) {
1796 var respondersMap = dependencies.responders;
1797
1798 if (respondersMap !== null) {
1799 var responderInstances = Array.from(respondersMap.values());
1800
1801 for (var i = 0, length = responderInstances.length; i < length; i++) {
1802 var responderInstance = responderInstances[i];
1803 var props = responderInstance.props,
1804 responder = responderInstance.responder,
1805 state = responderInstance.state;
1806
1807 if (!visitedResponders.has(responder) && validateResponderTargetEventTypes(eventType, responder) && (!insidePortal || responder.targetPortalPropagation)) {
1808 visitedResponders.add(responder);
1809 var onEvent = responder.onEvent;
1810
1811 if (onEvent !== null) {
1812 currentInstance = responderInstance;
1813 onEvent(responderEvent, eventResponderContext, props, state);
1814
1815 if (currentPropagationBehavior === PropagateToNextResponder) {
1816 visitedResponders.delete(responder);
1817 currentPropagationBehavior = DoNotPropagateToNextResponder;
1818 }
1819 }
1820 }
1821 }
1822 }
1823 }
1824
1825 node = node.return;
1826 } // Root phase
1827
1828
1829 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(eventType);
1830
1831 if (rootEventResponderInstances !== undefined) {
1832 var _responderInstances = Array.from(rootEventResponderInstances);
1833
1834 for (var _i = 0; _i < _responderInstances.length; _i++) {
1835 var _responderInstance = _responderInstances[_i];
1836 var props = _responderInstance.props,
1837 responder = _responderInstance.responder,
1838 state = _responderInstance.state;
1839 var onRootEvent = responder.onRootEvent;
1840
1841 if (onRootEvent !== null) {
1842 currentInstance = _responderInstance;
1843 onRootEvent(responderEvent, eventResponderContext, props, state);
1844 }
1845 }
1846 }
1847}
1848
1849function mountEventResponder(responder, responderInstance, props, state) {
1850 var onMount = responder.onMount;
1851
1852 if (onMount !== null) {
1853 var previousInstance = currentInstance;
1854 currentInstance = responderInstance;
1855
1856 try {
1857 batchedEventUpdates(function () {
1858 onMount(eventResponderContext, props, state);
1859 });
1860 } finally {
1861 currentInstance = previousInstance;
1862 }
1863 }
1864}
1865function unmountEventResponder(responderInstance) {
1866 var responder = responderInstance.responder;
1867 var onUnmount = responder.onUnmount;
1868
1869 if (onUnmount !== null) {
1870 var props = responderInstance.props,
1871 state = responderInstance.state;
1872 var previousInstance = currentInstance;
1873 currentInstance = responderInstance;
1874
1875 try {
1876 batchedEventUpdates(function () {
1877 onUnmount(eventResponderContext, props, state);
1878 });
1879 } finally {
1880 currentInstance = previousInstance;
1881 }
1882 }
1883
1884 var rootEventTypesSet = responderInstance.rootEventTypes;
1885
1886 if (rootEventTypesSet !== null) {
1887 var rootEventTypes = Array.from(rootEventTypesSet);
1888
1889 for (var i = 0; i < rootEventTypes.length; i++) {
1890 var topLevelEventType = rootEventTypes[i];
1891 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(topLevelEventType);
1892
1893 if (rootEventResponderInstances !== undefined) {
1894 rootEventResponderInstances.delete(responderInstance);
1895 }
1896 }
1897 }
1898}
1899
1900function validateResponderContext() {
1901 if (!(currentInstance !== null)) {
1902 {
1903 throw Error("An event responder context was used outside of an event cycle.");
1904 }
1905 }
1906}
1907
1908function dispatchEventForResponderEventSystem(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags) {
1909 if (enableFlareAPI) {
1910 var previousInstance = currentInstance;
1911 var previousTimeStamp = currentTimeStamp;
1912 var previousDocument = currentDocument;
1913 var previousPropagationBehavior = currentPropagationBehavior;
1914 currentPropagationBehavior = DoNotPropagateToNextResponder; // nodeType 9 is DOCUMENT_NODE
1915
1916 currentDocument = nativeEventTarget.nodeType === 9 ? nativeEventTarget : nativeEventTarget.ownerDocument; // We might want to control timeStamp another way here
1917
1918 currentTimeStamp = nativeEvent.timeStamp;
1919
1920 try {
1921 batchedEventUpdates(function () {
1922 traverseAndHandleEventResponderInstances(topLevelType, targetFiber, nativeEvent, nativeEventTarget, eventSystemFlags);
1923 });
1924 } finally {
1925 currentInstance = previousInstance;
1926 currentTimeStamp = previousTimeStamp;
1927 currentDocument = previousDocument;
1928 currentPropagationBehavior = previousPropagationBehavior;
1929 }
1930 }
1931}
1932function addRootEventTypesForResponderInstance(responderInstance, rootEventTypes) {
1933 for (var i = 0; i < rootEventTypes.length; i++) {
1934 var rootEventType = rootEventTypes[i];
1935 registerRootEventType(rootEventType, responderInstance);
1936 }
1937}
1938
1939function registerRootEventType(rootEventType, eventResponderInstance) {
1940 var rootEventResponderInstances = rootEventTypesToEventResponderInstances.get(rootEventType);
1941
1942 if (rootEventResponderInstances === undefined) {
1943 rootEventResponderInstances = new Set();
1944 rootEventTypesToEventResponderInstances.set(rootEventType, rootEventResponderInstances);
1945 }
1946
1947 var rootEventTypesSet = eventResponderInstance.rootEventTypes;
1948
1949 if (rootEventTypesSet === null) {
1950 rootEventTypesSet = eventResponderInstance.rootEventTypes = new Set();
1951 }
1952
1953 if (!!rootEventTypesSet.has(rootEventType)) {
1954 {
1955 throw Error("addRootEventTypes() found a duplicate root event type of \"" + rootEventType + "\". This might be because the event type exists in the event responder \"rootEventTypes\" array or because of a previous addRootEventTypes() using this root event type.");
1956 }
1957 }
1958
1959 rootEventTypesSet.add(rootEventType);
1960 rootEventResponderInstances.add(eventResponderInstance);
1961}
1962
1963// A reserved attribute.
1964// It is handled by React separately and shouldn't be written to the DOM.
1965var RESERVED = 0; // A simple string attribute.
1966// Attributes that aren't in the whitelist are presumed to have this type.
1967
1968var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
1969// "enumerated" attributes with "true" and "false" as possible values.
1970// When true, it should be set to a "true" string.
1971// When false, it should be set to a "false" string.
1972
1973var BOOLEANISH_STRING = 2; // A real boolean attribute.
1974// When true, it should be present (set either to an empty string or its name).
1975// When false, it should be omitted.
1976
1977var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
1978// When true, it should be present (set either to an empty string or its name).
1979// When false, it should be omitted.
1980// For any other value, should be present with that value.
1981
1982var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
1983// When falsy, it should be removed.
1984
1985var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
1986// When falsy, it should be removed.
1987
1988var POSITIVE_NUMERIC = 6;
1989
1990/* eslint-disable max-len */
1991var ATTRIBUTE_NAME_START_CHAR = ":A-Z_a-z\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
1992/* eslint-enable max-len */
1993
1994var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
1995
1996var ROOT_ATTRIBUTE_NAME = 'data-reactroot';
1997var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
1998var hasOwnProperty = Object.prototype.hasOwnProperty;
1999var illegalAttributeNameCache = {};
2000var validatedAttributeNameCache = {};
2001function isAttributeNameSafe(attributeName) {
2002 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
2003 return true;
2004 }
2005
2006 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
2007 return false;
2008 }
2009
2010 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
2011 validatedAttributeNameCache[attributeName] = true;
2012 return true;
2013 }
2014
2015 illegalAttributeNameCache[attributeName] = true;
2016
2017 {
2018 warning$1(false, 'Invalid attribute name: `%s`', attributeName);
2019 }
2020
2021 return false;
2022}
2023function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
2024 if (propertyInfo !== null) {
2025 return propertyInfo.type === RESERVED;
2026 }
2027
2028 if (isCustomComponentTag) {
2029 return false;
2030 }
2031
2032 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
2033 return true;
2034 }
2035
2036 return false;
2037}
2038function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
2039 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
2040 return false;
2041 }
2042
2043 switch (typeof value) {
2044 case 'function': // $FlowIssue symbol is perfectly valid here
2045
2046 case 'symbol':
2047 // eslint-disable-line
2048 return true;
2049
2050 case 'boolean':
2051 {
2052 if (isCustomComponentTag) {
2053 return false;
2054 }
2055
2056 if (propertyInfo !== null) {
2057 return !propertyInfo.acceptsBooleans;
2058 } else {
2059 var prefix = name.toLowerCase().slice(0, 5);
2060 return prefix !== 'data-' && prefix !== 'aria-';
2061 }
2062 }
2063
2064 default:
2065 return false;
2066 }
2067}
2068function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
2069 if (value === null || typeof value === 'undefined') {
2070 return true;
2071 }
2072
2073 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
2074 return true;
2075 }
2076
2077 if (isCustomComponentTag) {
2078 return false;
2079 }
2080
2081 if (propertyInfo !== null) {
2082 switch (propertyInfo.type) {
2083 case BOOLEAN:
2084 return !value;
2085
2086 case OVERLOADED_BOOLEAN:
2087 return value === false;
2088
2089 case NUMERIC:
2090 return isNaN(value);
2091
2092 case POSITIVE_NUMERIC:
2093 return isNaN(value) || value < 1;
2094 }
2095 }
2096
2097 return false;
2098}
2099function getPropertyInfo(name) {
2100 return properties.hasOwnProperty(name) ? properties[name] : null;
2101}
2102
2103function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL) {
2104 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
2105 this.attributeName = attributeName;
2106 this.attributeNamespace = attributeNamespace;
2107 this.mustUseProperty = mustUseProperty;
2108 this.propertyName = name;
2109 this.type = type;
2110 this.sanitizeURL = sanitizeURL;
2111} // When adding attributes to this list, be sure to also add them to
2112// the `possibleStandardNames` module to ensure casing and incorrect
2113// name warnings.
2114
2115
2116var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
2117
2118['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
2119// elements (not just inputs). Now that ReactDOMInput assigns to the
2120// defaultValue property -- do we need this?
2121'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'].forEach(function (name) {
2122 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
2123 name, // attributeName
2124 null, // attributeNamespace
2125 false);
2126}); // A few React string attributes have a different name.
2127// This is a mapping from React prop names to the attribute names.
2128
2129[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
2130 var name = _ref[0],
2131 attributeName = _ref[1];
2132 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2133 attributeName, // attributeName
2134 null, // attributeNamespace
2135 false);
2136}); // These are "enumerated" HTML attributes that accept "true" and "false".
2137// In React, we let users pass `true` and `false` even though technically
2138// these aren't boolean attributes (they are coerced to strings).
2139
2140['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
2141 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2142 name.toLowerCase(), // attributeName
2143 null, // attributeNamespace
2144 false);
2145}); // These are "enumerated" SVG attributes that accept "true" and "false".
2146// In React, we let users pass `true` and `false` even though technically
2147// these aren't boolean attributes (they are coerced to strings).
2148// Since these are SVG attributes, their attribute names are case-sensitive.
2149
2150['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
2151 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
2152 name, // attributeName
2153 null, // attributeNamespace
2154 false);
2155}); // These are HTML boolean attributes.
2156
2157['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
2158// on the client side because the browsers are inconsistent. Instead we call focus().
2159'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
2160'itemScope'].forEach(function (name) {
2161 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
2162 name.toLowerCase(), // attributeName
2163 null, // attributeNamespace
2164 false);
2165}); // These are the few React props that we set as DOM properties
2166// rather than attributes. These are all booleans.
2167
2168['checked', // Note: `option.selected` is not updated if `select.multiple` is
2169// disabled with `removeAttribute`. We have special logic for handling this.
2170'multiple', 'muted', 'selected'].forEach(function (name) {
2171 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
2172 name, // attributeName
2173 null, // attributeNamespace
2174 false);
2175}); // These are HTML attributes that are "overloaded booleans": they behave like
2176// booleans, but can also accept a string value.
2177
2178['capture', 'download'].forEach(function (name) {
2179 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
2180 name, // attributeName
2181 null, // attributeNamespace
2182 false);
2183}); // These are HTML attributes that must be positive numbers.
2184
2185['cols', 'rows', 'size', 'span'].forEach(function (name) {
2186 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
2187 name, // attributeName
2188 null, // attributeNamespace
2189 false);
2190}); // These are HTML attributes that must be numbers.
2191
2192['rowSpan', 'start'].forEach(function (name) {
2193 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
2194 name.toLowerCase(), // attributeName
2195 null, // attributeNamespace
2196 false);
2197});
2198var CAMELIZE = /[\-\:]([a-z])/g;
2199
2200var capitalize = function (token) {
2201 return token[1].toUpperCase();
2202}; // This is a list of all SVG attributes that need special casing, namespacing,
2203// or boolean value assignment. Regular attributes that just accept strings
2204// and have the same names are omitted, just like in the HTML whitelist.
2205// Some of these attributes can be hard to find. This list was created by
2206// scrapping the MDN documentation.
2207
2208
2209['accent-height', 'alignment-baseline', 'arabic-form', 'baseline-shift', 'cap-height', 'clip-path', 'clip-rule', 'color-interpolation', 'color-interpolation-filters', 'color-profile', 'color-rendering', 'dominant-baseline', 'enable-background', 'fill-opacity', 'fill-rule', 'flood-color', 'flood-opacity', 'font-family', 'font-size', 'font-size-adjust', 'font-stretch', 'font-style', 'font-variant', 'font-weight', 'glyph-name', 'glyph-orientation-horizontal', 'glyph-orientation-vertical', 'horiz-adv-x', 'horiz-origin-x', 'image-rendering', 'letter-spacing', 'lighting-color', 'marker-end', 'marker-mid', 'marker-start', 'overline-position', 'overline-thickness', 'paint-order', 'panose-1', 'pointer-events', 'rendering-intent', 'shape-rendering', 'stop-color', 'stop-opacity', 'strikethrough-position', 'strikethrough-thickness', 'stroke-dasharray', 'stroke-dashoffset', 'stroke-linecap', 'stroke-linejoin', 'stroke-miterlimit', 'stroke-opacity', 'stroke-width', 'text-anchor', 'text-decoration', 'text-rendering', 'underline-position', 'underline-thickness', 'unicode-bidi', 'unicode-range', 'units-per-em', 'v-alphabetic', 'v-hanging', 'v-ideographic', 'v-mathematical', 'vector-effect', 'vert-adv-y', 'vert-origin-x', 'vert-origin-y', 'word-spacing', 'writing-mode', 'xmlns:xlink', 'x-height'].forEach(function (attributeName) {
2210 var name = attributeName.replace(CAMELIZE, capitalize);
2211 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2212 attributeName, null, // attributeNamespace
2213 false);
2214}); // String SVG attributes with the xlink namespace.
2215
2216['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type'].forEach(function (attributeName) {
2217 var name = attributeName.replace(CAMELIZE, capitalize);
2218 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2219 attributeName, 'http://www.w3.org/1999/xlink', false);
2220}); // String SVG attributes with the xml namespace.
2221
2222['xml:base', 'xml:lang', 'xml:space'].forEach(function (attributeName) {
2223 var name = attributeName.replace(CAMELIZE, capitalize);
2224 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
2225 attributeName, 'http://www.w3.org/XML/1998/namespace', false);
2226}); // These attribute exists both in HTML and SVG.
2227// The attribute name is case-sensitive in SVG so we can't just use
2228// the React name like we do for attributes that exist only in HTML.
2229
2230['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
2231 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
2232 attributeName.toLowerCase(), // attributeName
2233 null, // attributeNamespace
2234 false);
2235}); // These attributes accept URLs. These must not allow javascript: URLS.
2236// These will also need to accept Trusted Types object in the future.
2237
2238var xlinkHref = 'xlinkHref';
2239properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
2240'xlink:href', 'http://www.w3.org/1999/xlink', true);
2241['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
2242 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
2243 attributeName.toLowerCase(), // attributeName
2244 null, // attributeNamespace
2245 true);
2246});
2247
2248var ReactDebugCurrentFrame$1 = null;
2249
2250{
2251 ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
2252} // A javascript: URL can contain leading C0 control or \u0020 SPACE,
2253// and any newline or tab are filtered out as if they're not part of the URL.
2254// https://url.spec.whatwg.org/#url-parsing
2255// Tab or newline are defined as \r\n\t:
2256// https://infra.spec.whatwg.org/#ascii-tab-or-newline
2257// A C0 control is a code point in the range \u0000 NULL to \u001F
2258// INFORMATION SEPARATOR ONE, inclusive:
2259// https://infra.spec.whatwg.org/#c0-control-or-space
2260
2261/* eslint-disable max-len */
2262
2263
2264var isJavaScriptProtocol = /^[\u0000-\u001F ]*j[\r\n\t]*a[\r\n\t]*v[\r\n\t]*a[\r\n\t]*s[\r\n\t]*c[\r\n\t]*r[\r\n\t]*i[\r\n\t]*p[\r\n\t]*t[\r\n\t]*\:/i;
2265var didWarn = false;
2266
2267function sanitizeURL(url) {
2268 if (disableJavaScriptURLs) {
2269 if (!!isJavaScriptProtocol.test(url)) {
2270 {
2271 throw Error("React has blocked a javascript: URL as a security precaution." + (ReactDebugCurrentFrame$1.getStackAddendum()));
2272 }
2273 }
2274 } else if (true && !didWarn && isJavaScriptProtocol.test(url)) {
2275 didWarn = true;
2276 warning$1(false, 'A future version of React will block javascript: URLs as a security precaution. ' + 'Use event handlers instead if you can. If you need to generate unsafe HTML try ' + 'using dangerouslySetInnerHTML instead. React was passed %s.', JSON.stringify(url));
2277 }
2278}
2279
2280// Flow does not allow string concatenation of most non-string types. To work
2281// around this limitation, we use an opaque type that can only be obtained by
2282// passing the value through getToStringValue first.
2283function toString(value) {
2284 return '' + value;
2285}
2286function getToStringValue(value) {
2287 switch (typeof value) {
2288 case 'boolean':
2289 case 'number':
2290 case 'object':
2291 case 'string':
2292 case 'undefined':
2293 return value;
2294
2295 default:
2296 // function, symbol are assigned as empty strings
2297 return '';
2298 }
2299}
2300/** Trusted value is a wrapper for "safe" values which can be assigned to DOM execution sinks. */
2301
2302/**
2303 * We allow passing objects with toString method as element attributes or in dangerouslySetInnerHTML
2304 * and we do validations that the value is safe. Once we do validation we want to use the validated
2305 * value instead of the object (because object.toString may return something else on next call).
2306 *
2307 * If application uses Trusted Types we don't stringify trusted values, but preserve them as objects.
2308 */
2309var toStringOrTrustedType = toString;
2310
2311if (enableTrustedTypesIntegration && typeof trustedTypes !== 'undefined') {
2312 toStringOrTrustedType = function (value) {
2313 if (typeof value === 'object' && (trustedTypes.isHTML(value) || trustedTypes.isScript(value) || trustedTypes.isScriptURL(value) ||
2314 /* TrustedURLs are deprecated and will be removed soon: https://github.com/WICG/trusted-types/pull/204 */
2315 trustedTypes.isURL && trustedTypes.isURL(value))) {
2316 // Pass Trusted Types through.
2317 return value;
2318 }
2319
2320 return toString(value);
2321 };
2322}
2323
2324/**
2325 * Set attribute for a node. The attribute value can be either string or
2326 * Trusted value (if application uses Trusted Types).
2327 */
2328function setAttribute(node, attributeName, attributeValue) {
2329 node.setAttribute(attributeName, attributeValue);
2330}
2331/**
2332 * Set attribute with namespace for a node. The attribute value can be either string or
2333 * Trusted value (if application uses Trusted Types).
2334 */
2335
2336function setAttributeNS(node, attributeNamespace, attributeName, attributeValue) {
2337 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
2338}
2339
2340/**
2341 * Get the value for a property on a node. Only used in DEV for SSR validation.
2342 * The "expected" argument is used as a hint of what the expected value is.
2343 * Some properties have multiple equivalent values.
2344 */
2345function getValueForProperty(node, name, expected, propertyInfo) {
2346 {
2347 if (propertyInfo.mustUseProperty) {
2348 var propertyName = propertyInfo.propertyName;
2349 return node[propertyName];
2350 } else {
2351 if (!disableJavaScriptURLs && propertyInfo.sanitizeURL) {
2352 // If we haven't fully disabled javascript: URLs, and if
2353 // the hydration is successful of a javascript: URL, we
2354 // still want to warn on the client.
2355 sanitizeURL('' + expected);
2356 }
2357
2358 var attributeName = propertyInfo.attributeName;
2359 var stringValue = null;
2360
2361 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
2362 if (node.hasAttribute(attributeName)) {
2363 var value = node.getAttribute(attributeName);
2364
2365 if (value === '') {
2366 return true;
2367 }
2368
2369 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2370 return value;
2371 }
2372
2373 if (value === '' + expected) {
2374 return expected;
2375 }
2376
2377 return value;
2378 }
2379 } else if (node.hasAttribute(attributeName)) {
2380 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2381 // We had an attribute but shouldn't have had one, so read it
2382 // for the error message.
2383 return node.getAttribute(attributeName);
2384 }
2385
2386 if (propertyInfo.type === BOOLEAN) {
2387 // If this was a boolean, it doesn't matter what the value is
2388 // the fact that we have it is the same as the expected.
2389 return expected;
2390 } // Even if this property uses a namespace we use getAttribute
2391 // because we assume its namespaced name is the same as our config.
2392 // To use getAttributeNS we need the local name which we don't have
2393 // in our config atm.
2394
2395
2396 stringValue = node.getAttribute(attributeName);
2397 }
2398
2399 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
2400 return stringValue === null ? expected : stringValue;
2401 } else if (stringValue === '' + expected) {
2402 return expected;
2403 } else {
2404 return stringValue;
2405 }
2406 }
2407 }
2408}
2409/**
2410 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
2411 * The third argument is used as a hint of what the expected value is. Some
2412 * attributes have multiple equivalent values.
2413 */
2414
2415function getValueForAttribute(node, name, expected) {
2416 {
2417 if (!isAttributeNameSafe(name)) {
2418 return;
2419 }
2420
2421 if (!node.hasAttribute(name)) {
2422 return expected === undefined ? undefined : null;
2423 }
2424
2425 var value = node.getAttribute(name);
2426
2427 if (value === '' + expected) {
2428 return expected;
2429 }
2430
2431 return value;
2432 }
2433}
2434/**
2435 * Sets the value for a property on a node.
2436 *
2437 * @param {DOMElement} node
2438 * @param {string} name
2439 * @param {*} value
2440 */
2441
2442function setValueForProperty(node, name, value, isCustomComponentTag) {
2443 var propertyInfo = getPropertyInfo(name);
2444
2445 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
2446 return;
2447 }
2448
2449 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
2450 value = null;
2451 } // If the prop isn't in the special list, treat it as a simple attribute.
2452
2453
2454 if (isCustomComponentTag || propertyInfo === null) {
2455 if (isAttributeNameSafe(name)) {
2456 var _attributeName = name;
2457
2458 if (value === null) {
2459 node.removeAttribute(_attributeName);
2460 } else {
2461 setAttribute(node, _attributeName, toStringOrTrustedType(value));
2462 }
2463 }
2464
2465 return;
2466 }
2467
2468 var mustUseProperty = propertyInfo.mustUseProperty;
2469
2470 if (mustUseProperty) {
2471 var propertyName = propertyInfo.propertyName;
2472
2473 if (value === null) {
2474 var type = propertyInfo.type;
2475 node[propertyName] = type === BOOLEAN ? false : '';
2476 } else {
2477 // Contrary to `setAttribute`, object properties are properly
2478 // `toString`ed by IE8/9.
2479 node[propertyName] = value;
2480 }
2481
2482 return;
2483 } // The rest are treated as attributes with special cases.
2484
2485
2486 var attributeName = propertyInfo.attributeName,
2487 attributeNamespace = propertyInfo.attributeNamespace;
2488
2489 if (value === null) {
2490 node.removeAttribute(attributeName);
2491 } else {
2492 var _type = propertyInfo.type;
2493 var attributeValue;
2494
2495 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
2496 // If attribute type is boolean, we know for sure it won't be an execution sink
2497 // and we won't require Trusted Type here.
2498 attributeValue = '';
2499 } else {
2500 // `setAttribute` with objects becomes only `[object]` in IE8/9,
2501 // ('' + value) makes it output the correct toString()-value.
2502 attributeValue = toStringOrTrustedType(value);
2503
2504 if (propertyInfo.sanitizeURL) {
2505 sanitizeURL(attributeValue.toString());
2506 }
2507 }
2508
2509 if (attributeNamespace) {
2510 setAttributeNS(node, attributeNamespace, attributeName, attributeValue);
2511 } else {
2512 setAttribute(node, attributeName, attributeValue);
2513 }
2514 }
2515}
2516
2517/**
2518 * Copyright (c) 2013-present, Facebook, Inc.
2519 *
2520 * This source code is licensed under the MIT license found in the
2521 * LICENSE file in the root directory of this source tree.
2522 */
2523
2524
2525
2526var ReactPropTypesSecret$1 = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';
2527
2528var ReactPropTypesSecret_1 = ReactPropTypesSecret$1;
2529
2530/**
2531 * Copyright (c) 2013-present, Facebook, Inc.
2532 *
2533 * This source code is licensed under the MIT license found in the
2534 * LICENSE file in the root directory of this source tree.
2535 */
2536
2537
2538
2539var printWarning = function() {};
2540
2541{
2542 var ReactPropTypesSecret = ReactPropTypesSecret_1;
2543 var loggedTypeFailures = {};
2544 var has = Function.call.bind(Object.prototype.hasOwnProperty);
2545
2546 printWarning = function(text) {
2547 var message = 'Warning: ' + text;
2548 if (typeof console !== 'undefined') {
2549 console.error(message);
2550 }
2551 try {
2552 // --- Welcome to debugging React ---
2553 // This error was thrown as a convenience so that you can use this stack
2554 // to find the callsite that caused this warning to fire.
2555 throw new Error(message);
2556 } catch (x) {}
2557 };
2558}
2559
2560/**
2561 * Assert that the values match with the type specs.
2562 * Error messages are memorized and will only be shown once.
2563 *
2564 * @param {object} typeSpecs Map of name to a ReactPropType
2565 * @param {object} values Runtime values that need to be type-checked
2566 * @param {string} location e.g. "prop", "context", "child context"
2567 * @param {string} componentName Name of the component for error messages.
2568 * @param {?Function} getStack Returns the component stack.
2569 * @private
2570 */
2571function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
2572 {
2573 for (var typeSpecName in typeSpecs) {
2574 if (has(typeSpecs, typeSpecName)) {
2575 var error;
2576 // Prop type validation may throw. In case they do, we don't want to
2577 // fail the render phase where it didn't fail before. So we log it.
2578 // After these have been cleaned up, we'll let them throw.
2579 try {
2580 // This is intentionally an invariant that gets caught. It's the same
2581 // behavior as without this statement except with a better message.
2582 if (typeof typeSpecs[typeSpecName] !== 'function') {
2583 var err = Error(
2584 (componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' +
2585 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.'
2586 );
2587 err.name = 'Invariant Violation';
2588 throw err;
2589 }
2590 error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
2591 } catch (ex) {
2592 error = ex;
2593 }
2594 if (error && !(error instanceof Error)) {
2595 printWarning(
2596 (componentName || 'React class') + ': type specification of ' +
2597 location + ' `' + typeSpecName + '` is invalid; the type checker ' +
2598 'function must return `null` or an `Error` but returned a ' + typeof error + '. ' +
2599 'You may have forgotten to pass an argument to the type checker ' +
2600 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' +
2601 'shape all require an argument).'
2602 );
2603 }
2604 if (error instanceof Error && !(error.message in loggedTypeFailures)) {
2605 // Only monitor this failure once because there tends to be a lot of the
2606 // same error.
2607 loggedTypeFailures[error.message] = true;
2608
2609 var stack = getStack ? getStack() : '';
2610
2611 printWarning(
2612 'Failed ' + location + ' type: ' + error.message + (stack != null ? stack : '')
2613 );
2614 }
2615 }
2616 }
2617 }
2618}
2619
2620/**
2621 * Resets warning cache when testing.
2622 *
2623 * @private
2624 */
2625checkPropTypes.resetWarningCache = function() {
2626 {
2627 loggedTypeFailures = {};
2628 }
2629};
2630
2631var checkPropTypes_1 = checkPropTypes;
2632
2633var ReactDebugCurrentFrame$2 = null;
2634var ReactControlledValuePropTypes = {
2635 checkPropTypes: null
2636};
2637
2638{
2639 ReactDebugCurrentFrame$2 = ReactSharedInternals.ReactDebugCurrentFrame;
2640 var hasReadOnlyValue = {
2641 button: true,
2642 checkbox: true,
2643 image: true,
2644 hidden: true,
2645 radio: true,
2646 reset: true,
2647 submit: true
2648 };
2649 var propTypes = {
2650 value: function (props, propName, componentName) {
2651 if (hasReadOnlyValue[props.type] || props.onChange || props.readOnly || props.disabled || props[propName] == null || enableFlareAPI && props.listeners) {
2652 return null;
2653 }
2654
2655 return new Error('You provided a `value` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultValue`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
2656 },
2657 checked: function (props, propName, componentName) {
2658 if (props.onChange || props.readOnly || props.disabled || props[propName] == null || enableFlareAPI && props.listeners) {
2659 return null;
2660 }
2661
2662 return new Error('You provided a `checked` prop to a form field without an ' + '`onChange` handler. This will render a read-only field. If ' + 'the field should be mutable use `defaultChecked`. Otherwise, ' + 'set either `onChange` or `readOnly`.');
2663 }
2664 };
2665 /**
2666 * Provide a linked `value` attribute for controlled forms. You should not use
2667 * this outside of the ReactDOM controlled form components.
2668 */
2669
2670 ReactControlledValuePropTypes.checkPropTypes = function (tagName, props) {
2671 checkPropTypes_1(propTypes, props, 'prop', tagName, ReactDebugCurrentFrame$2.getStackAddendum);
2672 };
2673}
2674
2675function isCheckable(elem) {
2676 var type = elem.type;
2677 var nodeName = elem.nodeName;
2678 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
2679}
2680
2681function getTracker(node) {
2682 return node._valueTracker;
2683}
2684
2685function detachTracker(node) {
2686 node._valueTracker = null;
2687}
2688
2689function getValueFromNode(node) {
2690 var value = '';
2691
2692 if (!node) {
2693 return value;
2694 }
2695
2696 if (isCheckable(node)) {
2697 value = node.checked ? 'true' : 'false';
2698 } else {
2699 value = node.value;
2700 }
2701
2702 return value;
2703}
2704
2705function trackValueOnNode(node) {
2706 var valueField = isCheckable(node) ? 'checked' : 'value';
2707 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
2708 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
2709 // and don't track value will cause over reporting of changes,
2710 // but it's better then a hard failure
2711 // (needed for certain tests that spyOn input values and Safari)
2712
2713 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
2714 return;
2715 }
2716
2717 var get = descriptor.get,
2718 set = descriptor.set;
2719 Object.defineProperty(node, valueField, {
2720 configurable: true,
2721 get: function () {
2722 return get.call(this);
2723 },
2724 set: function (value) {
2725 currentValue = '' + value;
2726 set.call(this, value);
2727 }
2728 }); // We could've passed this the first time
2729 // but it triggers a bug in IE11 and Edge 14/15.
2730 // Calling defineProperty() again should be equivalent.
2731 // https://github.com/facebook/react/issues/11768
2732
2733 Object.defineProperty(node, valueField, {
2734 enumerable: descriptor.enumerable
2735 });
2736 var tracker = {
2737 getValue: function () {
2738 return currentValue;
2739 },
2740 setValue: function (value) {
2741 currentValue = '' + value;
2742 },
2743 stopTracking: function () {
2744 detachTracker(node);
2745 delete node[valueField];
2746 }
2747 };
2748 return tracker;
2749}
2750
2751function track(node) {
2752 if (getTracker(node)) {
2753 return;
2754 } // TODO: Once it's just Fiber we can move this to node._wrapperState
2755
2756
2757 node._valueTracker = trackValueOnNode(node);
2758}
2759function updateValueIfChanged(node) {
2760 if (!node) {
2761 return false;
2762 }
2763
2764 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
2765 // that trying again will succeed
2766
2767 if (!tracker) {
2768 return true;
2769 }
2770
2771 var lastValue = tracker.getValue();
2772 var nextValue = getValueFromNode(node);
2773
2774 if (nextValue !== lastValue) {
2775 tracker.setValue(nextValue);
2776 return true;
2777 }
2778
2779 return false;
2780}
2781
2782// TODO: direct imports like some-package/src/* are bad. Fix me.
2783var didWarnValueDefaultValue = false;
2784var didWarnCheckedDefaultChecked = false;
2785var didWarnControlledToUncontrolled = false;
2786var didWarnUncontrolledToControlled = false;
2787
2788function isControlled(props) {
2789 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
2790 return usesChecked ? props.checked != null : props.value != null;
2791}
2792/**
2793 * Implements an <input> host component that allows setting these optional
2794 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
2795 *
2796 * If `checked` or `value` are not supplied (or null/undefined), user actions
2797 * that affect the checked state or value will trigger updates to the element.
2798 *
2799 * If they are supplied (and not null/undefined), the rendered element will not
2800 * trigger updates to the element. Instead, the props must change in order for
2801 * the rendered element to be updated.
2802 *
2803 * The rendered element will be initialized as unchecked (or `defaultChecked`)
2804 * with an empty value (or `defaultValue`).
2805 *
2806 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
2807 */
2808
2809
2810function getHostProps(element, props) {
2811 var node = element;
2812 var checked = props.checked;
2813
2814 var hostProps = _assign({}, props, {
2815 defaultChecked: undefined,
2816 defaultValue: undefined,
2817 value: undefined,
2818 checked: checked != null ? checked : node._wrapperState.initialChecked
2819 });
2820
2821 return hostProps;
2822}
2823function initWrapperState(element, props) {
2824 {
2825 ReactControlledValuePropTypes.checkPropTypes('input', props);
2826
2827 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
2828 warning$1(false, '%s contains an input of type %s with both checked and defaultChecked props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the checked prop, or the defaultChecked prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
2829 didWarnCheckedDefaultChecked = true;
2830 }
2831
2832 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
2833 warning$1(false, '%s contains an input of type %s with both value and defaultValue props. ' + 'Input elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled input ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
2834 didWarnValueDefaultValue = true;
2835 }
2836 }
2837
2838 var node = element;
2839 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
2840 node._wrapperState = {
2841 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
2842 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
2843 controlled: isControlled(props)
2844 };
2845}
2846function updateChecked(element, props) {
2847 var node = element;
2848 var checked = props.checked;
2849
2850 if (checked != null) {
2851 setValueForProperty(node, 'checked', checked, false);
2852 }
2853}
2854function updateWrapper(element, props) {
2855 var node = element;
2856
2857 {
2858 var controlled = isControlled(props);
2859
2860 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
2861 warning$1(false, 'A component is changing an uncontrolled input of type %s to be controlled. ' + 'Input elements should not switch from uncontrolled to controlled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
2862 didWarnUncontrolledToControlled = true;
2863 }
2864
2865 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
2866 warning$1(false, 'A component is changing a controlled input of type %s to be uncontrolled. ' + 'Input elements should not switch from controlled to uncontrolled (or vice versa). ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://fb.me/react-controlled-components', props.type);
2867 didWarnControlledToUncontrolled = true;
2868 }
2869 }
2870
2871 updateChecked(element, props);
2872 var value = getToStringValue(props.value);
2873 var type = props.type;
2874
2875 if (value != null) {
2876 if (type === 'number') {
2877 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
2878 // eslint-disable-next-line
2879 node.value != value) {
2880 node.value = toString(value);
2881 }
2882 } else if (node.value !== toString(value)) {
2883 node.value = toString(value);
2884 }
2885 } else if (type === 'submit' || type === 'reset') {
2886 // Submit/reset inputs need the attribute removed completely to avoid
2887 // blank-text buttons.
2888 node.removeAttribute('value');
2889 return;
2890 }
2891
2892 if (disableInputAttributeSyncing) {
2893 // When not syncing the value attribute, React only assigns a new value
2894 // whenever the defaultValue React prop has changed. When not present,
2895 // React does nothing
2896 if (props.hasOwnProperty('defaultValue')) {
2897 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
2898 }
2899 } else {
2900 // When syncing the value attribute, the value comes from a cascade of
2901 // properties:
2902 // 1. The value React property
2903 // 2. The defaultValue React property
2904 // 3. Otherwise there should be no change
2905 if (props.hasOwnProperty('value')) {
2906 setDefaultValue(node, props.type, value);
2907 } else if (props.hasOwnProperty('defaultValue')) {
2908 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
2909 }
2910 }
2911
2912 if (disableInputAttributeSyncing) {
2913 // When not syncing the checked attribute, the attribute is directly
2914 // controllable from the defaultValue React property. It needs to be
2915 // updated as new props come in.
2916 if (props.defaultChecked == null) {
2917 node.removeAttribute('checked');
2918 } else {
2919 node.defaultChecked = !!props.defaultChecked;
2920 }
2921 } else {
2922 // When syncing the checked attribute, it only changes when it needs
2923 // to be removed, such as transitioning from a checkbox into a text input
2924 if (props.checked == null && props.defaultChecked != null) {
2925 node.defaultChecked = !!props.defaultChecked;
2926 }
2927 }
2928}
2929function postMountWrapper(element, props, isHydrating) {
2930 var node = element; // Do not assign value if it is already set. This prevents user text input
2931 // from being lost during SSR hydration.
2932
2933 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
2934 var type = props.type;
2935 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
2936 // default value provided by the browser. See: #12872
2937
2938 if (isButton && (props.value === undefined || props.value === null)) {
2939 return;
2940 }
2941
2942 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
2943 // from being lost during SSR hydration.
2944
2945 if (!isHydrating) {
2946 if (disableInputAttributeSyncing) {
2947 var value = getToStringValue(props.value); // When not syncing the value attribute, the value property points
2948 // directly to the React prop. Only assign it if it exists.
2949
2950 if (value != null) {
2951 // Always assign on buttons so that it is possible to assign an
2952 // empty string to clear button text.
2953 //
2954 // Otherwise, do not re-assign the value property if is empty. This
2955 // potentially avoids a DOM write and prevents Firefox (~60.0.1) from
2956 // prematurely marking required inputs as invalid. Equality is compared
2957 // to the current value in case the browser provided value is not an
2958 // empty string.
2959 if (isButton || value !== node.value) {
2960 node.value = toString(value);
2961 }
2962 }
2963 } else {
2964 // When syncing the value attribute, the value property should use
2965 // the wrapperState._initialValue property. This uses:
2966 //
2967 // 1. The value React property when present
2968 // 2. The defaultValue React property when present
2969 // 3. An empty string
2970 if (initialValue !== node.value) {
2971 node.value = initialValue;
2972 }
2973 }
2974 }
2975
2976 if (disableInputAttributeSyncing) {
2977 // When not syncing the value attribute, assign the value attribute
2978 // directly from the defaultValue React property (when present)
2979 var defaultValue = getToStringValue(props.defaultValue);
2980
2981 if (defaultValue != null) {
2982 node.defaultValue = toString(defaultValue);
2983 }
2984 } else {
2985 // Otherwise, the value attribute is synchronized to the property,
2986 // so we assign defaultValue to the same thing as the value property
2987 // assignment step above.
2988 node.defaultValue = initialValue;
2989 }
2990 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
2991 // this is needed to work around a chrome bug where setting defaultChecked
2992 // will sometimes influence the value of checked (even after detachment).
2993 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
2994 // We need to temporarily unset name to avoid disrupting radio button groups.
2995
2996
2997 var name = node.name;
2998
2999 if (name !== '') {
3000 node.name = '';
3001 }
3002
3003 if (disableInputAttributeSyncing) {
3004 // When not syncing the checked attribute, the checked property
3005 // never gets assigned. It must be manually set. We don't want
3006 // to do this when hydrating so that existing user input isn't
3007 // modified
3008 if (!isHydrating) {
3009 updateChecked(element, props);
3010 } // Only assign the checked attribute if it is defined. This saves
3011 // a DOM write when controlling the checked attribute isn't needed
3012 // (text inputs, submit/reset)
3013
3014
3015 if (props.hasOwnProperty('defaultChecked')) {
3016 node.defaultChecked = !node.defaultChecked;
3017 node.defaultChecked = !!props.defaultChecked;
3018 }
3019 } else {
3020 // When syncing the checked attribute, both the checked property and
3021 // attribute are assigned at the same time using defaultChecked. This uses:
3022 //
3023 // 1. The checked React property when present
3024 // 2. The defaultChecked React property when present
3025 // 3. Otherwise, false
3026 node.defaultChecked = !node.defaultChecked;
3027 node.defaultChecked = !!node._wrapperState.initialChecked;
3028 }
3029
3030 if (name !== '') {
3031 node.name = name;
3032 }
3033}
3034function restoreControlledState$1(element, props) {
3035 var node = element;
3036 updateWrapper(node, props);
3037 updateNamedCousins(node, props);
3038}
3039
3040function updateNamedCousins(rootNode, props) {
3041 var name = props.name;
3042
3043 if (props.type === 'radio' && name != null) {
3044 var queryRoot = rootNode;
3045
3046 while (queryRoot.parentNode) {
3047 queryRoot = queryRoot.parentNode;
3048 } // If `rootNode.form` was non-null, then we could try `form.elements`,
3049 // but that sometimes behaves strangely in IE8. We could also try using
3050 // `form.getElementsByName`, but that will only return direct children
3051 // and won't include inputs that use the HTML5 `form=` attribute. Since
3052 // the input might not even be in a form. It might not even be in the
3053 // document. Let's just use the local `querySelectorAll` to ensure we don't
3054 // miss anything.
3055
3056
3057 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
3058
3059 for (var i = 0; i < group.length; i++) {
3060 var otherNode = group[i];
3061
3062 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
3063 continue;
3064 } // This will throw if radio buttons rendered by different copies of React
3065 // and the same name are rendered into the same form (same as #1939).
3066 // That's probably okay; we don't support it just as we don't support
3067 // mixing React radio buttons with non-React ones.
3068
3069
3070 var otherProps = getFiberCurrentPropsFromNode$1(otherNode);
3071
3072 if (!otherProps) {
3073 {
3074 throw Error("ReactDOMInput: Mixing React and non-React radio inputs with the same `name` is not supported.");
3075 }
3076 } // We need update the tracked value on the named cousin since the value
3077 // was changed but the input saw no event or value set
3078
3079
3080 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
3081 // was previously checked to update will cause it to be come re-checked
3082 // as appropriate.
3083
3084 updateWrapper(otherNode, otherProps);
3085 }
3086 }
3087} // In Chrome, assigning defaultValue to certain input types triggers input validation.
3088// For number inputs, the display value loses trailing decimal points. For email inputs,
3089// Chrome raises "The specified value <x> is not a valid email address".
3090//
3091// Here we check to see if the defaultValue has actually changed, avoiding these problems
3092// when the user is inputting text
3093//
3094// https://github.com/facebook/react/issues/7253
3095
3096
3097function setDefaultValue(node, type, value) {
3098 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
3099 type !== 'number' || node.ownerDocument.activeElement !== node) {
3100 if (value == null) {
3101 node.defaultValue = toString(node._wrapperState.initialValue);
3102 } else if (node.defaultValue !== toString(value)) {
3103 node.defaultValue = toString(value);
3104 }
3105 }
3106}
3107
3108var didWarnSelectedSetOnOption = false;
3109var didWarnInvalidChild = false;
3110
3111function flattenChildren(children) {
3112 var content = ''; // Flatten children. We'll warn if they are invalid
3113 // during validateProps() which runs for hydration too.
3114 // Note that this would throw on non-element objects.
3115 // Elements are stringified (which is normally irrelevant
3116 // but matters for <fbt>).
3117
3118 React.Children.forEach(children, function (child) {
3119 if (child == null) {
3120 return;
3121 }
3122
3123 content += child; // Note: we don't warn about invalid children here.
3124 // Instead, this is done separately below so that
3125 // it happens during the hydration codepath too.
3126 });
3127 return content;
3128}
3129/**
3130 * Implements an <option> host component that warns when `selected` is set.
3131 */
3132
3133
3134function validateProps(element, props) {
3135 {
3136 // This mirrors the codepath above, but runs for hydration too.
3137 // Warn about invalid children here so that client and hydration are consistent.
3138 // TODO: this seems like it could cause a DEV-only throw for hydration
3139 // if children contains a non-element object. We should try to avoid that.
3140 if (typeof props.children === 'object' && props.children !== null) {
3141 React.Children.forEach(props.children, function (child) {
3142 if (child == null) {
3143 return;
3144 }
3145
3146 if (typeof child === 'string' || typeof child === 'number') {
3147 return;
3148 }
3149
3150 if (typeof child.type !== 'string') {
3151 return;
3152 }
3153
3154 if (!didWarnInvalidChild) {
3155 didWarnInvalidChild = true;
3156 warning$1(false, 'Only strings and numbers are supported as <option> children.');
3157 }
3158 });
3159 } // TODO: Remove support for `selected` in <option>.
3160
3161
3162 if (props.selected != null && !didWarnSelectedSetOnOption) {
3163 warning$1(false, 'Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
3164 didWarnSelectedSetOnOption = true;
3165 }
3166 }
3167}
3168function postMountWrapper$1(element, props) {
3169 // value="" should make a value attribute (#6219)
3170 if (props.value != null) {
3171 element.setAttribute('value', toString(getToStringValue(props.value)));
3172 }
3173}
3174function getHostProps$1(element, props) {
3175 var hostProps = _assign({
3176 children: undefined
3177 }, props);
3178
3179 var content = flattenChildren(props.children);
3180
3181 if (content) {
3182 hostProps.children = content;
3183 }
3184
3185 return hostProps;
3186}
3187
3188// TODO: direct imports like some-package/src/* are bad. Fix me.
3189var didWarnValueDefaultValue$1;
3190
3191{
3192 didWarnValueDefaultValue$1 = false;
3193}
3194
3195function getDeclarationErrorAddendum() {
3196 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
3197
3198 if (ownerName) {
3199 return '\n\nCheck the render method of `' + ownerName + '`.';
3200 }
3201
3202 return '';
3203}
3204
3205var valuePropNames = ['value', 'defaultValue'];
3206/**
3207 * Validation function for `value` and `defaultValue`.
3208 */
3209
3210function checkSelectPropTypes(props) {
3211 ReactControlledValuePropTypes.checkPropTypes('select', props);
3212
3213 for (var i = 0; i < valuePropNames.length; i++) {
3214 var propName = valuePropNames[i];
3215
3216 if (props[propName] == null) {
3217 continue;
3218 }
3219
3220 var isArray = Array.isArray(props[propName]);
3221
3222 if (props.multiple && !isArray) {
3223 warning$1(false, 'The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
3224 } else if (!props.multiple && isArray) {
3225 warning$1(false, 'The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
3226 }
3227 }
3228}
3229
3230function updateOptions(node, multiple, propValue, setDefaultSelected) {
3231 var options = node.options;
3232
3233 if (multiple) {
3234 var selectedValues = propValue;
3235 var selectedValue = {};
3236
3237 for (var i = 0; i < selectedValues.length; i++) {
3238 // Prefix to avoid chaos with special keys.
3239 selectedValue['$' + selectedValues[i]] = true;
3240 }
3241
3242 for (var _i = 0; _i < options.length; _i++) {
3243 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
3244
3245 if (options[_i].selected !== selected) {
3246 options[_i].selected = selected;
3247 }
3248
3249 if (selected && setDefaultSelected) {
3250 options[_i].defaultSelected = true;
3251 }
3252 }
3253 } else {
3254 // Do not set `select.value` as exact behavior isn't consistent across all
3255 // browsers for all cases.
3256 var _selectedValue = toString(getToStringValue(propValue));
3257
3258 var defaultSelected = null;
3259
3260 for (var _i2 = 0; _i2 < options.length; _i2++) {
3261 if (options[_i2].value === _selectedValue) {
3262 options[_i2].selected = true;
3263
3264 if (setDefaultSelected) {
3265 options[_i2].defaultSelected = true;
3266 }
3267
3268 return;
3269 }
3270
3271 if (defaultSelected === null && !options[_i2].disabled) {
3272 defaultSelected = options[_i2];
3273 }
3274 }
3275
3276 if (defaultSelected !== null) {
3277 defaultSelected.selected = true;
3278 }
3279 }
3280}
3281/**
3282 * Implements a <select> host component that allows optionally setting the
3283 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
3284 * stringable. If `multiple` is true, the prop must be an array of stringables.
3285 *
3286 * If `value` is not supplied (or null/undefined), user actions that change the
3287 * selected option will trigger updates to the rendered options.
3288 *
3289 * If it is supplied (and not null/undefined), the rendered options will not
3290 * update in response to user actions. Instead, the `value` prop must change in
3291 * order for the rendered options to update.
3292 *
3293 * If `defaultValue` is provided, any options with the supplied values will be
3294 * selected.
3295 */
3296
3297
3298function getHostProps$2(element, props) {
3299 return _assign({}, props, {
3300 value: undefined
3301 });
3302}
3303function initWrapperState$1(element, props) {
3304 var node = element;
3305
3306 {
3307 checkSelectPropTypes(props);
3308 }
3309
3310 node._wrapperState = {
3311 wasMultiple: !!props.multiple
3312 };
3313
3314 {
3315 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
3316 warning$1(false, 'Select elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled select ' + 'element and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components');
3317 didWarnValueDefaultValue$1 = true;
3318 }
3319 }
3320}
3321function postMountWrapper$2(element, props) {
3322 var node = element;
3323 node.multiple = !!props.multiple;
3324 var value = props.value;
3325
3326 if (value != null) {
3327 updateOptions(node, !!props.multiple, value, false);
3328 } else if (props.defaultValue != null) {
3329 updateOptions(node, !!props.multiple, props.defaultValue, true);
3330 }
3331}
3332function postUpdateWrapper(element, props) {
3333 var node = element;
3334 var wasMultiple = node._wrapperState.wasMultiple;
3335 node._wrapperState.wasMultiple = !!props.multiple;
3336 var value = props.value;
3337
3338 if (value != null) {
3339 updateOptions(node, !!props.multiple, value, false);
3340 } else if (wasMultiple !== !!props.multiple) {
3341 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
3342 if (props.defaultValue != null) {
3343 updateOptions(node, !!props.multiple, props.defaultValue, true);
3344 } else {
3345 // Revert the select back to its default unselected state.
3346 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
3347 }
3348 }
3349}
3350function restoreControlledState$2(element, props) {
3351 var node = element;
3352 var value = props.value;
3353
3354 if (value != null) {
3355 updateOptions(node, !!props.multiple, value, false);
3356 }
3357}
3358
3359var didWarnValDefaultVal = false;
3360
3361/**
3362 * Implements a <textarea> host component that allows setting `value`, and
3363 * `defaultValue`. This differs from the traditional DOM API because value is
3364 * usually set as PCDATA children.
3365 *
3366 * If `value` is not supplied (or null/undefined), user actions that affect the
3367 * value will trigger updates to the element.
3368 *
3369 * If `value` is supplied (and not null/undefined), the rendered element will
3370 * not trigger updates to the element. Instead, the `value` prop must change in
3371 * order for the rendered element to be updated.
3372 *
3373 * The rendered element will be initialized with an empty value, the prop
3374 * `defaultValue` if specified, or the children content (deprecated).
3375 */
3376function getHostProps$3(element, props) {
3377 var node = element;
3378
3379 if (!(props.dangerouslySetInnerHTML == null)) {
3380 {
3381 throw Error("`dangerouslySetInnerHTML` does not make sense on <textarea>.");
3382 }
3383 } // Always set children to the same thing. In IE9, the selection range will
3384 // get reset if `textContent` is mutated. We could add a check in setTextContent
3385 // to only set the value if/when the value differs from the node value (which would
3386 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
3387 // solution. The value can be a boolean or object so that's why it's forced
3388 // to be a string.
3389
3390
3391 var hostProps = _assign({}, props, {
3392 value: undefined,
3393 defaultValue: undefined,
3394 children: toString(node._wrapperState.initialValue)
3395 });
3396
3397 return hostProps;
3398}
3399function initWrapperState$2(element, props) {
3400 var node = element;
3401
3402 {
3403 ReactControlledValuePropTypes.checkPropTypes('textarea', props);
3404
3405 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
3406 warning$1(false, '%s contains a textarea with both value and defaultValue props. ' + 'Textarea elements must be either controlled or uncontrolled ' + '(specify either the value prop, or the defaultValue prop, but not ' + 'both). Decide between using a controlled or uncontrolled textarea ' + 'and remove one of these props. More info: ' + 'https://fb.me/react-controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
3407 didWarnValDefaultVal = true;
3408 }
3409 }
3410
3411 var initialValue = props.value; // Only bother fetching default value if we're going to use it
3412
3413 if (initialValue == null) {
3414 var defaultValue = props.defaultValue; // TODO (yungsters): Remove support for children content in <textarea>.
3415
3416 var children = props.children;
3417
3418 if (children != null) {
3419 {
3420 warning$1(false, 'Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
3421 }
3422
3423 if (!(defaultValue == null)) {
3424 {
3425 throw Error("If you supply `defaultValue` on a <textarea>, do not pass children.");
3426 }
3427 }
3428
3429 if (Array.isArray(children)) {
3430 if (!(children.length <= 1)) {
3431 {
3432 throw Error("<textarea> can only have at most one child.");
3433 }
3434 }
3435
3436 children = children[0];
3437 }
3438
3439 defaultValue = children;
3440 }
3441
3442 if (defaultValue == null) {
3443 defaultValue = '';
3444 }
3445
3446 initialValue = defaultValue;
3447 }
3448
3449 node._wrapperState = {
3450 initialValue: getToStringValue(initialValue)
3451 };
3452}
3453function updateWrapper$1(element, props) {
3454 var node = element;
3455 var value = getToStringValue(props.value);
3456 var defaultValue = getToStringValue(props.defaultValue);
3457
3458 if (value != null) {
3459 // Cast `value` to a string to ensure the value is set correctly. While
3460 // browsers typically do this as necessary, jsdom doesn't.
3461 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
3462
3463 if (newValue !== node.value) {
3464 node.value = newValue;
3465 }
3466
3467 if (props.defaultValue == null && node.defaultValue !== newValue) {
3468 node.defaultValue = newValue;
3469 }
3470 }
3471
3472 if (defaultValue != null) {
3473 node.defaultValue = toString(defaultValue);
3474 }
3475}
3476function postMountWrapper$3(element, props) {
3477 var node = element; // This is in postMount because we need access to the DOM node, which is not
3478 // available until after the component has mounted.
3479
3480 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
3481 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
3482 // will populate textContent as well.
3483 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
3484
3485 if (textContent === node._wrapperState.initialValue) {
3486 if (textContent !== '' && textContent !== null) {
3487 node.value = textContent;
3488 }
3489 }
3490}
3491function restoreControlledState$3(element, props) {
3492 // DOM component is still mounted; update
3493 updateWrapper$1(element, props);
3494}
3495
3496var HTML_NAMESPACE$1 = 'http://www.w3.org/1999/xhtml';
3497var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
3498var SVG_NAMESPACE = 'http://www.w3.org/2000/svg';
3499var Namespaces = {
3500 html: HTML_NAMESPACE$1,
3501 mathml: MATH_NAMESPACE,
3502 svg: SVG_NAMESPACE
3503}; // Assumes there is no parent namespace.
3504
3505function getIntrinsicNamespace(type) {
3506 switch (type) {
3507 case 'svg':
3508 return SVG_NAMESPACE;
3509
3510 case 'math':
3511 return MATH_NAMESPACE;
3512
3513 default:
3514 return HTML_NAMESPACE$1;
3515 }
3516}
3517function getChildNamespace(parentNamespace, type) {
3518 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE$1) {
3519 // No (or default) parent namespace: potential entry point.
3520 return getIntrinsicNamespace(type);
3521 }
3522
3523 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
3524 // We're leaving SVG.
3525 return HTML_NAMESPACE$1;
3526 } // By default, pass namespace below.
3527
3528
3529 return parentNamespace;
3530}
3531
3532/* globals MSApp */
3533
3534/**
3535 * Create a function which has 'unsafe' privileges (required by windows8 apps)
3536 */
3537var createMicrosoftUnsafeLocalFunction = function (func) {
3538 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
3539 return function (arg0, arg1, arg2, arg3) {
3540 MSApp.execUnsafeLocalFunction(function () {
3541 return func(arg0, arg1, arg2, arg3);
3542 });
3543 };
3544 } else {
3545 return func;
3546 }
3547};
3548
3549var reusableSVGContainer;
3550/**
3551 * Set the innerHTML property of a node
3552 *
3553 * @param {DOMElement} node
3554 * @param {string} html
3555 * @internal
3556 */
3557
3558var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
3559 if (node.namespaceURI === Namespaces.svg) {
3560 {
3561 if (enableTrustedTypesIntegration) {
3562 // TODO: reconsider the text of this warning and when it should show
3563 // before enabling the feature flag.
3564 !(typeof trustedTypes === 'undefined') ? warning$1(false, "Using 'dangerouslySetInnerHTML' in an svg element with " + 'Trusted Types enabled in an Internet Explorer will cause ' + 'the trusted value to be converted to string. Assigning string ' + "to 'innerHTML' will throw an error if Trusted Types are enforced. " + "You can try to wrap your svg element inside a div and use 'dangerouslySetInnerHTML' " + 'on the enclosing div instead.') : void 0;
3565 }
3566 }
3567
3568 if (!('innerHTML' in node)) {
3569 // IE does not have innerHTML for SVG nodes, so instead we inject the
3570 // new markup in a temp node and then move the child nodes across into
3571 // the target node
3572 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
3573 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
3574 var svgNode = reusableSVGContainer.firstChild;
3575
3576 while (node.firstChild) {
3577 node.removeChild(node.firstChild);
3578 }
3579
3580 while (svgNode.firstChild) {
3581 node.appendChild(svgNode.firstChild);
3582 }
3583
3584 return;
3585 }
3586 }
3587
3588 node.innerHTML = html;
3589});
3590
3591/**
3592 * HTML nodeType values that represent the type of the node
3593 */
3594var ELEMENT_NODE = 1;
3595var TEXT_NODE = 3;
3596var COMMENT_NODE = 8;
3597var DOCUMENT_NODE = 9;
3598var DOCUMENT_FRAGMENT_NODE = 11;
3599
3600/**
3601 * Set the textContent property of a node. For text updates, it's faster
3602 * to set the `nodeValue` of the Text node directly instead of using
3603 * `.textContent` which will remove the existing node and create a new one.
3604 *
3605 * @param {DOMElement} node
3606 * @param {string} text
3607 * @internal
3608 */
3609
3610var setTextContent = function (node, text) {
3611 if (text) {
3612 var firstChild = node.firstChild;
3613
3614 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
3615 firstChild.nodeValue = text;
3616 return;
3617 }
3618 }
3619
3620 node.textContent = text;
3621};
3622
3623// Do not use the below two methods directly!
3624// Instead use constants exported from DOMTopLevelEventTypes in ReactDOM.
3625// (It is the only module that is allowed to access these methods.)
3626function unsafeCastStringToDOMTopLevelType(topLevelType) {
3627 return topLevelType;
3628}
3629function unsafeCastDOMTopLevelTypeToString(topLevelType) {
3630 return topLevelType;
3631}
3632
3633/**
3634 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
3635 *
3636 * @param {string} styleProp
3637 * @param {string} eventName
3638 * @returns {object}
3639 */
3640
3641function makePrefixMap(styleProp, eventName) {
3642 var prefixes = {};
3643 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
3644 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
3645 prefixes['Moz' + styleProp] = 'moz' + eventName;
3646 return prefixes;
3647}
3648/**
3649 * A list of event names to a configurable list of vendor prefixes.
3650 */
3651
3652
3653var vendorPrefixes = {
3654 animationend: makePrefixMap('Animation', 'AnimationEnd'),
3655 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
3656 animationstart: makePrefixMap('Animation', 'AnimationStart'),
3657 transitionend: makePrefixMap('Transition', 'TransitionEnd')
3658};
3659/**
3660 * Event names that have already been detected and prefixed (if applicable).
3661 */
3662
3663var prefixedEventNames = {};
3664/**
3665 * Element to check for prefixes on.
3666 */
3667
3668var style = {};
3669/**
3670 * Bootstrap if a DOM exists.
3671 */
3672
3673if (canUseDOM) {
3674 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
3675 // the un-prefixed "animation" and "transition" properties are defined on the
3676 // style object but the events that fire will still be prefixed, so we need
3677 // to check if the un-prefixed events are usable, and if not remove them from the map.
3678
3679 if (!('AnimationEvent' in window)) {
3680 delete vendorPrefixes.animationend.animation;
3681 delete vendorPrefixes.animationiteration.animation;
3682 delete vendorPrefixes.animationstart.animation;
3683 } // Same as above
3684
3685
3686 if (!('TransitionEvent' in window)) {
3687 delete vendorPrefixes.transitionend.transition;
3688 }
3689}
3690/**
3691 * Attempts to determine the correct vendor prefixed event name.
3692 *
3693 * @param {string} eventName
3694 * @returns {string}
3695 */
3696
3697
3698function getVendorPrefixedEventName(eventName) {
3699 if (prefixedEventNames[eventName]) {
3700 return prefixedEventNames[eventName];
3701 } else if (!vendorPrefixes[eventName]) {
3702 return eventName;
3703 }
3704
3705 var prefixMap = vendorPrefixes[eventName];
3706
3707 for (var styleProp in prefixMap) {
3708 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
3709 return prefixedEventNames[eventName] = prefixMap[styleProp];
3710 }
3711 }
3712
3713 return eventName;
3714}
3715
3716/**
3717 * To identify top level events in ReactDOM, we use constants defined by this
3718 * module. This is the only module that uses the unsafe* methods to express
3719 * that the constants actually correspond to the browser event names. This lets
3720 * us save some bundle size by avoiding a top level type -> event name map.
3721 * The rest of ReactDOM code should import top level types from this file.
3722 */
3723
3724var TOP_ABORT = unsafeCastStringToDOMTopLevelType('abort');
3725var TOP_ANIMATION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationend'));
3726var TOP_ANIMATION_ITERATION = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationiteration'));
3727var TOP_ANIMATION_START = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('animationstart'));
3728var TOP_BLUR = unsafeCastStringToDOMTopLevelType('blur');
3729var TOP_CAN_PLAY = unsafeCastStringToDOMTopLevelType('canplay');
3730var TOP_CAN_PLAY_THROUGH = unsafeCastStringToDOMTopLevelType('canplaythrough');
3731var TOP_CANCEL = unsafeCastStringToDOMTopLevelType('cancel');
3732var TOP_CHANGE = unsafeCastStringToDOMTopLevelType('change');
3733var TOP_CLICK = unsafeCastStringToDOMTopLevelType('click');
3734var TOP_CLOSE = unsafeCastStringToDOMTopLevelType('close');
3735var TOP_COMPOSITION_END = unsafeCastStringToDOMTopLevelType('compositionend');
3736var TOP_COMPOSITION_START = unsafeCastStringToDOMTopLevelType('compositionstart');
3737var TOP_COMPOSITION_UPDATE = unsafeCastStringToDOMTopLevelType('compositionupdate');
3738var TOP_CONTEXT_MENU = unsafeCastStringToDOMTopLevelType('contextmenu');
3739var TOP_COPY = unsafeCastStringToDOMTopLevelType('copy');
3740var TOP_CUT = unsafeCastStringToDOMTopLevelType('cut');
3741var TOP_DOUBLE_CLICK = unsafeCastStringToDOMTopLevelType('dblclick');
3742var TOP_AUX_CLICK = unsafeCastStringToDOMTopLevelType('auxclick');
3743var TOP_DRAG = unsafeCastStringToDOMTopLevelType('drag');
3744var TOP_DRAG_END = unsafeCastStringToDOMTopLevelType('dragend');
3745var TOP_DRAG_ENTER = unsafeCastStringToDOMTopLevelType('dragenter');
3746var TOP_DRAG_EXIT = unsafeCastStringToDOMTopLevelType('dragexit');
3747var TOP_DRAG_LEAVE = unsafeCastStringToDOMTopLevelType('dragleave');
3748var TOP_DRAG_OVER = unsafeCastStringToDOMTopLevelType('dragover');
3749var TOP_DRAG_START = unsafeCastStringToDOMTopLevelType('dragstart');
3750var TOP_DROP = unsafeCastStringToDOMTopLevelType('drop');
3751var TOP_DURATION_CHANGE = unsafeCastStringToDOMTopLevelType('durationchange');
3752var TOP_EMPTIED = unsafeCastStringToDOMTopLevelType('emptied');
3753var TOP_ENCRYPTED = unsafeCastStringToDOMTopLevelType('encrypted');
3754var TOP_ENDED = unsafeCastStringToDOMTopLevelType('ended');
3755var TOP_ERROR = unsafeCastStringToDOMTopLevelType('error');
3756var TOP_FOCUS = unsafeCastStringToDOMTopLevelType('focus');
3757var TOP_GOT_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('gotpointercapture');
3758var TOP_INPUT = unsafeCastStringToDOMTopLevelType('input');
3759var TOP_INVALID = unsafeCastStringToDOMTopLevelType('invalid');
3760var TOP_KEY_DOWN = unsafeCastStringToDOMTopLevelType('keydown');
3761var TOP_KEY_PRESS = unsafeCastStringToDOMTopLevelType('keypress');
3762var TOP_KEY_UP = unsafeCastStringToDOMTopLevelType('keyup');
3763var TOP_LOAD = unsafeCastStringToDOMTopLevelType('load');
3764var TOP_LOAD_START = unsafeCastStringToDOMTopLevelType('loadstart');
3765var TOP_LOADED_DATA = unsafeCastStringToDOMTopLevelType('loadeddata');
3766var TOP_LOADED_METADATA = unsafeCastStringToDOMTopLevelType('loadedmetadata');
3767var TOP_LOST_POINTER_CAPTURE = unsafeCastStringToDOMTopLevelType('lostpointercapture');
3768var TOP_MOUSE_DOWN = unsafeCastStringToDOMTopLevelType('mousedown');
3769var TOP_MOUSE_MOVE = unsafeCastStringToDOMTopLevelType('mousemove');
3770var TOP_MOUSE_OUT = unsafeCastStringToDOMTopLevelType('mouseout');
3771var TOP_MOUSE_OVER = unsafeCastStringToDOMTopLevelType('mouseover');
3772var TOP_MOUSE_UP = unsafeCastStringToDOMTopLevelType('mouseup');
3773var TOP_PASTE = unsafeCastStringToDOMTopLevelType('paste');
3774var TOP_PAUSE = unsafeCastStringToDOMTopLevelType('pause');
3775var TOP_PLAY = unsafeCastStringToDOMTopLevelType('play');
3776var TOP_PLAYING = unsafeCastStringToDOMTopLevelType('playing');
3777var TOP_POINTER_CANCEL = unsafeCastStringToDOMTopLevelType('pointercancel');
3778var TOP_POINTER_DOWN = unsafeCastStringToDOMTopLevelType('pointerdown');
3779
3780
3781var TOP_POINTER_MOVE = unsafeCastStringToDOMTopLevelType('pointermove');
3782var TOP_POINTER_OUT = unsafeCastStringToDOMTopLevelType('pointerout');
3783var TOP_POINTER_OVER = unsafeCastStringToDOMTopLevelType('pointerover');
3784var TOP_POINTER_UP = unsafeCastStringToDOMTopLevelType('pointerup');
3785var TOP_PROGRESS = unsafeCastStringToDOMTopLevelType('progress');
3786var TOP_RATE_CHANGE = unsafeCastStringToDOMTopLevelType('ratechange');
3787var TOP_RESET = unsafeCastStringToDOMTopLevelType('reset');
3788var TOP_SCROLL = unsafeCastStringToDOMTopLevelType('scroll');
3789var TOP_SEEKED = unsafeCastStringToDOMTopLevelType('seeked');
3790var TOP_SEEKING = unsafeCastStringToDOMTopLevelType('seeking');
3791var TOP_SELECTION_CHANGE = unsafeCastStringToDOMTopLevelType('selectionchange');
3792var TOP_STALLED = unsafeCastStringToDOMTopLevelType('stalled');
3793var TOP_SUBMIT = unsafeCastStringToDOMTopLevelType('submit');
3794var TOP_SUSPEND = unsafeCastStringToDOMTopLevelType('suspend');
3795var TOP_TEXT_INPUT = unsafeCastStringToDOMTopLevelType('textInput');
3796var TOP_TIME_UPDATE = unsafeCastStringToDOMTopLevelType('timeupdate');
3797var TOP_TOGGLE = unsafeCastStringToDOMTopLevelType('toggle');
3798var TOP_TOUCH_CANCEL = unsafeCastStringToDOMTopLevelType('touchcancel');
3799var TOP_TOUCH_END = unsafeCastStringToDOMTopLevelType('touchend');
3800var TOP_TOUCH_MOVE = unsafeCastStringToDOMTopLevelType('touchmove');
3801var TOP_TOUCH_START = unsafeCastStringToDOMTopLevelType('touchstart');
3802var TOP_TRANSITION_END = unsafeCastStringToDOMTopLevelType(getVendorPrefixedEventName('transitionend'));
3803var TOP_VOLUME_CHANGE = unsafeCastStringToDOMTopLevelType('volumechange');
3804var TOP_WAITING = unsafeCastStringToDOMTopLevelType('waiting');
3805var TOP_WHEEL = unsafeCastStringToDOMTopLevelType('wheel'); // List of events that need to be individually attached to media elements.
3806// Note that events in this list will *not* be listened to at the top level
3807// unless they're explicitly whitelisted in `ReactBrowserEventEmitter.listenTo`.
3808
3809var mediaEventTypes = [TOP_ABORT, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_VOLUME_CHANGE, TOP_WAITING];
3810function getRawEventName(topLevelType) {
3811 return unsafeCastDOMTopLevelTypeToString(topLevelType);
3812}
3813
3814/**
3815 * `ReactInstanceMap` maintains a mapping from a public facing stateful
3816 * instance (key) and the internal representation (value). This allows public
3817 * methods to accept the user facing instance as an argument and map them back
3818 * to internal methods.
3819 *
3820 * Note that this module is currently shared and assumed to be stateless.
3821 * If this becomes an actual Map, that will break.
3822 */
3823
3824/**
3825 * This API should be called `delete` but we'd have to make sure to always
3826 * transform these to strings for IE support. When this transform is fully
3827 * supported we can rename it.
3828 */
3829
3830function get(key) {
3831 return key._reactInternalFiber;
3832}
3833function has$1(key) {
3834 return key._reactInternalFiber !== undefined;
3835}
3836function set(key, value) {
3837 key._reactInternalFiber = value;
3838}
3839
3840// Don't change these two values. They're used by React Dev Tools.
3841var NoEffect =
3842/* */
38430;
3844var PerformedWork =
3845/* */
38461; // You can change the rest (and add more).
3847
3848var Placement =
3849/* */
38502;
3851var Update =
3852/* */
38534;
3854var PlacementAndUpdate =
3855/* */
38566;
3857var Deletion =
3858/* */
38598;
3860var ContentReset =
3861/* */
386216;
3863var Callback =
3864/* */
386532;
3866var DidCapture =
3867/* */
386864;
3869var Ref =
3870/* */
3871128;
3872var Snapshot =
3873/* */
3874256;
3875var Passive =
3876/* */
3877512;
3878var Hydrating =
3879/* */
38801024;
3881var HydratingAndUpdate =
3882/* */
38831028; // Passive & Update & Callback & Ref & Snapshot
3884
3885var LifecycleEffectMask =
3886/* */
3887932; // Union of all host effects
3888
3889var HostEffectMask =
3890/* */
38912047;
3892var Incomplete =
3893/* */
38942048;
3895var ShouldCapture =
3896/* */
38974096;
3898
3899var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
3900function getNearestMountedFiber(fiber) {
3901 var node = fiber;
3902 var nearestMounted = fiber;
3903
3904 if (!fiber.alternate) {
3905 // If there is no alternate, this might be a new tree that isn't inserted
3906 // yet. If it is, then it will have a pending insertion effect on it.
3907 var nextNode = node;
3908
3909 do {
3910 node = nextNode;
3911
3912 if ((node.effectTag & (Placement | Hydrating)) !== NoEffect) {
3913 // This is an insertion or in-progress hydration. The nearest possible
3914 // mounted fiber is the parent but we need to continue to figure out
3915 // if that one is still mounted.
3916 nearestMounted = node.return;
3917 }
3918
3919 nextNode = node.return;
3920 } while (nextNode);
3921 } else {
3922 while (node.return) {
3923 node = node.return;
3924 }
3925 }
3926
3927 if (node.tag === HostRoot) {
3928 // TODO: Check if this was a nested HostRoot when used with
3929 // renderContainerIntoSubtree.
3930 return nearestMounted;
3931 } // If we didn't hit the root, that means that we're in an disconnected tree
3932 // that has been unmounted.
3933
3934
3935 return null;
3936}
3937function getSuspenseInstanceFromFiber(fiber) {
3938 if (fiber.tag === SuspenseComponent) {
3939 var suspenseState = fiber.memoizedState;
3940
3941 if (suspenseState === null) {
3942 var current = fiber.alternate;
3943
3944 if (current !== null) {
3945 suspenseState = current.memoizedState;
3946 }
3947 }
3948
3949 if (suspenseState !== null) {
3950 return suspenseState.dehydrated;
3951 }
3952 }
3953
3954 return null;
3955}
3956function getContainerFromFiber(fiber) {
3957 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
3958}
3959function isFiberMounted(fiber) {
3960 return getNearestMountedFiber(fiber) === fiber;
3961}
3962function isMounted(component) {
3963 {
3964 var owner = ReactCurrentOwner.current;
3965
3966 if (owner !== null && owner.tag === ClassComponent) {
3967 var ownerFiber = owner;
3968 var instance = ownerFiber.stateNode;
3969 !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;
3970 instance._warnedAboutRefsInRender = true;
3971 }
3972 }
3973
3974 var fiber = get(component);
3975
3976 if (!fiber) {
3977 return false;
3978 }
3979
3980 return getNearestMountedFiber(fiber) === fiber;
3981}
3982
3983function assertIsMounted(fiber) {
3984 if (!(getNearestMountedFiber(fiber) === fiber)) {
3985 {
3986 throw Error("Unable to find node on an unmounted component.");
3987 }
3988 }
3989}
3990
3991function findCurrentFiberUsingSlowPath(fiber) {
3992 var alternate = fiber.alternate;
3993
3994 if (!alternate) {
3995 // If there is no alternate, then we only need to check if it is mounted.
3996 var nearestMounted = getNearestMountedFiber(fiber);
3997
3998 if (!(nearestMounted !== null)) {
3999 {
4000 throw Error("Unable to find node on an unmounted component.");
4001 }
4002 }
4003
4004 if (nearestMounted !== fiber) {
4005 return null;
4006 }
4007
4008 return fiber;
4009 } // If we have two possible branches, we'll walk backwards up to the root
4010 // to see what path the root points to. On the way we may hit one of the
4011 // special cases and we'll deal with them.
4012
4013
4014 var a = fiber;
4015 var b = alternate;
4016
4017 while (true) {
4018 var parentA = a.return;
4019
4020 if (parentA === null) {
4021 // We're at the root.
4022 break;
4023 }
4024
4025 var parentB = parentA.alternate;
4026
4027 if (parentB === null) {
4028 // There is no alternate. This is an unusual case. Currently, it only
4029 // happens when a Suspense component is hidden. An extra fragment fiber
4030 // is inserted in between the Suspense fiber and its children. Skip
4031 // over this extra fragment fiber and proceed to the next parent.
4032 var nextParent = parentA.return;
4033
4034 if (nextParent !== null) {
4035 a = b = nextParent;
4036 continue;
4037 } // If there's no parent, we're at the root.
4038
4039
4040 break;
4041 } // If both copies of the parent fiber point to the same child, we can
4042 // assume that the child is current. This happens when we bailout on low
4043 // priority: the bailed out fiber's child reuses the current child.
4044
4045
4046 if (parentA.child === parentB.child) {
4047 var child = parentA.child;
4048
4049 while (child) {
4050 if (child === a) {
4051 // We've determined that A is the current branch.
4052 assertIsMounted(parentA);
4053 return fiber;
4054 }
4055
4056 if (child === b) {
4057 // We've determined that B is the current branch.
4058 assertIsMounted(parentA);
4059 return alternate;
4060 }
4061
4062 child = child.sibling;
4063 } // We should never have an alternate for any mounting node. So the only
4064 // way this could possibly happen is if this was unmounted, if at all.
4065
4066
4067 {
4068 {
4069 throw Error("Unable to find node on an unmounted component.");
4070 }
4071 }
4072 }
4073
4074 if (a.return !== b.return) {
4075 // The return pointer of A and the return pointer of B point to different
4076 // fibers. We assume that return pointers never criss-cross, so A must
4077 // belong to the child set of A.return, and B must belong to the child
4078 // set of B.return.
4079 a = parentA;
4080 b = parentB;
4081 } else {
4082 // The return pointers point to the same fiber. We'll have to use the
4083 // default, slow path: scan the child sets of each parent alternate to see
4084 // which child belongs to which set.
4085 //
4086 // Search parent A's child set
4087 var didFindChild = false;
4088 var _child = parentA.child;
4089
4090 while (_child) {
4091 if (_child === a) {
4092 didFindChild = true;
4093 a = parentA;
4094 b = parentB;
4095 break;
4096 }
4097
4098 if (_child === b) {
4099 didFindChild = true;
4100 b = parentA;
4101 a = parentB;
4102 break;
4103 }
4104
4105 _child = _child.sibling;
4106 }
4107
4108 if (!didFindChild) {
4109 // Search parent B's child set
4110 _child = parentB.child;
4111
4112 while (_child) {
4113 if (_child === a) {
4114 didFindChild = true;
4115 a = parentB;
4116 b = parentA;
4117 break;
4118 }
4119
4120 if (_child === b) {
4121 didFindChild = true;
4122 b = parentB;
4123 a = parentA;
4124 break;
4125 }
4126
4127 _child = _child.sibling;
4128 }
4129
4130 if (!didFindChild) {
4131 {
4132 throw Error("Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.");
4133 }
4134 }
4135 }
4136 }
4137
4138 if (!(a.alternate === b)) {
4139 {
4140 throw Error("Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue.");
4141 }
4142 }
4143 } // If the root is not a host container, we're in a disconnected tree. I.e.
4144 // unmounted.
4145
4146
4147 if (!(a.tag === HostRoot)) {
4148 {
4149 throw Error("Unable to find node on an unmounted component.");
4150 }
4151 }
4152
4153 if (a.stateNode.current === a) {
4154 // We've determined that A is the current branch.
4155 return fiber;
4156 } // Otherwise B has to be current branch.
4157
4158
4159 return alternate;
4160}
4161function findCurrentHostFiber(parent) {
4162 var currentParent = findCurrentFiberUsingSlowPath(parent);
4163
4164 if (!currentParent) {
4165 return null;
4166 } // Next we'll drill down this component to find the first HostComponent/Text.
4167
4168
4169 var node = currentParent;
4170
4171 while (true) {
4172 if (node.tag === HostComponent || node.tag === HostText) {
4173 return node;
4174 } else if (node.child) {
4175 node.child.return = node;
4176 node = node.child;
4177 continue;
4178 }
4179
4180 if (node === currentParent) {
4181 return null;
4182 }
4183
4184 while (!node.sibling) {
4185 if (!node.return || node.return === currentParent) {
4186 return null;
4187 }
4188
4189 node = node.return;
4190 }
4191
4192 node.sibling.return = node.return;
4193 node = node.sibling;
4194 } // Flow needs the return null here, but ESLint complains about it.
4195 // eslint-disable-next-line no-unreachable
4196
4197
4198 return null;
4199}
4200function findCurrentHostFiberWithNoPortals(parent) {
4201 var currentParent = findCurrentFiberUsingSlowPath(parent);
4202
4203 if (!currentParent) {
4204 return null;
4205 } // Next we'll drill down this component to find the first HostComponent/Text.
4206
4207
4208 var node = currentParent;
4209
4210 while (true) {
4211 if (node.tag === HostComponent || node.tag === HostText || enableFundamentalAPI && node.tag === FundamentalComponent) {
4212 return node;
4213 } else if (node.child && node.tag !== HostPortal) {
4214 node.child.return = node;
4215 node = node.child;
4216 continue;
4217 }
4218
4219 if (node === currentParent) {
4220 return null;
4221 }
4222
4223 while (!node.sibling) {
4224 if (!node.return || node.return === currentParent) {
4225 return null;
4226 }
4227
4228 node = node.return;
4229 }
4230
4231 node.sibling.return = node.return;
4232 node = node.sibling;
4233 } // Flow needs the return null here, but ESLint complains about it.
4234 // eslint-disable-next-line no-unreachable
4235
4236
4237 return null;
4238}
4239
4240var attemptSynchronousHydration;
4241function setAttemptSynchronousHydration(fn) {
4242 attemptSynchronousHydration = fn;
4243}
4244var attemptUserBlockingHydration;
4245function setAttemptUserBlockingHydration(fn) {
4246 attemptUserBlockingHydration = fn;
4247}
4248var attemptContinuousHydration;
4249function setAttemptContinuousHydration(fn) {
4250 attemptContinuousHydration = fn;
4251}
4252var attemptHydrationAtCurrentPriority;
4253function setAttemptHydrationAtCurrentPriority(fn) {
4254 attemptHydrationAtCurrentPriority = fn;
4255} // TODO: Upgrade this definition once we're on a newer version of Flow that
4256// has this definition built-in.
4257
4258var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
4259
4260var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
4261
4262// if the last target was dehydrated.
4263
4264var queuedFocus = null;
4265var queuedDrag = null;
4266var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
4267
4268var queuedPointers = new Map();
4269var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
4270
4271var queuedExplicitHydrationTargets = [];
4272function hasQueuedDiscreteEvents() {
4273 return queuedDiscreteEvents.length > 0;
4274}
4275
4276var discreteReplayableEvents = [TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_TOUCH_CANCEL, TOP_TOUCH_END, TOP_TOUCH_START, TOP_AUX_CLICK, TOP_DOUBLE_CLICK, TOP_POINTER_CANCEL, TOP_POINTER_DOWN, TOP_POINTER_UP, TOP_DRAG_END, TOP_DRAG_START, TOP_DROP, TOP_COMPOSITION_END, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_INPUT, TOP_TEXT_INPUT, TOP_CLOSE, TOP_CANCEL, TOP_COPY, TOP_CUT, TOP_PASTE, TOP_CLICK, TOP_CHANGE, TOP_CONTEXT_MENU, TOP_RESET, TOP_SUBMIT];
4277var continuousReplayableEvents = [TOP_FOCUS, TOP_BLUR, TOP_DRAG_ENTER, TOP_DRAG_LEAVE, TOP_MOUSE_OVER, TOP_MOUSE_OUT, TOP_POINTER_OVER, TOP_POINTER_OUT, TOP_GOT_POINTER_CAPTURE, TOP_LOST_POINTER_CAPTURE];
4278function isReplayableDiscreteEvent(eventType) {
4279 return discreteReplayableEvents.indexOf(eventType) > -1;
4280}
4281
4282function trapReplayableEvent(topLevelType, document, listeningSet) {
4283 listenToTopLevel(topLevelType, document, listeningSet);
4284
4285 if (enableFlareAPI) {
4286 // Trap events for the responder system.
4287 var passiveEventKey = unsafeCastDOMTopLevelTypeToString(topLevelType) + '_passive';
4288
4289 if (!listeningSet.has(passiveEventKey)) {
4290 trapEventForResponderEventSystem(document, topLevelType, true);
4291 listeningSet.add(passiveEventKey);
4292 } // TODO: This listens to all events as active which might have
4293 // undesirable effects. It's also unnecessary to have both
4294 // passive and active listeners. Instead, we could start with
4295 // a passive and upgrade it to an active one if needed.
4296 // For replaying purposes the active is never needed since we
4297 // currently don't preventDefault.
4298
4299
4300 var activeEventKey = unsafeCastDOMTopLevelTypeToString(topLevelType) + '_active';
4301
4302 if (!listeningSet.has(activeEventKey)) {
4303 trapEventForResponderEventSystem(document, topLevelType, false);
4304 listeningSet.add(activeEventKey);
4305 }
4306 }
4307}
4308
4309function eagerlyTrapReplayableEvents(document) {
4310 var listeningSet = getListeningSetForElement(document); // Discrete
4311
4312 discreteReplayableEvents.forEach(function (topLevelType) {
4313 trapReplayableEvent(topLevelType, document, listeningSet);
4314 }); // Continuous
4315
4316 continuousReplayableEvents.forEach(function (topLevelType) {
4317 trapReplayableEvent(topLevelType, document, listeningSet);
4318 });
4319}
4320
4321function createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, nativeEvent) {
4322 return {
4323 blockedOn: blockedOn,
4324 topLevelType: topLevelType,
4325 eventSystemFlags: eventSystemFlags | IS_REPLAYED,
4326 nativeEvent: nativeEvent
4327 };
4328}
4329
4330function queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, nativeEvent) {
4331 var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, nativeEvent);
4332 queuedDiscreteEvents.push(queuedEvent);
4333
4334 if (enableSelectiveHydration) {
4335 if (queuedDiscreteEvents.length === 1) {
4336 // If this was the first discrete event, we might be able to
4337 // synchronously unblock it so that preventDefault still works.
4338 while (queuedEvent.blockedOn !== null) {
4339 var _fiber = getInstanceFromNode$1(queuedEvent.blockedOn);
4340
4341 if (_fiber === null) {
4342 break;
4343 }
4344
4345 attemptSynchronousHydration(_fiber);
4346
4347 if (queuedEvent.blockedOn === null) {
4348 // We got unblocked by hydration. Let's try again.
4349 replayUnblockedEvents(); // If we're reblocked, on an inner boundary, we might need
4350 // to attempt hydrating that one.
4351
4352 continue;
4353 } else {
4354 // We're still blocked from hydation, we have to give up
4355 // and replay later.
4356 break;
4357 }
4358 }
4359 }
4360 }
4361} // Resets the replaying for this type of continuous event to no event.
4362
4363function clearIfContinuousEvent(topLevelType, nativeEvent) {
4364 switch (topLevelType) {
4365 case TOP_FOCUS:
4366 case TOP_BLUR:
4367 queuedFocus = null;
4368 break;
4369
4370 case TOP_DRAG_ENTER:
4371 case TOP_DRAG_LEAVE:
4372 queuedDrag = null;
4373 break;
4374
4375 case TOP_MOUSE_OVER:
4376 case TOP_MOUSE_OUT:
4377 queuedMouse = null;
4378 break;
4379
4380 case TOP_POINTER_OVER:
4381 case TOP_POINTER_OUT:
4382 {
4383 var pointerId = nativeEvent.pointerId;
4384 queuedPointers.delete(pointerId);
4385 break;
4386 }
4387
4388 case TOP_GOT_POINTER_CAPTURE:
4389 case TOP_LOST_POINTER_CAPTURE:
4390 {
4391 var _pointerId = nativeEvent.pointerId;
4392 queuedPointerCaptures.delete(_pointerId);
4393 break;
4394 }
4395 }
4396}
4397
4398function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, topLevelType, eventSystemFlags, nativeEvent) {
4399 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
4400 var queuedEvent = createQueuedReplayableEvent(blockedOn, topLevelType, eventSystemFlags, nativeEvent);
4401
4402 if (blockedOn !== null) {
4403 var _fiber2 = getInstanceFromNode$1(blockedOn);
4404
4405 if (_fiber2 !== null) {
4406 // Attempt to increase the priority of this target.
4407 attemptContinuousHydration(_fiber2);
4408 }
4409 }
4410
4411 return queuedEvent;
4412 } // If we have already queued this exact event, then it's because
4413 // the different event systems have different DOM event listeners.
4414 // We can accumulate the flags and store a single event to be
4415 // replayed.
4416
4417
4418 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
4419 return existingQueuedEvent;
4420}
4421
4422function queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, nativeEvent) {
4423 // These set relatedTarget to null because the replayed event will be treated as if we
4424 // moved from outside the window (no target) onto the target once it hydrates.
4425 // Instead of mutating we could clone the event.
4426 switch (topLevelType) {
4427 case TOP_FOCUS:
4428 {
4429 var focusEvent = nativeEvent;
4430 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, topLevelType, eventSystemFlags, focusEvent);
4431 return true;
4432 }
4433
4434 case TOP_DRAG_ENTER:
4435 {
4436 var dragEvent = nativeEvent;
4437 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, topLevelType, eventSystemFlags, dragEvent);
4438 return true;
4439 }
4440
4441 case TOP_MOUSE_OVER:
4442 {
4443 var mouseEvent = nativeEvent;
4444 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, topLevelType, eventSystemFlags, mouseEvent);
4445 return true;
4446 }
4447
4448 case TOP_POINTER_OVER:
4449 {
4450 var pointerEvent = nativeEvent;
4451 var pointerId = pointerEvent.pointerId;
4452 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, topLevelType, eventSystemFlags, pointerEvent));
4453 return true;
4454 }
4455
4456 case TOP_GOT_POINTER_CAPTURE:
4457 {
4458 var _pointerEvent = nativeEvent;
4459 var _pointerId2 = _pointerEvent.pointerId;
4460 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, topLevelType, eventSystemFlags, _pointerEvent));
4461 return true;
4462 }
4463 }
4464
4465 return false;
4466} // Check if this target is unblocked. Returns true if it's unblocked.
4467
4468function attemptExplicitHydrationTarget(queuedTarget) {
4469 // TODO: This function shares a lot of logic with attemptToDispatchEvent.
4470 // Try to unify them. It's a bit tricky since it would require two return
4471 // values.
4472 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
4473
4474 if (targetInst !== null) {
4475 var nearestMounted = getNearestMountedFiber(targetInst);
4476
4477 if (nearestMounted !== null) {
4478 var tag = nearestMounted.tag;
4479
4480 if (tag === SuspenseComponent) {
4481 var instance = getSuspenseInstanceFromFiber(nearestMounted);
4482
4483 if (instance !== null) {
4484 // We're blocked on hydrating this boundary.
4485 // Increase its priority.
4486 queuedTarget.blockedOn = instance;
4487 unstable_runWithPriority(queuedTarget.priority, function () {
4488 attemptHydrationAtCurrentPriority(nearestMounted);
4489 });
4490 return;
4491 }
4492 } else if (tag === HostRoot) {
4493 var root = nearestMounted.stateNode;
4494
4495 if (root.hydrate) {
4496 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
4497 // a root other than sync.
4498
4499 return;
4500 }
4501 }
4502 }
4503 }
4504
4505 queuedTarget.blockedOn = null;
4506}
4507
4508function queueExplicitHydrationTarget(target) {
4509 if (enableSelectiveHydration) {
4510 var priority = unstable_getCurrentPriorityLevel();
4511 var queuedTarget = {
4512 blockedOn: null,
4513 target: target,
4514 priority: priority
4515 };
4516 var i = 0;
4517
4518 for (; i < queuedExplicitHydrationTargets.length; i++) {
4519 if (priority <= queuedExplicitHydrationTargets[i].priority) {
4520 break;
4521 }
4522 }
4523
4524 queuedExplicitHydrationTargets.splice(i, 0, queuedTarget);
4525
4526 if (i === 0) {
4527 attemptExplicitHydrationTarget(queuedTarget);
4528 }
4529 }
4530}
4531
4532function attemptReplayContinuousQueuedEvent(queuedEvent) {
4533 if (queuedEvent.blockedOn !== null) {
4534 return false;
4535 }
4536
4537 var nextBlockedOn = attemptToDispatchEvent(queuedEvent.topLevelType, queuedEvent.eventSystemFlags, queuedEvent.nativeEvent);
4538
4539 if (nextBlockedOn !== null) {
4540 // We're still blocked. Try again later.
4541 var _fiber3 = getInstanceFromNode$1(nextBlockedOn);
4542
4543 if (_fiber3 !== null) {
4544 attemptContinuousHydration(_fiber3);
4545 }
4546
4547 queuedEvent.blockedOn = nextBlockedOn;
4548 return false;
4549 }
4550
4551 return true;
4552}
4553
4554function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
4555 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
4556 map.delete(key);
4557 }
4558}
4559
4560function replayUnblockedEvents() {
4561 hasScheduledReplayAttempt = false; // First replay discrete events.
4562
4563 while (queuedDiscreteEvents.length > 0) {
4564 var nextDiscreteEvent = queuedDiscreteEvents[0];
4565
4566 if (nextDiscreteEvent.blockedOn !== null) {
4567 // We're still blocked.
4568 // Increase the priority of this boundary to unblock
4569 // the next discrete event.
4570 var _fiber4 = getInstanceFromNode$1(nextDiscreteEvent.blockedOn);
4571
4572 if (_fiber4 !== null) {
4573 attemptUserBlockingHydration(_fiber4);
4574 }
4575
4576 break;
4577 }
4578
4579 var nextBlockedOn = attemptToDispatchEvent(nextDiscreteEvent.topLevelType, nextDiscreteEvent.eventSystemFlags, nextDiscreteEvent.nativeEvent);
4580
4581 if (nextBlockedOn !== null) {
4582 // We're still blocked. Try again later.
4583 nextDiscreteEvent.blockedOn = nextBlockedOn;
4584 } else {
4585 // We've successfully replayed the first event. Let's try the next one.
4586 queuedDiscreteEvents.shift();
4587 }
4588 } // Next replay any continuous events.
4589
4590
4591 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
4592 queuedFocus = null;
4593 }
4594
4595 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
4596 queuedDrag = null;
4597 }
4598
4599 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
4600 queuedMouse = null;
4601 }
4602
4603 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
4604 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
4605}
4606
4607function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
4608 if (queuedEvent.blockedOn === unblocked) {
4609 queuedEvent.blockedOn = null;
4610
4611 if (!hasScheduledReplayAttempt) {
4612 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
4613 // now unblocked. This first might not actually be unblocked yet.
4614 // We could check it early to avoid scheduling an unnecessary callback.
4615
4616 unstable_scheduleCallback(unstable_NormalPriority, replayUnblockedEvents);
4617 }
4618 }
4619}
4620
4621function retryIfBlockedOn(unblocked) {
4622 // Mark anything that was blocked on this as no longer blocked
4623 // and eligible for a replay.
4624 if (queuedDiscreteEvents.length > 0) {
4625 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's
4626 // worth it because we expect very few discrete events to queue up and once
4627 // we are actually fully unblocked it will be fast to replay them.
4628
4629 for (var i = 1; i < queuedDiscreteEvents.length; i++) {
4630 var queuedEvent = queuedDiscreteEvents[i];
4631
4632 if (queuedEvent.blockedOn === unblocked) {
4633 queuedEvent.blockedOn = null;
4634 }
4635 }
4636 }
4637
4638 if (queuedFocus !== null) {
4639 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
4640 }
4641
4642 if (queuedDrag !== null) {
4643 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
4644 }
4645
4646 if (queuedMouse !== null) {
4647 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
4648 }
4649
4650 var unblock = function (queuedEvent) {
4651 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
4652 };
4653
4654 queuedPointers.forEach(unblock);
4655 queuedPointerCaptures.forEach(unblock);
4656
4657 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
4658 var queuedTarget = queuedExplicitHydrationTargets[_i];
4659
4660 if (queuedTarget.blockedOn === unblocked) {
4661 queuedTarget.blockedOn = null;
4662 }
4663 }
4664
4665 while (queuedExplicitHydrationTargets.length > 0) {
4666 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
4667
4668 if (nextExplicitTarget.blockedOn !== null) {
4669 // We're still blocked.
4670 break;
4671 } else {
4672 attemptExplicitHydrationTarget(nextExplicitTarget);
4673
4674 if (nextExplicitTarget.blockedOn === null) {
4675 // We're unblocked.
4676 queuedExplicitHydrationTargets.shift();
4677 }
4678 }
4679 }
4680}
4681
4682function addEventBubbleListener(element, eventType, listener) {
4683 element.addEventListener(eventType, listener, false);
4684}
4685function addEventCaptureListener(element, eventType, listener) {
4686 element.addEventListener(eventType, listener, true);
4687}
4688function addEventCaptureListenerWithPassiveFlag(element, eventType, listener, passive) {
4689 element.addEventListener(eventType, listener, {
4690 capture: true,
4691 passive: passive
4692 });
4693}
4694
4695/**
4696 * Gets the target node from a native browser event by accounting for
4697 * inconsistencies in browser DOM APIs.
4698 *
4699 * @param {object} nativeEvent Native browser event.
4700 * @return {DOMEventTarget} Target node.
4701 */
4702
4703function getEventTarget(nativeEvent) {
4704 // Fallback to nativeEvent.srcElement for IE9
4705 // https://github.com/facebook/react/issues/12506
4706 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
4707
4708 if (target.correspondingUseElement) {
4709 target = target.correspondingUseElement;
4710 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
4711 // @see http://www.quirksmode.org/js/events_properties.html
4712
4713
4714 return target.nodeType === TEXT_NODE ? target.parentNode : target;
4715}
4716
4717function getParent(inst) {
4718 do {
4719 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
4720 // That is depending on if we want nested subtrees (layers) to bubble
4721 // events to their parent. We could also go through parentNode on the
4722 // host node but that wouldn't work for React Native and doesn't let us
4723 // do the portal feature.
4724 } while (inst && inst.tag !== HostComponent);
4725
4726 if (inst) {
4727 return inst;
4728 }
4729
4730 return null;
4731}
4732/**
4733 * Return the lowest common ancestor of A and B, or null if they are in
4734 * different trees.
4735 */
4736
4737
4738function getLowestCommonAncestor(instA, instB) {
4739 var depthA = 0;
4740
4741 for (var tempA = instA; tempA; tempA = getParent(tempA)) {
4742 depthA++;
4743 }
4744
4745 var depthB = 0;
4746
4747 for (var tempB = instB; tempB; tempB = getParent(tempB)) {
4748 depthB++;
4749 } // If A is deeper, crawl up.
4750
4751
4752 while (depthA - depthB > 0) {
4753 instA = getParent(instA);
4754 depthA--;
4755 } // If B is deeper, crawl up.
4756
4757
4758 while (depthB - depthA > 0) {
4759 instB = getParent(instB);
4760 depthB--;
4761 } // Walk in lockstep until we find a match.
4762
4763
4764 var depth = depthA;
4765
4766 while (depth--) {
4767 if (instA === instB || instA === instB.alternate) {
4768 return instA;
4769 }
4770
4771 instA = getParent(instA);
4772 instB = getParent(instB);
4773 }
4774
4775 return null;
4776}
4777/**
4778 * Return if A is an ancestor of B.
4779 */
4780
4781
4782/**
4783 * Return the parent instance of the passed-in instance.
4784 */
4785
4786
4787/**
4788 * Simulates the traversal of a two-phase, capture/bubble event dispatch.
4789 */
4790
4791function traverseTwoPhase(inst, fn, arg) {
4792 var path = [];
4793
4794 while (inst) {
4795 path.push(inst);
4796 inst = getParent(inst);
4797 }
4798
4799 var i;
4800
4801 for (i = path.length; i-- > 0;) {
4802 fn(path[i], 'captured', arg);
4803 }
4804
4805 for (i = 0; i < path.length; i++) {
4806 fn(path[i], 'bubbled', arg);
4807 }
4808}
4809/**
4810 * Traverses the ID hierarchy and invokes the supplied `cb` on any IDs that
4811 * should would receive a `mouseEnter` or `mouseLeave` event.
4812 *
4813 * Does not invoke the callback on the nearest common ancestor because nothing
4814 * "entered" or "left" that element.
4815 */
4816
4817function traverseEnterLeave(from, to, fn, argFrom, argTo) {
4818 var common = from && to ? getLowestCommonAncestor(from, to) : null;
4819 var pathFrom = [];
4820
4821 while (true) {
4822 if (!from) {
4823 break;
4824 }
4825
4826 if (from === common) {
4827 break;
4828 }
4829
4830 var alternate = from.alternate;
4831
4832 if (alternate !== null && alternate === common) {
4833 break;
4834 }
4835
4836 pathFrom.push(from);
4837 from = getParent(from);
4838 }
4839
4840 var pathTo = [];
4841
4842 while (true) {
4843 if (!to) {
4844 break;
4845 }
4846
4847 if (to === common) {
4848 break;
4849 }
4850
4851 var _alternate = to.alternate;
4852
4853 if (_alternate !== null && _alternate === common) {
4854 break;
4855 }
4856
4857 pathTo.push(to);
4858 to = getParent(to);
4859 }
4860
4861 for (var i = 0; i < pathFrom.length; i++) {
4862 fn(pathFrom[i], 'bubbled', argFrom);
4863 }
4864
4865 for (var _i = pathTo.length; _i-- > 0;) {
4866 fn(pathTo[_i], 'captured', argTo);
4867 }
4868}
4869
4870/**
4871 * Some event types have a notion of different registration names for different
4872 * "phases" of propagation. This finds listeners by a given phase.
4873 */
4874function listenerAtPhase(inst, event, propagationPhase) {
4875 var registrationName = event.dispatchConfig.phasedRegistrationNames[propagationPhase];
4876 return getListener(inst, registrationName);
4877}
4878/**
4879 * A small set of propagation patterns, each of which will accept a small amount
4880 * of information, and generate a set of "dispatch ready event objects" - which
4881 * are sets of events that have already been annotated with a set of dispatched
4882 * listener functions/ids. The API is designed this way to discourage these
4883 * propagation strategies from actually executing the dispatches, since we
4884 * always want to collect the entire set of dispatches before executing even a
4885 * single one.
4886 */
4887
4888/**
4889 * Tags a `SyntheticEvent` with dispatched listeners. Creating this function
4890 * here, allows us to not have to bind or create functions for each event.
4891 * Mutating the event's members allows us to not have to create a wrapping
4892 * "dispatch" object that pairs the event with the listener.
4893 */
4894
4895
4896function accumulateDirectionalDispatches(inst, phase, event) {
4897 {
4898 !inst ? warningWithoutStack$1(false, 'Dispatching inst must not be null') : void 0;
4899 }
4900
4901 var listener = listenerAtPhase(inst, event, phase);
4902
4903 if (listener) {
4904 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
4905 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
4906 }
4907}
4908/**
4909 * Collect dispatches (must be entirely collected before dispatching - see unit
4910 * tests). Lazily allocate the array to conserve memory. We must loop through
4911 * each event and perform the traversal for each one. We cannot perform a
4912 * single traversal for the entire collection of events because each event may
4913 * have a different target.
4914 */
4915
4916
4917function accumulateTwoPhaseDispatchesSingle(event) {
4918 if (event && event.dispatchConfig.phasedRegistrationNames) {
4919 traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
4920 }
4921}
4922/**
4923 * Accumulates without regard to direction, does not look for phased
4924 * registration names. Same as `accumulateDirectDispatchesSingle` but without
4925 * requiring that the `dispatchMarker` be the same as the dispatched ID.
4926 */
4927
4928
4929function accumulateDispatches(inst, ignoredDirection, event) {
4930 if (inst && event && event.dispatchConfig.registrationName) {
4931 var registrationName = event.dispatchConfig.registrationName;
4932 var listener = getListener(inst, registrationName);
4933
4934 if (listener) {
4935 event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
4936 event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
4937 }
4938 }
4939}
4940/**
4941 * Accumulates dispatches on an `SyntheticEvent`, but only for the
4942 * `dispatchMarker`.
4943 * @param {SyntheticEvent} event
4944 */
4945
4946
4947function accumulateDirectDispatchesSingle(event) {
4948 if (event && event.dispatchConfig.registrationName) {
4949 accumulateDispatches(event._targetInst, null, event);
4950 }
4951}
4952
4953function accumulateTwoPhaseDispatches(events) {
4954 forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
4955}
4956
4957function accumulateEnterLeaveDispatches(leave, enter, from, to) {
4958 traverseEnterLeave(from, to, accumulateDispatches, leave, enter);
4959}
4960function accumulateDirectDispatches(events) {
4961 forEachAccumulated(events, accumulateDirectDispatchesSingle);
4962}
4963
4964/* eslint valid-typeof: 0 */
4965var EVENT_POOL_SIZE = 10;
4966/**
4967 * @interface Event
4968 * @see http://www.w3.org/TR/DOM-Level-3-Events/
4969 */
4970
4971var EventInterface = {
4972 type: null,
4973 target: null,
4974 // currentTarget is set when dispatching; no use in copying it here
4975 currentTarget: function () {
4976 return null;
4977 },
4978 eventPhase: null,
4979 bubbles: null,
4980 cancelable: null,
4981 timeStamp: function (event) {
4982 return event.timeStamp || Date.now();
4983 },
4984 defaultPrevented: null,
4985 isTrusted: null
4986};
4987
4988function functionThatReturnsTrue() {
4989 return true;
4990}
4991
4992function functionThatReturnsFalse() {
4993 return false;
4994}
4995/**
4996 * Synthetic events are dispatched by event plugins, typically in response to a
4997 * top-level event delegation handler.
4998 *
4999 * These systems should generally use pooling to reduce the frequency of garbage
5000 * collection. The system should check `isPersistent` to determine whether the
5001 * event should be released into the pool after being dispatched. Users that
5002 * need a persisted event should invoke `persist`.
5003 *
5004 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
5005 * normalizing browser quirks. Subclasses do not necessarily have to implement a
5006 * DOM interface; custom application-specific events can also subclass this.
5007 *
5008 * @param {object} dispatchConfig Configuration used to dispatch this event.
5009 * @param {*} targetInst Marker identifying the event target.
5010 * @param {object} nativeEvent Native browser event.
5011 * @param {DOMEventTarget} nativeEventTarget Target node.
5012 */
5013
5014
5015function SyntheticEvent(dispatchConfig, targetInst, nativeEvent, nativeEventTarget) {
5016 {
5017 // these have a getter/setter for warnings
5018 delete this.nativeEvent;
5019 delete this.preventDefault;
5020 delete this.stopPropagation;
5021 delete this.isDefaultPrevented;
5022 delete this.isPropagationStopped;
5023 }
5024
5025 this.dispatchConfig = dispatchConfig;
5026 this._targetInst = targetInst;
5027 this.nativeEvent = nativeEvent;
5028 var Interface = this.constructor.Interface;
5029
5030 for (var propName in Interface) {
5031 if (!Interface.hasOwnProperty(propName)) {
5032 continue;
5033 }
5034
5035 {
5036 delete this[propName]; // this has a getter/setter for warnings
5037 }
5038
5039 var normalize = Interface[propName];
5040
5041 if (normalize) {
5042 this[propName] = normalize(nativeEvent);
5043 } else {
5044 if (propName === 'target') {
5045 this.target = nativeEventTarget;
5046 } else {
5047 this[propName] = nativeEvent[propName];
5048 }
5049 }
5050 }
5051
5052 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
5053
5054 if (defaultPrevented) {
5055 this.isDefaultPrevented = functionThatReturnsTrue;
5056 } else {
5057 this.isDefaultPrevented = functionThatReturnsFalse;
5058 }
5059
5060 this.isPropagationStopped = functionThatReturnsFalse;
5061 return this;
5062}
5063
5064_assign(SyntheticEvent.prototype, {
5065 preventDefault: function () {
5066 this.defaultPrevented = true;
5067 var event = this.nativeEvent;
5068
5069 if (!event) {
5070 return;
5071 }
5072
5073 if (event.preventDefault) {
5074 event.preventDefault();
5075 } else if (typeof event.returnValue !== 'unknown') {
5076 event.returnValue = false;
5077 }
5078
5079 this.isDefaultPrevented = functionThatReturnsTrue;
5080 },
5081 stopPropagation: function () {
5082 var event = this.nativeEvent;
5083
5084 if (!event) {
5085 return;
5086 }
5087
5088 if (event.stopPropagation) {
5089 event.stopPropagation();
5090 } else if (typeof event.cancelBubble !== 'unknown') {
5091 // The ChangeEventPlugin registers a "propertychange" event for
5092 // IE. This event does not support bubbling or cancelling, and
5093 // any references to cancelBubble throw "Member not found". A
5094 // typeof check of "unknown" circumvents this issue (and is also
5095 // IE specific).
5096 event.cancelBubble = true;
5097 }
5098
5099 this.isPropagationStopped = functionThatReturnsTrue;
5100 },
5101
5102 /**
5103 * We release all dispatched `SyntheticEvent`s after each event loop, adding
5104 * them back into the pool. This allows a way to hold onto a reference that
5105 * won't be added back into the pool.
5106 */
5107 persist: function () {
5108 this.isPersistent = functionThatReturnsTrue;
5109 },
5110
5111 /**
5112 * Checks if this event should be released back into the pool.
5113 *
5114 * @return {boolean} True if this should not be released, false otherwise.
5115 */
5116 isPersistent: functionThatReturnsFalse,
5117
5118 /**
5119 * `PooledClass` looks for `destructor` on each instance it releases.
5120 */
5121 destructor: function () {
5122 var Interface = this.constructor.Interface;
5123
5124 for (var propName in Interface) {
5125 {
5126 Object.defineProperty(this, propName, getPooledWarningPropertyDefinition(propName, Interface[propName]));
5127 }
5128 }
5129
5130 this.dispatchConfig = null;
5131 this._targetInst = null;
5132 this.nativeEvent = null;
5133 this.isDefaultPrevented = functionThatReturnsFalse;
5134 this.isPropagationStopped = functionThatReturnsFalse;
5135 this._dispatchListeners = null;
5136 this._dispatchInstances = null;
5137
5138 {
5139 Object.defineProperty(this, 'nativeEvent', getPooledWarningPropertyDefinition('nativeEvent', null));
5140 Object.defineProperty(this, 'isDefaultPrevented', getPooledWarningPropertyDefinition('isDefaultPrevented', functionThatReturnsFalse));
5141 Object.defineProperty(this, 'isPropagationStopped', getPooledWarningPropertyDefinition('isPropagationStopped', functionThatReturnsFalse));
5142 Object.defineProperty(this, 'preventDefault', getPooledWarningPropertyDefinition('preventDefault', function () {}));
5143 Object.defineProperty(this, 'stopPropagation', getPooledWarningPropertyDefinition('stopPropagation', function () {}));
5144 }
5145 }
5146});
5147
5148SyntheticEvent.Interface = EventInterface;
5149/**
5150 * Helper to reduce boilerplate when creating subclasses.
5151 */
5152
5153SyntheticEvent.extend = function (Interface) {
5154 var Super = this;
5155
5156 var E = function () {};
5157
5158 E.prototype = Super.prototype;
5159 var prototype = new E();
5160
5161 function Class() {
5162 return Super.apply(this, arguments);
5163 }
5164
5165 _assign(prototype, Class.prototype);
5166
5167 Class.prototype = prototype;
5168 Class.prototype.constructor = Class;
5169 Class.Interface = _assign({}, Super.Interface, Interface);
5170 Class.extend = Super.extend;
5171 addEventPoolingTo(Class);
5172 return Class;
5173};
5174
5175addEventPoolingTo(SyntheticEvent);
5176/**
5177 * Helper to nullify syntheticEvent instance properties when destructing
5178 *
5179 * @param {String} propName
5180 * @param {?object} getVal
5181 * @return {object} defineProperty object
5182 */
5183
5184function getPooledWarningPropertyDefinition(propName, getVal) {
5185 var isFunction = typeof getVal === 'function';
5186 return {
5187 configurable: true,
5188 set: set,
5189 get: get
5190 };
5191
5192 function set(val) {
5193 var action = isFunction ? 'setting the method' : 'setting the property';
5194 warn(action, 'This is effectively a no-op');
5195 return val;
5196 }
5197
5198 function get() {
5199 var action = isFunction ? 'accessing the method' : 'accessing the property';
5200 var result = isFunction ? 'This is a no-op function' : 'This is set to null';
5201 warn(action, result);
5202 return getVal;
5203 }
5204
5205 function warn(action, result) {
5206 var warningCondition = false;
5207 !warningCondition ? warningWithoutStack$1(false, "This synthetic event is reused for performance reasons. If you're seeing this, " + "you're %s `%s` on a released/nullified synthetic event. %s. " + 'If you must keep the original synthetic event around, use event.persist(). ' + 'See https://fb.me/react-event-pooling for more information.', action, propName, result) : void 0;
5208 }
5209}
5210
5211function getPooledEvent(dispatchConfig, targetInst, nativeEvent, nativeInst) {
5212 var EventConstructor = this;
5213
5214 if (EventConstructor.eventPool.length) {
5215 var instance = EventConstructor.eventPool.pop();
5216 EventConstructor.call(instance, dispatchConfig, targetInst, nativeEvent, nativeInst);
5217 return instance;
5218 }
5219
5220 return new EventConstructor(dispatchConfig, targetInst, nativeEvent, nativeInst);
5221}
5222
5223function releasePooledEvent(event) {
5224 var EventConstructor = this;
5225
5226 if (!(event instanceof EventConstructor)) {
5227 {
5228 throw Error("Trying to release an event instance into a pool of a different type.");
5229 }
5230 }
5231
5232 event.destructor();
5233
5234 if (EventConstructor.eventPool.length < EVENT_POOL_SIZE) {
5235 EventConstructor.eventPool.push(event);
5236 }
5237}
5238
5239function addEventPoolingTo(EventConstructor) {
5240 EventConstructor.eventPool = [];
5241 EventConstructor.getPooled = getPooledEvent;
5242 EventConstructor.release = releasePooledEvent;
5243}
5244
5245/**
5246 * @interface Event
5247 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
5248 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
5249 */
5250
5251var SyntheticAnimationEvent = SyntheticEvent.extend({
5252 animationName: null,
5253 elapsedTime: null,
5254 pseudoElement: null
5255});
5256
5257/**
5258 * @interface Event
5259 * @see http://www.w3.org/TR/clipboard-apis/
5260 */
5261
5262var SyntheticClipboardEvent = SyntheticEvent.extend({
5263 clipboardData: function (event) {
5264 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
5265 }
5266});
5267
5268var SyntheticUIEvent = SyntheticEvent.extend({
5269 view: null,
5270 detail: null
5271});
5272
5273/**
5274 * @interface FocusEvent
5275 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5276 */
5277
5278var SyntheticFocusEvent = SyntheticUIEvent.extend({
5279 relatedTarget: null
5280});
5281
5282/**
5283 * `charCode` represents the actual "character code" and is safe to use with
5284 * `String.fromCharCode`. As such, only keys that correspond to printable
5285 * characters produce a valid `charCode`, the only exception to this is Enter.
5286 * The Tab-key is considered non-printable and does not have a `charCode`,
5287 * presumably because it does not produce a tab-character in browsers.
5288 *
5289 * @param {object} nativeEvent Native browser event.
5290 * @return {number} Normalized `charCode` property.
5291 */
5292function getEventCharCode(nativeEvent) {
5293 var charCode;
5294 var keyCode = nativeEvent.keyCode;
5295
5296 if ('charCode' in nativeEvent) {
5297 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
5298
5299 if (charCode === 0 && keyCode === 13) {
5300 charCode = 13;
5301 }
5302 } else {
5303 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
5304 charCode = keyCode;
5305 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
5306 // report Enter as charCode 10 when ctrl is pressed.
5307
5308
5309 if (charCode === 10) {
5310 charCode = 13;
5311 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
5312 // Must not discard the (non-)printable Enter-key.
5313
5314
5315 if (charCode >= 32 || charCode === 13) {
5316 return charCode;
5317 }
5318
5319 return 0;
5320}
5321
5322/**
5323 * Normalization of deprecated HTML5 `key` values
5324 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5325 */
5326
5327var normalizeKey = {
5328 Esc: 'Escape',
5329 Spacebar: ' ',
5330 Left: 'ArrowLeft',
5331 Up: 'ArrowUp',
5332 Right: 'ArrowRight',
5333 Down: 'ArrowDown',
5334 Del: 'Delete',
5335 Win: 'OS',
5336 Menu: 'ContextMenu',
5337 Apps: 'ContextMenu',
5338 Scroll: 'ScrollLock',
5339 MozPrintableKey: 'Unidentified'
5340};
5341/**
5342 * Translation from legacy `keyCode` to HTML5 `key`
5343 * Only special keys supported, all others depend on keyboard layout or browser
5344 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
5345 */
5346
5347var translateToKey = {
5348 '8': 'Backspace',
5349 '9': 'Tab',
5350 '12': 'Clear',
5351 '13': 'Enter',
5352 '16': 'Shift',
5353 '17': 'Control',
5354 '18': 'Alt',
5355 '19': 'Pause',
5356 '20': 'CapsLock',
5357 '27': 'Escape',
5358 '32': ' ',
5359 '33': 'PageUp',
5360 '34': 'PageDown',
5361 '35': 'End',
5362 '36': 'Home',
5363 '37': 'ArrowLeft',
5364 '38': 'ArrowUp',
5365 '39': 'ArrowRight',
5366 '40': 'ArrowDown',
5367 '45': 'Insert',
5368 '46': 'Delete',
5369 '112': 'F1',
5370 '113': 'F2',
5371 '114': 'F3',
5372 '115': 'F4',
5373 '116': 'F5',
5374 '117': 'F6',
5375 '118': 'F7',
5376 '119': 'F8',
5377 '120': 'F9',
5378 '121': 'F10',
5379 '122': 'F11',
5380 '123': 'F12',
5381 '144': 'NumLock',
5382 '145': 'ScrollLock',
5383 '224': 'Meta'
5384};
5385/**
5386 * @param {object} nativeEvent Native browser event.
5387 * @return {string} Normalized `key` property.
5388 */
5389
5390function getEventKey(nativeEvent) {
5391 if (nativeEvent.key) {
5392 // Normalize inconsistent values reported by browsers due to
5393 // implementations of a working draft specification.
5394 // FireFox implements `key` but returns `MozPrintableKey` for all
5395 // printable characters (normalized to `Unidentified`), ignore it.
5396 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
5397
5398 if (key !== 'Unidentified') {
5399 return key;
5400 }
5401 } // Browser does not implement `key`, polyfill as much of it as we can.
5402
5403
5404 if (nativeEvent.type === 'keypress') {
5405 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
5406 // thus be captured by `keypress`, no other non-printable key should.
5407
5408 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
5409 }
5410
5411 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
5412 // While user keyboard layout determines the actual meaning of each
5413 // `keyCode` value, almost all function keys have a universal value.
5414 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
5415 }
5416
5417 return '';
5418}
5419
5420/**
5421 * Translation from modifier key to the associated property in the event.
5422 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
5423 */
5424var modifierKeyToProp = {
5425 Alt: 'altKey',
5426 Control: 'ctrlKey',
5427 Meta: 'metaKey',
5428 Shift: 'shiftKey'
5429}; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
5430// getModifierState. If getModifierState is not supported, we map it to a set of
5431// modifier keys exposed by the event. In this case, Lock-keys are not supported.
5432
5433function modifierStateGetter(keyArg) {
5434 var syntheticEvent = this;
5435 var nativeEvent = syntheticEvent.nativeEvent;
5436
5437 if (nativeEvent.getModifierState) {
5438 return nativeEvent.getModifierState(keyArg);
5439 }
5440
5441 var keyProp = modifierKeyToProp[keyArg];
5442 return keyProp ? !!nativeEvent[keyProp] : false;
5443}
5444
5445function getEventModifierState(nativeEvent) {
5446 return modifierStateGetter;
5447}
5448
5449/**
5450 * @interface KeyboardEvent
5451 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5452 */
5453
5454var SyntheticKeyboardEvent = SyntheticUIEvent.extend({
5455 key: getEventKey,
5456 location: null,
5457 ctrlKey: null,
5458 shiftKey: null,
5459 altKey: null,
5460 metaKey: null,
5461 repeat: null,
5462 locale: null,
5463 getModifierState: getEventModifierState,
5464 // Legacy Interface
5465 charCode: function (event) {
5466 // `charCode` is the result of a KeyPress event and represents the value of
5467 // the actual printable character.
5468 // KeyPress is deprecated, but its replacement is not yet final and not
5469 // implemented in any major browser. Only KeyPress has charCode.
5470 if (event.type === 'keypress') {
5471 return getEventCharCode(event);
5472 }
5473
5474 return 0;
5475 },
5476 keyCode: function (event) {
5477 // `keyCode` is the result of a KeyDown/Up event and represents the value of
5478 // physical keyboard key.
5479 // The actual meaning of the value depends on the users' keyboard layout
5480 // which cannot be detected. Assuming that it is a US keyboard layout
5481 // provides a surprisingly accurate mapping for US and European users.
5482 // Due to this, it is left to the user to implement at this time.
5483 if (event.type === 'keydown' || event.type === 'keyup') {
5484 return event.keyCode;
5485 }
5486
5487 return 0;
5488 },
5489 which: function (event) {
5490 // `which` is an alias for either `keyCode` or `charCode` depending on the
5491 // type of the event.
5492 if (event.type === 'keypress') {
5493 return getEventCharCode(event);
5494 }
5495
5496 if (event.type === 'keydown' || event.type === 'keyup') {
5497 return event.keyCode;
5498 }
5499
5500 return 0;
5501 }
5502});
5503
5504var previousScreenX = 0;
5505var previousScreenY = 0; // Use flags to signal movementX/Y has already been set
5506
5507var isMovementXSet = false;
5508var isMovementYSet = false;
5509/**
5510 * @interface MouseEvent
5511 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5512 */
5513
5514var SyntheticMouseEvent = SyntheticUIEvent.extend({
5515 screenX: null,
5516 screenY: null,
5517 clientX: null,
5518 clientY: null,
5519 pageX: null,
5520 pageY: null,
5521 ctrlKey: null,
5522 shiftKey: null,
5523 altKey: null,
5524 metaKey: null,
5525 getModifierState: getEventModifierState,
5526 button: null,
5527 buttons: null,
5528 relatedTarget: function (event) {
5529 return event.relatedTarget || (event.fromElement === event.srcElement ? event.toElement : event.fromElement);
5530 },
5531 movementX: function (event) {
5532 if ('movementX' in event) {
5533 return event.movementX;
5534 }
5535
5536 var screenX = previousScreenX;
5537 previousScreenX = event.screenX;
5538
5539 if (!isMovementXSet) {
5540 isMovementXSet = true;
5541 return 0;
5542 }
5543
5544 return event.type === 'mousemove' ? event.screenX - screenX : 0;
5545 },
5546 movementY: function (event) {
5547 if ('movementY' in event) {
5548 return event.movementY;
5549 }
5550
5551 var screenY = previousScreenY;
5552 previousScreenY = event.screenY;
5553
5554 if (!isMovementYSet) {
5555 isMovementYSet = true;
5556 return 0;
5557 }
5558
5559 return event.type === 'mousemove' ? event.screenY - screenY : 0;
5560 }
5561});
5562
5563/**
5564 * @interface PointerEvent
5565 * @see http://www.w3.org/TR/pointerevents/
5566 */
5567
5568var SyntheticPointerEvent = SyntheticMouseEvent.extend({
5569 pointerId: null,
5570 width: null,
5571 height: null,
5572 pressure: null,
5573 tangentialPressure: null,
5574 tiltX: null,
5575 tiltY: null,
5576 twist: null,
5577 pointerType: null,
5578 isPrimary: null
5579});
5580
5581/**
5582 * @interface DragEvent
5583 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5584 */
5585
5586var SyntheticDragEvent = SyntheticMouseEvent.extend({
5587 dataTransfer: null
5588});
5589
5590/**
5591 * @interface TouchEvent
5592 * @see http://www.w3.org/TR/touch-events/
5593 */
5594
5595var SyntheticTouchEvent = SyntheticUIEvent.extend({
5596 touches: null,
5597 targetTouches: null,
5598 changedTouches: null,
5599 altKey: null,
5600 metaKey: null,
5601 ctrlKey: null,
5602 shiftKey: null,
5603 getModifierState: getEventModifierState
5604});
5605
5606/**
5607 * @interface Event
5608 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
5609 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
5610 */
5611
5612var SyntheticTransitionEvent = SyntheticEvent.extend({
5613 propertyName: null,
5614 elapsedTime: null,
5615 pseudoElement: null
5616});
5617
5618/**
5619 * @interface WheelEvent
5620 * @see http://www.w3.org/TR/DOM-Level-3-Events/
5621 */
5622
5623var SyntheticWheelEvent = SyntheticMouseEvent.extend({
5624 deltaX: function (event) {
5625 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
5626 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
5627 },
5628 deltaY: function (event) {
5629 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
5630 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
5631 'wheelDelta' in event ? -event.wheelDelta : 0;
5632 },
5633 deltaZ: null,
5634 // Browsers without "deltaMode" is reporting in raw wheel delta where one
5635 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
5636 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
5637 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
5638 deltaMode: null
5639});
5640
5641/**
5642 * Turns
5643 * ['abort', ...]
5644 * into
5645 * eventTypes = {
5646 * 'abort': {
5647 * phasedRegistrationNames: {
5648 * bubbled: 'onAbort',
5649 * captured: 'onAbortCapture',
5650 * },
5651 * dependencies: [TOP_ABORT],
5652 * },
5653 * ...
5654 * };
5655 * topLevelEventsToDispatchConfig = new Map([
5656 * [TOP_ABORT, { sameConfig }],
5657 * ]);
5658 */
5659
5660var eventTuples = [// Discrete events
5661[TOP_BLUR, 'blur', DiscreteEvent], [TOP_CANCEL, 'cancel', DiscreteEvent], [TOP_CLICK, 'click', DiscreteEvent], [TOP_CLOSE, 'close', DiscreteEvent], [TOP_CONTEXT_MENU, 'contextMenu', DiscreteEvent], [TOP_COPY, 'copy', DiscreteEvent], [TOP_CUT, 'cut', DiscreteEvent], [TOP_AUX_CLICK, 'auxClick', DiscreteEvent], [TOP_DOUBLE_CLICK, 'doubleClick', DiscreteEvent], [TOP_DRAG_END, 'dragEnd', DiscreteEvent], [TOP_DRAG_START, 'dragStart', DiscreteEvent], [TOP_DROP, 'drop', DiscreteEvent], [TOP_FOCUS, 'focus', DiscreteEvent], [TOP_INPUT, 'input', DiscreteEvent], [TOP_INVALID, 'invalid', DiscreteEvent], [TOP_KEY_DOWN, 'keyDown', DiscreteEvent], [TOP_KEY_PRESS, 'keyPress', DiscreteEvent], [TOP_KEY_UP, 'keyUp', DiscreteEvent], [TOP_MOUSE_DOWN, 'mouseDown', DiscreteEvent], [TOP_MOUSE_UP, 'mouseUp', DiscreteEvent], [TOP_PASTE, 'paste', DiscreteEvent], [TOP_PAUSE, 'pause', DiscreteEvent], [TOP_PLAY, 'play', DiscreteEvent], [TOP_POINTER_CANCEL, 'pointerCancel', DiscreteEvent], [TOP_POINTER_DOWN, 'pointerDown', DiscreteEvent], [TOP_POINTER_UP, 'pointerUp', DiscreteEvent], [TOP_RATE_CHANGE, 'rateChange', DiscreteEvent], [TOP_RESET, 'reset', DiscreteEvent], [TOP_SEEKED, 'seeked', DiscreteEvent], [TOP_SUBMIT, 'submit', DiscreteEvent], [TOP_TOUCH_CANCEL, 'touchCancel', DiscreteEvent], [TOP_TOUCH_END, 'touchEnd', DiscreteEvent], [TOP_TOUCH_START, 'touchStart', DiscreteEvent], [TOP_VOLUME_CHANGE, 'volumeChange', DiscreteEvent], // User-blocking events
5662[TOP_DRAG, 'drag', UserBlockingEvent], [TOP_DRAG_ENTER, 'dragEnter', UserBlockingEvent], [TOP_DRAG_EXIT, 'dragExit', UserBlockingEvent], [TOP_DRAG_LEAVE, 'dragLeave', UserBlockingEvent], [TOP_DRAG_OVER, 'dragOver', UserBlockingEvent], [TOP_MOUSE_MOVE, 'mouseMove', UserBlockingEvent], [TOP_MOUSE_OUT, 'mouseOut', UserBlockingEvent], [TOP_MOUSE_OVER, 'mouseOver', UserBlockingEvent], [TOP_POINTER_MOVE, 'pointerMove', UserBlockingEvent], [TOP_POINTER_OUT, 'pointerOut', UserBlockingEvent], [TOP_POINTER_OVER, 'pointerOver', UserBlockingEvent], [TOP_SCROLL, 'scroll', UserBlockingEvent], [TOP_TOGGLE, 'toggle', UserBlockingEvent], [TOP_TOUCH_MOVE, 'touchMove', UserBlockingEvent], [TOP_WHEEL, 'wheel', UserBlockingEvent], // Continuous events
5663[TOP_ABORT, 'abort', ContinuousEvent], [TOP_ANIMATION_END, 'animationEnd', ContinuousEvent], [TOP_ANIMATION_ITERATION, 'animationIteration', ContinuousEvent], [TOP_ANIMATION_START, 'animationStart', ContinuousEvent], [TOP_CAN_PLAY, 'canPlay', ContinuousEvent], [TOP_CAN_PLAY_THROUGH, 'canPlayThrough', ContinuousEvent], [TOP_DURATION_CHANGE, 'durationChange', ContinuousEvent], [TOP_EMPTIED, 'emptied', ContinuousEvent], [TOP_ENCRYPTED, 'encrypted', ContinuousEvent], [TOP_ENDED, 'ended', ContinuousEvent], [TOP_ERROR, 'error', ContinuousEvent], [TOP_GOT_POINTER_CAPTURE, 'gotPointerCapture', ContinuousEvent], [TOP_LOAD, 'load', ContinuousEvent], [TOP_LOADED_DATA, 'loadedData', ContinuousEvent], [TOP_LOADED_METADATA, 'loadedMetadata', ContinuousEvent], [TOP_LOAD_START, 'loadStart', ContinuousEvent], [TOP_LOST_POINTER_CAPTURE, 'lostPointerCapture', ContinuousEvent], [TOP_PLAYING, 'playing', ContinuousEvent], [TOP_PROGRESS, 'progress', ContinuousEvent], [TOP_SEEKING, 'seeking', ContinuousEvent], [TOP_STALLED, 'stalled', ContinuousEvent], [TOP_SUSPEND, 'suspend', ContinuousEvent], [TOP_TIME_UPDATE, 'timeUpdate', ContinuousEvent], [TOP_TRANSITION_END, 'transitionEnd', ContinuousEvent], [TOP_WAITING, 'waiting', ContinuousEvent]];
5664var eventTypes = {};
5665var topLevelEventsToDispatchConfig = {};
5666
5667for (var i = 0; i < eventTuples.length; i++) {
5668 var eventTuple = eventTuples[i];
5669 var topEvent = eventTuple[0];
5670 var event = eventTuple[1];
5671 var eventPriority = eventTuple[2];
5672 var capitalizedEvent = event[0].toUpperCase() + event.slice(1);
5673 var onEvent = 'on' + capitalizedEvent;
5674 var config = {
5675 phasedRegistrationNames: {
5676 bubbled: onEvent,
5677 captured: onEvent + 'Capture'
5678 },
5679 dependencies: [topEvent],
5680 eventPriority: eventPriority
5681 };
5682 eventTypes[event] = config;
5683 topLevelEventsToDispatchConfig[topEvent] = config;
5684} // Only used in DEV for exhaustiveness validation.
5685
5686
5687var knownHTMLTopLevelTypes = [TOP_ABORT, TOP_CANCEL, TOP_CAN_PLAY, TOP_CAN_PLAY_THROUGH, TOP_CLOSE, TOP_DURATION_CHANGE, TOP_EMPTIED, TOP_ENCRYPTED, TOP_ENDED, TOP_ERROR, TOP_INPUT, TOP_INVALID, TOP_LOAD, TOP_LOADED_DATA, TOP_LOADED_METADATA, TOP_LOAD_START, TOP_PAUSE, TOP_PLAY, TOP_PLAYING, TOP_PROGRESS, TOP_RATE_CHANGE, TOP_RESET, TOP_SEEKED, TOP_SEEKING, TOP_STALLED, TOP_SUBMIT, TOP_SUSPEND, TOP_TIME_UPDATE, TOP_TOGGLE, TOP_VOLUME_CHANGE, TOP_WAITING];
5688var SimpleEventPlugin = {
5689 eventTypes: eventTypes,
5690 getEventPriority: function (topLevelType) {
5691 var config = topLevelEventsToDispatchConfig[topLevelType];
5692 return config !== undefined ? config.eventPriority : ContinuousEvent;
5693 },
5694 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
5695 var dispatchConfig = topLevelEventsToDispatchConfig[topLevelType];
5696
5697 if (!dispatchConfig) {
5698 return null;
5699 }
5700
5701 var EventConstructor;
5702
5703 switch (topLevelType) {
5704 case TOP_KEY_PRESS:
5705 // Firefox creates a keypress event for function keys too. This removes
5706 // the unwanted keypress events. Enter is however both printable and
5707 // non-printable. One would expect Tab to be as well (but it isn't).
5708 if (getEventCharCode(nativeEvent) === 0) {
5709 return null;
5710 }
5711
5712 /* falls through */
5713
5714 case TOP_KEY_DOWN:
5715 case TOP_KEY_UP:
5716 EventConstructor = SyntheticKeyboardEvent;
5717 break;
5718
5719 case TOP_BLUR:
5720 case TOP_FOCUS:
5721 EventConstructor = SyntheticFocusEvent;
5722 break;
5723
5724 case TOP_CLICK:
5725 // Firefox creates a click event on right mouse clicks. This removes the
5726 // unwanted click events.
5727 if (nativeEvent.button === 2) {
5728 return null;
5729 }
5730
5731 /* falls through */
5732
5733 case TOP_AUX_CLICK:
5734 case TOP_DOUBLE_CLICK:
5735 case TOP_MOUSE_DOWN:
5736 case TOP_MOUSE_MOVE:
5737 case TOP_MOUSE_UP: // TODO: Disabled elements should not respond to mouse events
5738
5739 /* falls through */
5740
5741 case TOP_MOUSE_OUT:
5742 case TOP_MOUSE_OVER:
5743 case TOP_CONTEXT_MENU:
5744 EventConstructor = SyntheticMouseEvent;
5745 break;
5746
5747 case TOP_DRAG:
5748 case TOP_DRAG_END:
5749 case TOP_DRAG_ENTER:
5750 case TOP_DRAG_EXIT:
5751 case TOP_DRAG_LEAVE:
5752 case TOP_DRAG_OVER:
5753 case TOP_DRAG_START:
5754 case TOP_DROP:
5755 EventConstructor = SyntheticDragEvent;
5756 break;
5757
5758 case TOP_TOUCH_CANCEL:
5759 case TOP_TOUCH_END:
5760 case TOP_TOUCH_MOVE:
5761 case TOP_TOUCH_START:
5762 EventConstructor = SyntheticTouchEvent;
5763 break;
5764
5765 case TOP_ANIMATION_END:
5766 case TOP_ANIMATION_ITERATION:
5767 case TOP_ANIMATION_START:
5768 EventConstructor = SyntheticAnimationEvent;
5769 break;
5770
5771 case TOP_TRANSITION_END:
5772 EventConstructor = SyntheticTransitionEvent;
5773 break;
5774
5775 case TOP_SCROLL:
5776 EventConstructor = SyntheticUIEvent;
5777 break;
5778
5779 case TOP_WHEEL:
5780 EventConstructor = SyntheticWheelEvent;
5781 break;
5782
5783 case TOP_COPY:
5784 case TOP_CUT:
5785 case TOP_PASTE:
5786 EventConstructor = SyntheticClipboardEvent;
5787 break;
5788
5789 case TOP_GOT_POINTER_CAPTURE:
5790 case TOP_LOST_POINTER_CAPTURE:
5791 case TOP_POINTER_CANCEL:
5792 case TOP_POINTER_DOWN:
5793 case TOP_POINTER_MOVE:
5794 case TOP_POINTER_OUT:
5795 case TOP_POINTER_OVER:
5796 case TOP_POINTER_UP:
5797 EventConstructor = SyntheticPointerEvent;
5798 break;
5799
5800 default:
5801 {
5802 if (knownHTMLTopLevelTypes.indexOf(topLevelType) === -1) {
5803 warningWithoutStack$1(false, 'SimpleEventPlugin: Unhandled event type, `%s`. This warning ' + 'is likely caused by a bug in React. Please file an issue.', topLevelType);
5804 }
5805 } // HTML Events
5806 // @see http://www.w3.org/TR/html5/index.html#events-0
5807
5808
5809 EventConstructor = SyntheticEvent;
5810 break;
5811 }
5812
5813 var event = EventConstructor.getPooled(dispatchConfig, targetInst, nativeEvent, nativeEventTarget);
5814 accumulateTwoPhaseDispatches(event);
5815 return event;
5816 }
5817};
5818
5819var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners
5820// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
5821
5822if (enableFlareAPI && canUseDOM) {
5823 try {
5824 var options = {}; // $FlowFixMe: Ignore Flow complaining about needing a value
5825
5826 Object.defineProperty(options, 'passive', {
5827 get: function () {
5828 passiveBrowserEventsSupported = true;
5829 }
5830 });
5831 window.addEventListener('test', options, options);
5832 window.removeEventListener('test', options, options);
5833 } catch (e) {
5834 passiveBrowserEventsSupported = false;
5835 }
5836}
5837
5838// Intentionally not named imports because Rollup would use dynamic dispatch for
5839// CommonJS interop named imports.
5840var UserBlockingPriority$1 = unstable_UserBlockingPriority;
5841var runWithPriority$1 = unstable_runWithPriority;
5842var getEventPriority = SimpleEventPlugin.getEventPriority;
5843var CALLBACK_BOOKKEEPING_POOL_SIZE = 10;
5844var callbackBookkeepingPool = [];
5845
5846/**
5847 * Find the deepest React component completely containing the root of the
5848 * passed-in instance (for use when entire React trees are nested within each
5849 * other). If React trees are not nested, returns null.
5850 */
5851function findRootContainerNode(inst) {
5852 if (inst.tag === HostRoot) {
5853 return inst.stateNode.containerInfo;
5854 } // TODO: It may be a good idea to cache this to prevent unnecessary DOM
5855 // traversal, but caching is difficult to do correctly without using a
5856 // mutation observer to listen for all DOM changes.
5857
5858
5859 while (inst.return) {
5860 inst = inst.return;
5861 }
5862
5863 if (inst.tag !== HostRoot) {
5864 // This can happen if we're in a detached tree.
5865 return null;
5866 }
5867
5868 return inst.stateNode.containerInfo;
5869} // Used to store ancestor hierarchy in top level callback
5870
5871
5872function getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags) {
5873 if (callbackBookkeepingPool.length) {
5874 var instance = callbackBookkeepingPool.pop();
5875 instance.topLevelType = topLevelType;
5876 instance.eventSystemFlags = eventSystemFlags;
5877 instance.nativeEvent = nativeEvent;
5878 instance.targetInst = targetInst;
5879 return instance;
5880 }
5881
5882 return {
5883 topLevelType: topLevelType,
5884 eventSystemFlags: eventSystemFlags,
5885 nativeEvent: nativeEvent,
5886 targetInst: targetInst,
5887 ancestors: []
5888 };
5889}
5890
5891function releaseTopLevelCallbackBookKeeping(instance) {
5892 instance.topLevelType = null;
5893 instance.nativeEvent = null;
5894 instance.targetInst = null;
5895 instance.ancestors.length = 0;
5896
5897 if (callbackBookkeepingPool.length < CALLBACK_BOOKKEEPING_POOL_SIZE) {
5898 callbackBookkeepingPool.push(instance);
5899 }
5900}
5901
5902function handleTopLevel(bookKeeping) {
5903 var targetInst = bookKeeping.targetInst; // Loop through the hierarchy, in case there's any nested components.
5904 // It's important that we build the array of ancestors before calling any
5905 // event handlers, because event handlers can modify the DOM, leading to
5906 // inconsistencies with ReactMount's node cache. See #1105.
5907
5908 var ancestor = targetInst;
5909
5910 do {
5911 if (!ancestor) {
5912 var ancestors = bookKeeping.ancestors;
5913 ancestors.push(ancestor);
5914 break;
5915 }
5916
5917 var root = findRootContainerNode(ancestor);
5918
5919 if (!root) {
5920 break;
5921 }
5922
5923 var tag = ancestor.tag;
5924
5925 if (tag === HostComponent || tag === HostText) {
5926 bookKeeping.ancestors.push(ancestor);
5927 }
5928
5929 ancestor = getClosestInstanceFromNode(root);
5930 } while (ancestor);
5931
5932 for (var i = 0; i < bookKeeping.ancestors.length; i++) {
5933 targetInst = bookKeeping.ancestors[i];
5934 var eventTarget = getEventTarget(bookKeeping.nativeEvent);
5935 var topLevelType = bookKeeping.topLevelType;
5936 var nativeEvent = bookKeeping.nativeEvent;
5937 runExtractedPluginEventsInBatch(topLevelType, targetInst, nativeEvent, eventTarget, bookKeeping.eventSystemFlags);
5938 }
5939} // TODO: can we stop exporting these?
5940
5941
5942var _enabled = true;
5943function setEnabled(enabled) {
5944 _enabled = !!enabled;
5945}
5946function isEnabled() {
5947 return _enabled;
5948}
5949function trapBubbledEvent(topLevelType, element) {
5950 trapEventForPluginEventSystem(element, topLevelType, false);
5951}
5952function trapCapturedEvent(topLevelType, element) {
5953 trapEventForPluginEventSystem(element, topLevelType, true);
5954}
5955function trapEventForResponderEventSystem(element, topLevelType, passive) {
5956 if (enableFlareAPI) {
5957 var rawEventName = getRawEventName(topLevelType);
5958 var eventFlags = RESPONDER_EVENT_SYSTEM; // If passive option is not supported, then the event will be
5959 // active and not passive, but we flag it as using not being
5960 // supported too. This way the responder event plugins know,
5961 // and can provide polyfills if needed.
5962
5963 if (passive) {
5964 if (passiveBrowserEventsSupported) {
5965 eventFlags |= IS_PASSIVE;
5966 } else {
5967 eventFlags |= IS_ACTIVE;
5968 eventFlags |= PASSIVE_NOT_SUPPORTED;
5969 passive = false;
5970 }
5971 } else {
5972 eventFlags |= IS_ACTIVE;
5973 } // Check if interactive and wrap in discreteUpdates
5974
5975
5976 var listener = dispatchEvent.bind(null, topLevelType, eventFlags);
5977
5978 if (passiveBrowserEventsSupported) {
5979 addEventCaptureListenerWithPassiveFlag(element, rawEventName, listener, passive);
5980 } else {
5981 addEventCaptureListener(element, rawEventName, listener);
5982 }
5983 }
5984}
5985
5986function trapEventForPluginEventSystem(element, topLevelType, capture) {
5987 var listener;
5988
5989 switch (getEventPriority(topLevelType)) {
5990 case DiscreteEvent:
5991 listener = dispatchDiscreteEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
5992 break;
5993
5994 case UserBlockingEvent:
5995 listener = dispatchUserBlockingUpdate.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
5996 break;
5997
5998 case ContinuousEvent:
5999 default:
6000 listener = dispatchEvent.bind(null, topLevelType, PLUGIN_EVENT_SYSTEM);
6001 break;
6002 }
6003
6004 var rawEventName = getRawEventName(topLevelType);
6005
6006 if (capture) {
6007 addEventCaptureListener(element, rawEventName, listener);
6008 } else {
6009 addEventBubbleListener(element, rawEventName, listener);
6010 }
6011}
6012
6013function dispatchDiscreteEvent(topLevelType, eventSystemFlags, nativeEvent) {
6014 flushDiscreteUpdatesIfNeeded(nativeEvent.timeStamp);
6015 discreteUpdates(dispatchEvent, topLevelType, eventSystemFlags, nativeEvent);
6016}
6017
6018function dispatchUserBlockingUpdate(topLevelType, eventSystemFlags, nativeEvent) {
6019 runWithPriority$1(UserBlockingPriority$1, dispatchEvent.bind(null, topLevelType, eventSystemFlags, nativeEvent));
6020}
6021
6022function dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst) {
6023 var bookKeeping = getTopLevelCallbackBookKeeping(topLevelType, nativeEvent, targetInst, eventSystemFlags);
6024
6025 try {
6026 // Event queue being processed in the same cycle allows
6027 // `preventDefault`.
6028 batchedEventUpdates(handleTopLevel, bookKeeping);
6029 } finally {
6030 releaseTopLevelCallbackBookKeeping(bookKeeping);
6031 }
6032}
6033
6034function dispatchEvent(topLevelType, eventSystemFlags, nativeEvent) {
6035 if (!_enabled) {
6036 return;
6037 }
6038
6039 if (hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(topLevelType)) {
6040 // If we already have a queue of discrete events, and this is another discrete
6041 // event, then we can't dispatch it regardless of its target, since they
6042 // need to dispatch in order.
6043 queueDiscreteEvent(null, // Flags that we're not actually blocked on anything as far as we know.
6044 topLevelType, eventSystemFlags, nativeEvent);
6045 return;
6046 }
6047
6048 var blockedOn = attemptToDispatchEvent(topLevelType, eventSystemFlags, nativeEvent);
6049
6050 if (blockedOn === null) {
6051 // We successfully dispatched this event.
6052 clearIfContinuousEvent(topLevelType, nativeEvent);
6053 return;
6054 }
6055
6056 if (isReplayableDiscreteEvent(topLevelType)) {
6057 // This this to be replayed later once the target is available.
6058 queueDiscreteEvent(blockedOn, topLevelType, eventSystemFlags, nativeEvent);
6059 return;
6060 }
6061
6062 if (queueIfContinuousEvent(blockedOn, topLevelType, eventSystemFlags, nativeEvent)) {
6063 return;
6064 } // We need to clear only if we didn't queue because
6065 // queueing is accummulative.
6066
6067
6068 clearIfContinuousEvent(topLevelType, nativeEvent); // This is not replayable so we'll invoke it but without a target,
6069 // in case the event system needs to trace it.
6070
6071 if (enableFlareAPI) {
6072 if (eventSystemFlags & PLUGIN_EVENT_SYSTEM) {
6073 dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, null);
6074 }
6075
6076 if (eventSystemFlags & RESPONDER_EVENT_SYSTEM) {
6077 // React Flare event system
6078 dispatchEventForResponderEventSystem(topLevelType, null, nativeEvent, getEventTarget(nativeEvent), eventSystemFlags);
6079 }
6080 } else {
6081 dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, null);
6082 }
6083} // Attempt dispatching an event. Returns a SuspenseInstance or Container if it's blocked.
6084
6085function attemptToDispatchEvent(topLevelType, eventSystemFlags, nativeEvent) {
6086 // TODO: Warn if _enabled is false.
6087 var nativeEventTarget = getEventTarget(nativeEvent);
6088 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
6089
6090 if (targetInst !== null) {
6091 var nearestMounted = getNearestMountedFiber(targetInst);
6092
6093 if (nearestMounted === null) {
6094 // This tree has been unmounted already. Dispatch without a target.
6095 targetInst = null;
6096 } else {
6097 var tag = nearestMounted.tag;
6098
6099 if (tag === SuspenseComponent) {
6100 var instance = getSuspenseInstanceFromFiber(nearestMounted);
6101
6102 if (instance !== null) {
6103 // Queue the event to be replayed later. Abort dispatching since we
6104 // don't want this event dispatched twice through the event system.
6105 // TODO: If this is the first discrete event in the queue. Schedule an increased
6106 // priority for this boundary.
6107 return instance;
6108 } // This shouldn't happen, something went wrong but to avoid blocking
6109 // the whole system, dispatch the event without a target.
6110 // TODO: Warn.
6111
6112
6113 targetInst = null;
6114 } else if (tag === HostRoot) {
6115 var root = nearestMounted.stateNode;
6116
6117 if (root.hydrate) {
6118 // If this happens during a replay something went wrong and it might block
6119 // the whole system.
6120 return getContainerFromFiber(nearestMounted);
6121 }
6122
6123 targetInst = null;
6124 } else if (nearestMounted !== targetInst) {
6125 // If we get an event (ex: img onload) before committing that
6126 // component's mount, ignore it for now (that is, treat it as if it was an
6127 // event on a non-React tree). We might also consider queueing events and
6128 // dispatching them after the mount.
6129 targetInst = null;
6130 }
6131 }
6132 }
6133
6134 if (enableFlareAPI) {
6135 if (eventSystemFlags & PLUGIN_EVENT_SYSTEM) {
6136 dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
6137 }
6138
6139 if (eventSystemFlags & RESPONDER_EVENT_SYSTEM) {
6140 // React Flare event system
6141 dispatchEventForResponderEventSystem(topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
6142 }
6143 } else {
6144 dispatchEventForPluginEventSystem(topLevelType, eventSystemFlags, nativeEvent, targetInst);
6145 } // We're not blocked on anything.
6146
6147
6148 return null;
6149}
6150
6151/**
6152 * Checks if an event is supported in the current execution environment.
6153 *
6154 * NOTE: This will not work correctly for non-generic events such as `change`,
6155 * `reset`, `load`, `error`, and `select`.
6156 *
6157 * Borrows from Modernizr.
6158 *
6159 * @param {string} eventNameSuffix Event name, e.g. "click".
6160 * @return {boolean} True if the event is supported.
6161 * @internal
6162 * @license Modernizr 3.0.0pre (Custom Build) | MIT
6163 */
6164
6165function isEventSupported(eventNameSuffix) {
6166 if (!canUseDOM) {
6167 return false;
6168 }
6169
6170 var eventName = 'on' + eventNameSuffix;
6171 var isSupported = eventName in document;
6172
6173 if (!isSupported) {
6174 var element = document.createElement('div');
6175 element.setAttribute(eventName, 'return;');
6176 isSupported = typeof element[eventName] === 'function';
6177 }
6178
6179 return isSupported;
6180}
6181
6182/**
6183 * Summary of `ReactBrowserEventEmitter` event handling:
6184 *
6185 * - Top-level delegation is used to trap most native browser events. This
6186 * may only occur in the main thread and is the responsibility of
6187 * ReactDOMEventListener, which is injected and can therefore support
6188 * pluggable event sources. This is the only work that occurs in the main
6189 * thread.
6190 *
6191 * - We normalize and de-duplicate events to account for browser quirks. This
6192 * may be done in the worker thread.
6193 *
6194 * - Forward these native events (with the associated top-level type used to
6195 * trap it) to `EventPluginHub`, which in turn will ask plugins if they want
6196 * to extract any synthetic events.
6197 *
6198 * - The `EventPluginHub` will then process each event by annotating them with
6199 * "dispatches", a sequence of listeners and IDs that care about that event.
6200 *
6201 * - The `EventPluginHub` then dispatches the events.
6202 *
6203 * Overview of React and the event system:
6204 *
6205 * +------------+ .
6206 * | DOM | .
6207 * +------------+ .
6208 * | .
6209 * v .
6210 * +------------+ .
6211 * | ReactEvent | .
6212 * | Listener | .
6213 * +------------+ . +-----------+
6214 * | . +--------+|SimpleEvent|
6215 * | . | |Plugin |
6216 * +-----|------+ . v +-----------+
6217 * | | | . +--------------+ +------------+
6218 * | +-----------.--->|EventPluginHub| | Event |
6219 * | | . | | +-----------+ | Propagators|
6220 * | ReactEvent | . | | |TapEvent | |------------|
6221 * | Emitter | . | |<---+|Plugin | |other plugin|
6222 * | | . | | +-----------+ | utilities |
6223 * | +-----------.--->| | +------------+
6224 * | | | . +--------------+
6225 * +-----|------+ . ^ +-----------+
6226 * | . | |Enter/Leave|
6227 * + . +-------+|Plugin |
6228 * +-------------+ . +-----------+
6229 * | application | .
6230 * |-------------| .
6231 * | | .
6232 * | | .
6233 * +-------------+ .
6234 * .
6235 * React Core . General Purpose Event Plugin System
6236 */
6237
6238var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
6239var elementListeningSets = new PossiblyWeakMap();
6240function getListeningSetForElement(element) {
6241 var listeningSet = elementListeningSets.get(element);
6242
6243 if (listeningSet === undefined) {
6244 listeningSet = new Set();
6245 elementListeningSets.set(element, listeningSet);
6246 }
6247
6248 return listeningSet;
6249}
6250/**
6251 * We listen for bubbled touch events on the document object.
6252 *
6253 * Firefox v8.01 (and possibly others) exhibited strange behavior when
6254 * mounting `onmousemove` events at some node that was not the document
6255 * element. The symptoms were that if your mouse is not moving over something
6256 * contained within that mount point (for example on the background) the
6257 * top-level listeners for `onmousemove` won't be called. However, if you
6258 * register the `mousemove` on the document object, then it will of course
6259 * catch all `mousemove`s. This along with iOS quirks, justifies restricting
6260 * top-level listeners to the document object only, at least for these
6261 * movement types of events and possibly all events.
6262 *
6263 * @see http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
6264 *
6265 * Also, `keyup`/`keypress`/`keydown` do not bubble to the window on IE, but
6266 * they bubble to document.
6267 *
6268 * @param {string} registrationName Name of listener (e.g. `onClick`).
6269 * @param {object} mountAt Container where to mount the listener
6270 */
6271
6272function listenTo(registrationName, mountAt) {
6273 var listeningSet = getListeningSetForElement(mountAt);
6274 var dependencies = registrationNameDependencies[registrationName];
6275
6276 for (var i = 0; i < dependencies.length; i++) {
6277 var dependency = dependencies[i];
6278 listenToTopLevel(dependency, mountAt, listeningSet);
6279 }
6280}
6281function listenToTopLevel(topLevelType, mountAt, listeningSet) {
6282 if (!listeningSet.has(topLevelType)) {
6283 switch (topLevelType) {
6284 case TOP_SCROLL:
6285 trapCapturedEvent(TOP_SCROLL, mountAt);
6286 break;
6287
6288 case TOP_FOCUS:
6289 case TOP_BLUR:
6290 trapCapturedEvent(TOP_FOCUS, mountAt);
6291 trapCapturedEvent(TOP_BLUR, mountAt); // We set the flag for a single dependency later in this function,
6292 // but this ensures we mark both as attached rather than just one.
6293
6294 listeningSet.add(TOP_BLUR);
6295 listeningSet.add(TOP_FOCUS);
6296 break;
6297
6298 case TOP_CANCEL:
6299 case TOP_CLOSE:
6300 if (isEventSupported(getRawEventName(topLevelType))) {
6301 trapCapturedEvent(topLevelType, mountAt);
6302 }
6303
6304 break;
6305
6306 case TOP_INVALID:
6307 case TOP_SUBMIT:
6308 case TOP_RESET:
6309 // We listen to them on the target DOM elements.
6310 // Some of them bubble so we don't want them to fire twice.
6311 break;
6312
6313 default:
6314 // By default, listen on the top level to all non-media events.
6315 // Media events don't bubble so adding the listener wouldn't do anything.
6316 var isMediaEvent = mediaEventTypes.indexOf(topLevelType) !== -1;
6317
6318 if (!isMediaEvent) {
6319 trapBubbledEvent(topLevelType, mountAt);
6320 }
6321
6322 break;
6323 }
6324
6325 listeningSet.add(topLevelType);
6326 }
6327}
6328function isListeningToAllDependencies(registrationName, mountAt) {
6329 var listeningSet = getListeningSetForElement(mountAt);
6330 var dependencies = registrationNameDependencies[registrationName];
6331
6332 for (var i = 0; i < dependencies.length; i++) {
6333 var dependency = dependencies[i];
6334
6335 if (!listeningSet.has(dependency)) {
6336 return false;
6337 }
6338 }
6339
6340 return true;
6341}
6342
6343// List derived from Gecko source code:
6344// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
6345var shorthandToLonghand = {
6346 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
6347 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
6348 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
6349 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6350 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
6351 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
6352 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
6353 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
6354 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
6355 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
6356 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
6357 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
6358 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
6359 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
6360 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
6361 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
6362 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
6363 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
6364 columns: ['columnCount', 'columnWidth'],
6365 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
6366 flexFlow: ['flexDirection', 'flexWrap'],
6367 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
6368 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
6369 gap: ['columnGap', 'rowGap'],
6370 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6371 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
6372 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
6373 gridColumnGap: ['columnGap'],
6374 gridGap: ['columnGap', 'rowGap'],
6375 gridRow: ['gridRowEnd', 'gridRowStart'],
6376 gridRowGap: ['rowGap'],
6377 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
6378 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
6379 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
6380 marker: ['markerEnd', 'markerMid', 'markerStart'],
6381 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
6382 maskPosition: ['maskPositionX', 'maskPositionY'],
6383 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
6384 overflow: ['overflowX', 'overflowY'],
6385 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
6386 placeContent: ['alignContent', 'justifyContent'],
6387 placeItems: ['alignItems', 'justifyItems'],
6388 placeSelf: ['alignSelf', 'justifySelf'],
6389 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
6390 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
6391 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
6392 wordWrap: ['overflowWrap']
6393};
6394
6395/**
6396 * CSS properties which accept numbers but are not in units of "px".
6397 */
6398var isUnitlessNumber = {
6399 animationIterationCount: true,
6400 borderImageOutset: true,
6401 borderImageSlice: true,
6402 borderImageWidth: true,
6403 boxFlex: true,
6404 boxFlexGroup: true,
6405 boxOrdinalGroup: true,
6406 columnCount: true,
6407 columns: true,
6408 flex: true,
6409 flexGrow: true,
6410 flexPositive: true,
6411 flexShrink: true,
6412 flexNegative: true,
6413 flexOrder: true,
6414 gridArea: true,
6415 gridRow: true,
6416 gridRowEnd: true,
6417 gridRowSpan: true,
6418 gridRowStart: true,
6419 gridColumn: true,
6420 gridColumnEnd: true,
6421 gridColumnSpan: true,
6422 gridColumnStart: true,
6423 fontWeight: true,
6424 lineClamp: true,
6425 lineHeight: true,
6426 opacity: true,
6427 order: true,
6428 orphans: true,
6429 tabSize: true,
6430 widows: true,
6431 zIndex: true,
6432 zoom: true,
6433 // SVG-related properties
6434 fillOpacity: true,
6435 floodOpacity: true,
6436 stopOpacity: true,
6437 strokeDasharray: true,
6438 strokeDashoffset: true,
6439 strokeMiterlimit: true,
6440 strokeOpacity: true,
6441 strokeWidth: true
6442};
6443/**
6444 * @param {string} prefix vendor-specific prefix, eg: Webkit
6445 * @param {string} key style name, eg: transitionDuration
6446 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
6447 * WebkitTransitionDuration
6448 */
6449
6450function prefixKey(prefix, key) {
6451 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
6452}
6453/**
6454 * Support style names that may come passed in prefixed by adding permutations
6455 * of vendor prefixes.
6456 */
6457
6458
6459var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
6460// infinite loop, because it iterates over the newly added props too.
6461
6462Object.keys(isUnitlessNumber).forEach(function (prop) {
6463 prefixes.forEach(function (prefix) {
6464 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
6465 });
6466});
6467
6468/**
6469 * Convert a value into the proper css writable value. The style name `name`
6470 * should be logical (no hyphens), as specified
6471 * in `CSSProperty.isUnitlessNumber`.
6472 *
6473 * @param {string} name CSS property name such as `topMargin`.
6474 * @param {*} value CSS property value such as `10px`.
6475 * @return {string} Normalized style value with dimensions applied.
6476 */
6477
6478function dangerousStyleValue(name, value, isCustomProperty) {
6479 // Note that we've removed escapeTextForBrowser() calls here since the
6480 // whole string will be escaped when the attribute is injected into
6481 // the markup. If you provide unsafe user data here they can inject
6482 // arbitrary CSS which may be problematic (I couldn't repro this):
6483 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
6484 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
6485 // This is not an XSS hole but instead a potential CSS injection issue
6486 // which has lead to a greater discussion about how we're going to
6487 // trust URLs moving forward. See #2115901
6488 var isEmpty = value == null || typeof value === 'boolean' || value === '';
6489
6490 if (isEmpty) {
6491 return '';
6492 }
6493
6494 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
6495 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
6496 }
6497
6498 return ('' + value).trim();
6499}
6500
6501var uppercasePattern = /([A-Z])/g;
6502var msPattern = /^ms-/;
6503/**
6504 * Hyphenates a camelcased CSS property name, for example:
6505 *
6506 * > hyphenateStyleName('backgroundColor')
6507 * < "background-color"
6508 * > hyphenateStyleName('MozTransition')
6509 * < "-moz-transition"
6510 * > hyphenateStyleName('msTransition')
6511 * < "-ms-transition"
6512 *
6513 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
6514 * is converted to `-ms-`.
6515 */
6516
6517function hyphenateStyleName(name) {
6518 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
6519}
6520
6521var warnValidStyle = function () {};
6522
6523{
6524 // 'msTransform' is correct, but the other prefixes should be capitalized
6525 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
6526 var msPattern$1 = /^-ms-/;
6527 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
6528
6529 var badStyleValueWithSemicolonPattern = /;\s*$/;
6530 var warnedStyleNames = {};
6531 var warnedStyleValues = {};
6532 var warnedForNaNValue = false;
6533 var warnedForInfinityValue = false;
6534
6535 var camelize = function (string) {
6536 return string.replace(hyphenPattern, function (_, character) {
6537 return character.toUpperCase();
6538 });
6539 };
6540
6541 var warnHyphenatedStyleName = function (name) {
6542 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6543 return;
6544 }
6545
6546 warnedStyleNames[name] = true;
6547 warning$1(false, 'Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
6548 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
6549 // is converted to lowercase `ms`.
6550 camelize(name.replace(msPattern$1, 'ms-')));
6551 };
6552
6553 var warnBadVendoredStyleName = function (name) {
6554 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
6555 return;
6556 }
6557
6558 warnedStyleNames[name] = true;
6559 warning$1(false, 'Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
6560 };
6561
6562 var warnStyleValueWithSemicolon = function (name, value) {
6563 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
6564 return;
6565 }
6566
6567 warnedStyleValues[value] = true;
6568 warning$1(false, "Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
6569 };
6570
6571 var warnStyleValueIsNaN = function (name, value) {
6572 if (warnedForNaNValue) {
6573 return;
6574 }
6575
6576 warnedForNaNValue = true;
6577 warning$1(false, '`NaN` is an invalid value for the `%s` css style property.', name);
6578 };
6579
6580 var warnStyleValueIsInfinity = function (name, value) {
6581 if (warnedForInfinityValue) {
6582 return;
6583 }
6584
6585 warnedForInfinityValue = true;
6586 warning$1(false, '`Infinity` is an invalid value for the `%s` css style property.', name);
6587 };
6588
6589 warnValidStyle = function (name, value) {
6590 if (name.indexOf('-') > -1) {
6591 warnHyphenatedStyleName(name);
6592 } else if (badVendoredStyleNamePattern.test(name)) {
6593 warnBadVendoredStyleName(name);
6594 } else if (badStyleValueWithSemicolonPattern.test(value)) {
6595 warnStyleValueWithSemicolon(name, value);
6596 }
6597
6598 if (typeof value === 'number') {
6599 if (isNaN(value)) {
6600 warnStyleValueIsNaN(name, value);
6601 } else if (!isFinite(value)) {
6602 warnStyleValueIsInfinity(name, value);
6603 }
6604 }
6605 };
6606}
6607
6608var warnValidStyle$1 = warnValidStyle;
6609
6610/**
6611 * Operations for dealing with CSS properties.
6612 */
6613
6614/**
6615 * This creates a string that is expected to be equivalent to the style
6616 * attribute generated by server-side rendering. It by-passes warnings and
6617 * security checks so it's not safe to use this value for anything other than
6618 * comparison. It is only used in DEV for SSR validation.
6619 */
6620
6621function createDangerousStringForStyles(styles) {
6622 {
6623 var serialized = '';
6624 var delimiter = '';
6625
6626 for (var styleName in styles) {
6627 if (!styles.hasOwnProperty(styleName)) {
6628 continue;
6629 }
6630
6631 var styleValue = styles[styleName];
6632
6633 if (styleValue != null) {
6634 var isCustomProperty = styleName.indexOf('--') === 0;
6635 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
6636 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
6637 delimiter = ';';
6638 }
6639 }
6640
6641 return serialized || null;
6642 }
6643}
6644/**
6645 * Sets the value for multiple styles on a node. If a value is specified as
6646 * '' (empty string), the corresponding style property will be unset.
6647 *
6648 * @param {DOMElement} node
6649 * @param {object} styles
6650 */
6651
6652function setValueForStyles(node, styles) {
6653 var style = node.style;
6654
6655 for (var styleName in styles) {
6656 if (!styles.hasOwnProperty(styleName)) {
6657 continue;
6658 }
6659
6660 var isCustomProperty = styleName.indexOf('--') === 0;
6661
6662 {
6663 if (!isCustomProperty) {
6664 warnValidStyle$1(styleName, styles[styleName]);
6665 }
6666 }
6667
6668 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
6669
6670 if (styleName === 'float') {
6671 styleName = 'cssFloat';
6672 }
6673
6674 if (isCustomProperty) {
6675 style.setProperty(styleName, styleValue);
6676 } else {
6677 style[styleName] = styleValue;
6678 }
6679 }
6680}
6681
6682function isValueEmpty(value) {
6683 return value == null || typeof value === 'boolean' || value === '';
6684}
6685/**
6686 * Given {color: 'red', overflow: 'hidden'} returns {
6687 * color: 'color',
6688 * overflowX: 'overflow',
6689 * overflowY: 'overflow',
6690 * }. This can be read as "the overflowY property was set by the overflow
6691 * shorthand". That is, the values are the property that each was derived from.
6692 */
6693
6694
6695function expandShorthandMap(styles) {
6696 var expanded = {};
6697
6698 for (var key in styles) {
6699 var longhands = shorthandToLonghand[key] || [key];
6700
6701 for (var i = 0; i < longhands.length; i++) {
6702 expanded[longhands[i]] = key;
6703 }
6704 }
6705
6706 return expanded;
6707}
6708/**
6709 * When mixing shorthand and longhand property names, we warn during updates if
6710 * we expect an incorrect result to occur. In particular, we warn for:
6711 *
6712 * Updating a shorthand property (longhand gets overwritten):
6713 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
6714 * becomes .style.font = 'baz'
6715 * Removing a shorthand property (longhand gets lost too):
6716 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
6717 * becomes .style.font = ''
6718 * Removing a longhand property (should revert to shorthand; doesn't):
6719 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
6720 * becomes .style.fontVariant = ''
6721 */
6722
6723
6724function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
6725 if (!warnAboutShorthandPropertyCollision) {
6726 return;
6727 }
6728
6729 if (!nextStyles) {
6730 return;
6731 }
6732
6733 var expandedUpdates = expandShorthandMap(styleUpdates);
6734 var expandedStyles = expandShorthandMap(nextStyles);
6735 var warnedAbout = {};
6736
6737 for (var key in expandedUpdates) {
6738 var originalKey = expandedUpdates[key];
6739 var correctOriginalKey = expandedStyles[key];
6740
6741 if (correctOriginalKey && originalKey !== correctOriginalKey) {
6742 var warningKey = originalKey + ',' + correctOriginalKey;
6743
6744 if (warnedAbout[warningKey]) {
6745 continue;
6746 }
6747
6748 warnedAbout[warningKey] = true;
6749 warning$1(false, '%s a style property during rerender (%s) when a ' + 'conflicting property is set (%s) can lead to styling bugs. To ' + "avoid this, don't mix shorthand and non-shorthand properties " + 'for the same value; instead, replace the shorthand with ' + 'separate values.', isValueEmpty(styleUpdates[originalKey]) ? 'Removing' : 'Updating', originalKey, correctOriginalKey);
6750 }
6751 }
6752}
6753
6754// For HTML, certain tags should omit their close tag. We keep a whitelist for
6755// those special-case tags.
6756var omittedCloseTags = {
6757 area: true,
6758 base: true,
6759 br: true,
6760 col: true,
6761 embed: true,
6762 hr: true,
6763 img: true,
6764 input: true,
6765 keygen: true,
6766 link: true,
6767 meta: true,
6768 param: true,
6769 source: true,
6770 track: true,
6771 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
6772
6773};
6774
6775// `omittedCloseTags` except that `menuitem` should still have its closing tag.
6776
6777var voidElementTags = _assign({
6778 menuitem: true
6779}, omittedCloseTags);
6780
6781// or add stack by default to invariants where possible.
6782
6783var HTML$1 = '__html';
6784var ReactDebugCurrentFrame$3 = null;
6785
6786{
6787 ReactDebugCurrentFrame$3 = ReactSharedInternals.ReactDebugCurrentFrame;
6788}
6789
6790function assertValidProps(tag, props) {
6791 if (!props) {
6792 return;
6793 } // Note the use of `==` which checks for null or undefined.
6794
6795
6796 if (voidElementTags[tag]) {
6797 if (!(props.children == null && props.dangerouslySetInnerHTML == null)) {
6798 {
6799 throw Error(tag + " is a void element tag and must neither have `children` nor use `dangerouslySetInnerHTML`." + (ReactDebugCurrentFrame$3.getStackAddendum()));
6800 }
6801 }
6802 }
6803
6804 if (props.dangerouslySetInnerHTML != null) {
6805 if (!(props.children == null)) {
6806 {
6807 throw Error("Can only set one of `children` or `props.dangerouslySetInnerHTML`.");
6808 }
6809 }
6810
6811 if (!(typeof props.dangerouslySetInnerHTML === 'object' && HTML$1 in props.dangerouslySetInnerHTML)) {
6812 {
6813 throw Error("`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. Please visit https://fb.me/react-invariant-dangerously-set-inner-html for more information.");
6814 }
6815 }
6816 }
6817
6818 {
6819 !(props.suppressContentEditableWarning || !props.contentEditable || props.children == null) ? warning$1(false, 'A component is `contentEditable` and contains `children` managed by ' + 'React. It is now your responsibility to guarantee that none of ' + 'those nodes are unexpectedly modified or duplicated. This is ' + 'probably not intentional.') : void 0;
6820 }
6821
6822 if (!(props.style == null || typeof props.style === 'object')) {
6823 {
6824 throw Error("The `style` prop expects a mapping from style properties to values, not a string. For example, style={{marginRight: spacing + 'em'}} when using JSX." + (ReactDebugCurrentFrame$3.getStackAddendum()));
6825 }
6826 }
6827}
6828
6829function isCustomComponent(tagName, props) {
6830 if (tagName.indexOf('-') === -1) {
6831 return typeof props.is === 'string';
6832 }
6833
6834 switch (tagName) {
6835 // These are reserved SVG and MathML elements.
6836 // We don't mind this whitelist too much because we expect it to never grow.
6837 // The alternative is to track the namespace in a few places which is convoluted.
6838 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
6839 case 'annotation-xml':
6840 case 'color-profile':
6841 case 'font-face':
6842 case 'font-face-src':
6843 case 'font-face-uri':
6844 case 'font-face-format':
6845 case 'font-face-name':
6846 case 'missing-glyph':
6847 return false;
6848
6849 default:
6850 return true;
6851 }
6852}
6853
6854// When adding attributes to the HTML or SVG whitelist, be sure to
6855// also add them to this module to ensure casing and incorrect name
6856// warnings.
6857var possibleStandardNames = {
6858 // HTML
6859 accept: 'accept',
6860 acceptcharset: 'acceptCharset',
6861 'accept-charset': 'acceptCharset',
6862 accesskey: 'accessKey',
6863 action: 'action',
6864 allowfullscreen: 'allowFullScreen',
6865 alt: 'alt',
6866 as: 'as',
6867 async: 'async',
6868 autocapitalize: 'autoCapitalize',
6869 autocomplete: 'autoComplete',
6870 autocorrect: 'autoCorrect',
6871 autofocus: 'autoFocus',
6872 autoplay: 'autoPlay',
6873 autosave: 'autoSave',
6874 capture: 'capture',
6875 cellpadding: 'cellPadding',
6876 cellspacing: 'cellSpacing',
6877 challenge: 'challenge',
6878 charset: 'charSet',
6879 checked: 'checked',
6880 children: 'children',
6881 cite: 'cite',
6882 class: 'className',
6883 classid: 'classID',
6884 classname: 'className',
6885 cols: 'cols',
6886 colspan: 'colSpan',
6887 content: 'content',
6888 contenteditable: 'contentEditable',
6889 contextmenu: 'contextMenu',
6890 controls: 'controls',
6891 controlslist: 'controlsList',
6892 coords: 'coords',
6893 crossorigin: 'crossOrigin',
6894 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
6895 data: 'data',
6896 datetime: 'dateTime',
6897 default: 'default',
6898 defaultchecked: 'defaultChecked',
6899 defaultvalue: 'defaultValue',
6900 defer: 'defer',
6901 dir: 'dir',
6902 disabled: 'disabled',
6903 disablepictureinpicture: 'disablePictureInPicture',
6904 download: 'download',
6905 draggable: 'draggable',
6906 enctype: 'encType',
6907 for: 'htmlFor',
6908 form: 'form',
6909 formmethod: 'formMethod',
6910 formaction: 'formAction',
6911 formenctype: 'formEncType',
6912 formnovalidate: 'formNoValidate',
6913 formtarget: 'formTarget',
6914 frameborder: 'frameBorder',
6915 headers: 'headers',
6916 height: 'height',
6917 hidden: 'hidden',
6918 high: 'high',
6919 href: 'href',
6920 hreflang: 'hrefLang',
6921 htmlfor: 'htmlFor',
6922 httpequiv: 'httpEquiv',
6923 'http-equiv': 'httpEquiv',
6924 icon: 'icon',
6925 id: 'id',
6926 innerhtml: 'innerHTML',
6927 inputmode: 'inputMode',
6928 integrity: 'integrity',
6929 is: 'is',
6930 itemid: 'itemID',
6931 itemprop: 'itemProp',
6932 itemref: 'itemRef',
6933 itemscope: 'itemScope',
6934 itemtype: 'itemType',
6935 keyparams: 'keyParams',
6936 keytype: 'keyType',
6937 kind: 'kind',
6938 label: 'label',
6939 lang: 'lang',
6940 list: 'list',
6941 loop: 'loop',
6942 low: 'low',
6943 manifest: 'manifest',
6944 marginwidth: 'marginWidth',
6945 marginheight: 'marginHeight',
6946 max: 'max',
6947 maxlength: 'maxLength',
6948 media: 'media',
6949 mediagroup: 'mediaGroup',
6950 method: 'method',
6951 min: 'min',
6952 minlength: 'minLength',
6953 multiple: 'multiple',
6954 muted: 'muted',
6955 name: 'name',
6956 nomodule: 'noModule',
6957 nonce: 'nonce',
6958 novalidate: 'noValidate',
6959 open: 'open',
6960 optimum: 'optimum',
6961 pattern: 'pattern',
6962 placeholder: 'placeholder',
6963 playsinline: 'playsInline',
6964 poster: 'poster',
6965 preload: 'preload',
6966 profile: 'profile',
6967 radiogroup: 'radioGroup',
6968 readonly: 'readOnly',
6969 referrerpolicy: 'referrerPolicy',
6970 rel: 'rel',
6971 required: 'required',
6972 reversed: 'reversed',
6973 role: 'role',
6974 rows: 'rows',
6975 rowspan: 'rowSpan',
6976 sandbox: 'sandbox',
6977 scope: 'scope',
6978 scoped: 'scoped',
6979 scrolling: 'scrolling',
6980 seamless: 'seamless',
6981 selected: 'selected',
6982 shape: 'shape',
6983 size: 'size',
6984 sizes: 'sizes',
6985 span: 'span',
6986 spellcheck: 'spellCheck',
6987 src: 'src',
6988 srcdoc: 'srcDoc',
6989 srclang: 'srcLang',
6990 srcset: 'srcSet',
6991 start: 'start',
6992 step: 'step',
6993 style: 'style',
6994 summary: 'summary',
6995 tabindex: 'tabIndex',
6996 target: 'target',
6997 title: 'title',
6998 type: 'type',
6999 usemap: 'useMap',
7000 value: 'value',
7001 width: 'width',
7002 wmode: 'wmode',
7003 wrap: 'wrap',
7004 // SVG
7005 about: 'about',
7006 accentheight: 'accentHeight',
7007 'accent-height': 'accentHeight',
7008 accumulate: 'accumulate',
7009 additive: 'additive',
7010 alignmentbaseline: 'alignmentBaseline',
7011 'alignment-baseline': 'alignmentBaseline',
7012 allowreorder: 'allowReorder',
7013 alphabetic: 'alphabetic',
7014 amplitude: 'amplitude',
7015 arabicform: 'arabicForm',
7016 'arabic-form': 'arabicForm',
7017 ascent: 'ascent',
7018 attributename: 'attributeName',
7019 attributetype: 'attributeType',
7020 autoreverse: 'autoReverse',
7021 azimuth: 'azimuth',
7022 basefrequency: 'baseFrequency',
7023 baselineshift: 'baselineShift',
7024 'baseline-shift': 'baselineShift',
7025 baseprofile: 'baseProfile',
7026 bbox: 'bbox',
7027 begin: 'begin',
7028 bias: 'bias',
7029 by: 'by',
7030 calcmode: 'calcMode',
7031 capheight: 'capHeight',
7032 'cap-height': 'capHeight',
7033 clip: 'clip',
7034 clippath: 'clipPath',
7035 'clip-path': 'clipPath',
7036 clippathunits: 'clipPathUnits',
7037 cliprule: 'clipRule',
7038 'clip-rule': 'clipRule',
7039 color: 'color',
7040 colorinterpolation: 'colorInterpolation',
7041 'color-interpolation': 'colorInterpolation',
7042 colorinterpolationfilters: 'colorInterpolationFilters',
7043 'color-interpolation-filters': 'colorInterpolationFilters',
7044 colorprofile: 'colorProfile',
7045 'color-profile': 'colorProfile',
7046 colorrendering: 'colorRendering',
7047 'color-rendering': 'colorRendering',
7048 contentscripttype: 'contentScriptType',
7049 contentstyletype: 'contentStyleType',
7050 cursor: 'cursor',
7051 cx: 'cx',
7052 cy: 'cy',
7053 d: 'd',
7054 datatype: 'datatype',
7055 decelerate: 'decelerate',
7056 descent: 'descent',
7057 diffuseconstant: 'diffuseConstant',
7058 direction: 'direction',
7059 display: 'display',
7060 divisor: 'divisor',
7061 dominantbaseline: 'dominantBaseline',
7062 'dominant-baseline': 'dominantBaseline',
7063 dur: 'dur',
7064 dx: 'dx',
7065 dy: 'dy',
7066 edgemode: 'edgeMode',
7067 elevation: 'elevation',
7068 enablebackground: 'enableBackground',
7069 'enable-background': 'enableBackground',
7070 end: 'end',
7071 exponent: 'exponent',
7072 externalresourcesrequired: 'externalResourcesRequired',
7073 fill: 'fill',
7074 fillopacity: 'fillOpacity',
7075 'fill-opacity': 'fillOpacity',
7076 fillrule: 'fillRule',
7077 'fill-rule': 'fillRule',
7078 filter: 'filter',
7079 filterres: 'filterRes',
7080 filterunits: 'filterUnits',
7081 floodopacity: 'floodOpacity',
7082 'flood-opacity': 'floodOpacity',
7083 floodcolor: 'floodColor',
7084 'flood-color': 'floodColor',
7085 focusable: 'focusable',
7086 fontfamily: 'fontFamily',
7087 'font-family': 'fontFamily',
7088 fontsize: 'fontSize',
7089 'font-size': 'fontSize',
7090 fontsizeadjust: 'fontSizeAdjust',
7091 'font-size-adjust': 'fontSizeAdjust',
7092 fontstretch: 'fontStretch',
7093 'font-stretch': 'fontStretch',
7094 fontstyle: 'fontStyle',
7095 'font-style': 'fontStyle',
7096 fontvariant: 'fontVariant',
7097 'font-variant': 'fontVariant',
7098 fontweight: 'fontWeight',
7099 'font-weight': 'fontWeight',
7100 format: 'format',
7101 from: 'from',
7102 fx: 'fx',
7103 fy: 'fy',
7104 g1: 'g1',
7105 g2: 'g2',
7106 glyphname: 'glyphName',
7107 'glyph-name': 'glyphName',
7108 glyphorientationhorizontal: 'glyphOrientationHorizontal',
7109 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
7110 glyphorientationvertical: 'glyphOrientationVertical',
7111 'glyph-orientation-vertical': 'glyphOrientationVertical',
7112 glyphref: 'glyphRef',
7113 gradienttransform: 'gradientTransform',
7114 gradientunits: 'gradientUnits',
7115 hanging: 'hanging',
7116 horizadvx: 'horizAdvX',
7117 'horiz-adv-x': 'horizAdvX',
7118 horizoriginx: 'horizOriginX',
7119 'horiz-origin-x': 'horizOriginX',
7120 ideographic: 'ideographic',
7121 imagerendering: 'imageRendering',
7122 'image-rendering': 'imageRendering',
7123 in2: 'in2',
7124 in: 'in',
7125 inlist: 'inlist',
7126 intercept: 'intercept',
7127 k1: 'k1',
7128 k2: 'k2',
7129 k3: 'k3',
7130 k4: 'k4',
7131 k: 'k',
7132 kernelmatrix: 'kernelMatrix',
7133 kernelunitlength: 'kernelUnitLength',
7134 kerning: 'kerning',
7135 keypoints: 'keyPoints',
7136 keysplines: 'keySplines',
7137 keytimes: 'keyTimes',
7138 lengthadjust: 'lengthAdjust',
7139 letterspacing: 'letterSpacing',
7140 'letter-spacing': 'letterSpacing',
7141 lightingcolor: 'lightingColor',
7142 'lighting-color': 'lightingColor',
7143 limitingconeangle: 'limitingConeAngle',
7144 local: 'local',
7145 markerend: 'markerEnd',
7146 'marker-end': 'markerEnd',
7147 markerheight: 'markerHeight',
7148 markermid: 'markerMid',
7149 'marker-mid': 'markerMid',
7150 markerstart: 'markerStart',
7151 'marker-start': 'markerStart',
7152 markerunits: 'markerUnits',
7153 markerwidth: 'markerWidth',
7154 mask: 'mask',
7155 maskcontentunits: 'maskContentUnits',
7156 maskunits: 'maskUnits',
7157 mathematical: 'mathematical',
7158 mode: 'mode',
7159 numoctaves: 'numOctaves',
7160 offset: 'offset',
7161 opacity: 'opacity',
7162 operator: 'operator',
7163 order: 'order',
7164 orient: 'orient',
7165 orientation: 'orientation',
7166 origin: 'origin',
7167 overflow: 'overflow',
7168 overlineposition: 'overlinePosition',
7169 'overline-position': 'overlinePosition',
7170 overlinethickness: 'overlineThickness',
7171 'overline-thickness': 'overlineThickness',
7172 paintorder: 'paintOrder',
7173 'paint-order': 'paintOrder',
7174 panose1: 'panose1',
7175 'panose-1': 'panose1',
7176 pathlength: 'pathLength',
7177 patterncontentunits: 'patternContentUnits',
7178 patterntransform: 'patternTransform',
7179 patternunits: 'patternUnits',
7180 pointerevents: 'pointerEvents',
7181 'pointer-events': 'pointerEvents',
7182 points: 'points',
7183 pointsatx: 'pointsAtX',
7184 pointsaty: 'pointsAtY',
7185 pointsatz: 'pointsAtZ',
7186 prefix: 'prefix',
7187 preservealpha: 'preserveAlpha',
7188 preserveaspectratio: 'preserveAspectRatio',
7189 primitiveunits: 'primitiveUnits',
7190 property: 'property',
7191 r: 'r',
7192 radius: 'radius',
7193 refx: 'refX',
7194 refy: 'refY',
7195 renderingintent: 'renderingIntent',
7196 'rendering-intent': 'renderingIntent',
7197 repeatcount: 'repeatCount',
7198 repeatdur: 'repeatDur',
7199 requiredextensions: 'requiredExtensions',
7200 requiredfeatures: 'requiredFeatures',
7201 resource: 'resource',
7202 restart: 'restart',
7203 result: 'result',
7204 results: 'results',
7205 rotate: 'rotate',
7206 rx: 'rx',
7207 ry: 'ry',
7208 scale: 'scale',
7209 security: 'security',
7210 seed: 'seed',
7211 shaperendering: 'shapeRendering',
7212 'shape-rendering': 'shapeRendering',
7213 slope: 'slope',
7214 spacing: 'spacing',
7215 specularconstant: 'specularConstant',
7216 specularexponent: 'specularExponent',
7217 speed: 'speed',
7218 spreadmethod: 'spreadMethod',
7219 startoffset: 'startOffset',
7220 stddeviation: 'stdDeviation',
7221 stemh: 'stemh',
7222 stemv: 'stemv',
7223 stitchtiles: 'stitchTiles',
7224 stopcolor: 'stopColor',
7225 'stop-color': 'stopColor',
7226 stopopacity: 'stopOpacity',
7227 'stop-opacity': 'stopOpacity',
7228 strikethroughposition: 'strikethroughPosition',
7229 'strikethrough-position': 'strikethroughPosition',
7230 strikethroughthickness: 'strikethroughThickness',
7231 'strikethrough-thickness': 'strikethroughThickness',
7232 string: 'string',
7233 stroke: 'stroke',
7234 strokedasharray: 'strokeDasharray',
7235 'stroke-dasharray': 'strokeDasharray',
7236 strokedashoffset: 'strokeDashoffset',
7237 'stroke-dashoffset': 'strokeDashoffset',
7238 strokelinecap: 'strokeLinecap',
7239 'stroke-linecap': 'strokeLinecap',
7240 strokelinejoin: 'strokeLinejoin',
7241 'stroke-linejoin': 'strokeLinejoin',
7242 strokemiterlimit: 'strokeMiterlimit',
7243 'stroke-miterlimit': 'strokeMiterlimit',
7244 strokewidth: 'strokeWidth',
7245 'stroke-width': 'strokeWidth',
7246 strokeopacity: 'strokeOpacity',
7247 'stroke-opacity': 'strokeOpacity',
7248 suppresscontenteditablewarning: 'suppressContentEditableWarning',
7249 suppresshydrationwarning: 'suppressHydrationWarning',
7250 surfacescale: 'surfaceScale',
7251 systemlanguage: 'systemLanguage',
7252 tablevalues: 'tableValues',
7253 targetx: 'targetX',
7254 targety: 'targetY',
7255 textanchor: 'textAnchor',
7256 'text-anchor': 'textAnchor',
7257 textdecoration: 'textDecoration',
7258 'text-decoration': 'textDecoration',
7259 textlength: 'textLength',
7260 textrendering: 'textRendering',
7261 'text-rendering': 'textRendering',
7262 to: 'to',
7263 transform: 'transform',
7264 typeof: 'typeof',
7265 u1: 'u1',
7266 u2: 'u2',
7267 underlineposition: 'underlinePosition',
7268 'underline-position': 'underlinePosition',
7269 underlinethickness: 'underlineThickness',
7270 'underline-thickness': 'underlineThickness',
7271 unicode: 'unicode',
7272 unicodebidi: 'unicodeBidi',
7273 'unicode-bidi': 'unicodeBidi',
7274 unicoderange: 'unicodeRange',
7275 'unicode-range': 'unicodeRange',
7276 unitsperem: 'unitsPerEm',
7277 'units-per-em': 'unitsPerEm',
7278 unselectable: 'unselectable',
7279 valphabetic: 'vAlphabetic',
7280 'v-alphabetic': 'vAlphabetic',
7281 values: 'values',
7282 vectoreffect: 'vectorEffect',
7283 'vector-effect': 'vectorEffect',
7284 version: 'version',
7285 vertadvy: 'vertAdvY',
7286 'vert-adv-y': 'vertAdvY',
7287 vertoriginx: 'vertOriginX',
7288 'vert-origin-x': 'vertOriginX',
7289 vertoriginy: 'vertOriginY',
7290 'vert-origin-y': 'vertOriginY',
7291 vhanging: 'vHanging',
7292 'v-hanging': 'vHanging',
7293 videographic: 'vIdeographic',
7294 'v-ideographic': 'vIdeographic',
7295 viewbox: 'viewBox',
7296 viewtarget: 'viewTarget',
7297 visibility: 'visibility',
7298 vmathematical: 'vMathematical',
7299 'v-mathematical': 'vMathematical',
7300 vocab: 'vocab',
7301 widths: 'widths',
7302 wordspacing: 'wordSpacing',
7303 'word-spacing': 'wordSpacing',
7304 writingmode: 'writingMode',
7305 'writing-mode': 'writingMode',
7306 x1: 'x1',
7307 x2: 'x2',
7308 x: 'x',
7309 xchannelselector: 'xChannelSelector',
7310 xheight: 'xHeight',
7311 'x-height': 'xHeight',
7312 xlinkactuate: 'xlinkActuate',
7313 'xlink:actuate': 'xlinkActuate',
7314 xlinkarcrole: 'xlinkArcrole',
7315 'xlink:arcrole': 'xlinkArcrole',
7316 xlinkhref: 'xlinkHref',
7317 'xlink:href': 'xlinkHref',
7318 xlinkrole: 'xlinkRole',
7319 'xlink:role': 'xlinkRole',
7320 xlinkshow: 'xlinkShow',
7321 'xlink:show': 'xlinkShow',
7322 xlinktitle: 'xlinkTitle',
7323 'xlink:title': 'xlinkTitle',
7324 xlinktype: 'xlinkType',
7325 'xlink:type': 'xlinkType',
7326 xmlbase: 'xmlBase',
7327 'xml:base': 'xmlBase',
7328 xmllang: 'xmlLang',
7329 'xml:lang': 'xmlLang',
7330 xmlns: 'xmlns',
7331 'xml:space': 'xmlSpace',
7332 xmlnsxlink: 'xmlnsXlink',
7333 'xmlns:xlink': 'xmlnsXlink',
7334 xmlspace: 'xmlSpace',
7335 y1: 'y1',
7336 y2: 'y2',
7337 y: 'y',
7338 ychannelselector: 'yChannelSelector',
7339 z: 'z',
7340 zoomandpan: 'zoomAndPan'
7341};
7342
7343var ariaProperties = {
7344 'aria-current': 0,
7345 // state
7346 'aria-details': 0,
7347 'aria-disabled': 0,
7348 // state
7349 'aria-hidden': 0,
7350 // state
7351 'aria-invalid': 0,
7352 // state
7353 'aria-keyshortcuts': 0,
7354 'aria-label': 0,
7355 'aria-roledescription': 0,
7356 // Widget Attributes
7357 'aria-autocomplete': 0,
7358 'aria-checked': 0,
7359 'aria-expanded': 0,
7360 'aria-haspopup': 0,
7361 'aria-level': 0,
7362 'aria-modal': 0,
7363 'aria-multiline': 0,
7364 'aria-multiselectable': 0,
7365 'aria-orientation': 0,
7366 'aria-placeholder': 0,
7367 'aria-pressed': 0,
7368 'aria-readonly': 0,
7369 'aria-required': 0,
7370 'aria-selected': 0,
7371 'aria-sort': 0,
7372 'aria-valuemax': 0,
7373 'aria-valuemin': 0,
7374 'aria-valuenow': 0,
7375 'aria-valuetext': 0,
7376 // Live Region Attributes
7377 'aria-atomic': 0,
7378 'aria-busy': 0,
7379 'aria-live': 0,
7380 'aria-relevant': 0,
7381 // Drag-and-Drop Attributes
7382 'aria-dropeffect': 0,
7383 'aria-grabbed': 0,
7384 // Relationship Attributes
7385 'aria-activedescendant': 0,
7386 'aria-colcount': 0,
7387 'aria-colindex': 0,
7388 'aria-colspan': 0,
7389 'aria-controls': 0,
7390 'aria-describedby': 0,
7391 'aria-errormessage': 0,
7392 'aria-flowto': 0,
7393 'aria-labelledby': 0,
7394 'aria-owns': 0,
7395 'aria-posinset': 0,
7396 'aria-rowcount': 0,
7397 'aria-rowindex': 0,
7398 'aria-rowspan': 0,
7399 'aria-setsize': 0
7400};
7401
7402var warnedProperties = {};
7403var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7404var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7405var hasOwnProperty$1 = Object.prototype.hasOwnProperty;
7406
7407function validateProperty(tagName, name) {
7408 if (hasOwnProperty$1.call(warnedProperties, name) && warnedProperties[name]) {
7409 return true;
7410 }
7411
7412 if (rARIACamel.test(name)) {
7413 var ariaName = 'aria-' + name.slice(4).toLowerCase();
7414 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
7415 // DOM properties, then it is an invalid aria-* attribute.
7416
7417 if (correctName == null) {
7418 warning$1(false, 'Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
7419 warnedProperties[name] = true;
7420 return true;
7421 } // aria-* attributes should be lowercase; suggest the lowercase version.
7422
7423
7424 if (name !== correctName) {
7425 warning$1(false, 'Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
7426 warnedProperties[name] = true;
7427 return true;
7428 }
7429 }
7430
7431 if (rARIA.test(name)) {
7432 var lowerCasedName = name.toLowerCase();
7433 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
7434 // DOM properties, then it is an invalid aria-* attribute.
7435
7436 if (standardName == null) {
7437 warnedProperties[name] = true;
7438 return false;
7439 } // aria-* attributes should be lowercase; suggest the lowercase version.
7440
7441
7442 if (name !== standardName) {
7443 warning$1(false, 'Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
7444 warnedProperties[name] = true;
7445 return true;
7446 }
7447 }
7448
7449 return true;
7450}
7451
7452function warnInvalidARIAProps(type, props) {
7453 var invalidProps = [];
7454
7455 for (var key in props) {
7456 var isValid = validateProperty(type, key);
7457
7458 if (!isValid) {
7459 invalidProps.push(key);
7460 }
7461 }
7462
7463 var unknownPropString = invalidProps.map(function (prop) {
7464 return '`' + prop + '`';
7465 }).join(', ');
7466
7467 if (invalidProps.length === 1) {
7468 warning$1(false, 'Invalid aria prop %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7469 } else if (invalidProps.length > 1) {
7470 warning$1(false, 'Invalid aria props %s on <%s> tag. ' + 'For details, see https://fb.me/invalid-aria-prop', unknownPropString, type);
7471 }
7472}
7473
7474function validateProperties(type, props) {
7475 if (isCustomComponent(type, props)) {
7476 return;
7477 }
7478
7479 warnInvalidARIAProps(type, props);
7480}
7481
7482var didWarnValueNull = false;
7483function validateProperties$1(type, props) {
7484 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
7485 return;
7486 }
7487
7488 if (props != null && props.value === null && !didWarnValueNull) {
7489 didWarnValueNull = true;
7490
7491 if (type === 'select' && props.multiple) {
7492 warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty array when `multiple` is set to `true` ' + 'to clear the component or `undefined` for uncontrolled components.', type);
7493 } else {
7494 warning$1(false, '`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
7495 }
7496 }
7497}
7498
7499var validateProperty$1 = function () {};
7500
7501{
7502 var warnedProperties$1 = {};
7503 var _hasOwnProperty = Object.prototype.hasOwnProperty;
7504 var EVENT_NAME_REGEX = /^on./;
7505 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
7506 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
7507 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
7508
7509 validateProperty$1 = function (tagName, name, value, canUseEventSystem) {
7510 if (_hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
7511 return true;
7512 }
7513
7514 var lowerCasedName = name.toLowerCase();
7515
7516 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
7517 warning$1(false, 'React uses onFocus and onBlur instead of onFocusIn and onFocusOut. ' + 'All React events are normalized to bubble, so onFocusIn and onFocusOut ' + 'are not needed/supported by React.');
7518 warnedProperties$1[name] = true;
7519 return true;
7520 } // We can't rely on the event system being injected on the server.
7521
7522
7523 if (canUseEventSystem) {
7524 if (registrationNameModules.hasOwnProperty(name)) {
7525 return true;
7526 }
7527
7528 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
7529
7530 if (registrationName != null) {
7531 warning$1(false, 'Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
7532 warnedProperties$1[name] = true;
7533 return true;
7534 }
7535
7536 if (EVENT_NAME_REGEX.test(name)) {
7537 warning$1(false, 'Unknown event handler property `%s`. It will be ignored.', name);
7538 warnedProperties$1[name] = true;
7539 return true;
7540 }
7541 } else if (EVENT_NAME_REGEX.test(name)) {
7542 // If no event plugins have been injected, we are in a server environment.
7543 // So we can't tell if the event name is correct for sure, but we can filter
7544 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
7545 if (INVALID_EVENT_NAME_REGEX.test(name)) {
7546 warning$1(false, 'Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
7547 }
7548
7549 warnedProperties$1[name] = true;
7550 return true;
7551 } // Let the ARIA attribute hook validate ARIA attributes
7552
7553
7554 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
7555 return true;
7556 }
7557
7558 if (lowerCasedName === 'innerhtml') {
7559 warning$1(false, 'Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
7560 warnedProperties$1[name] = true;
7561 return true;
7562 }
7563
7564 if (lowerCasedName === 'aria') {
7565 warning$1(false, 'The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
7566 warnedProperties$1[name] = true;
7567 return true;
7568 }
7569
7570 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
7571 warning$1(false, 'Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
7572 warnedProperties$1[name] = true;
7573 return true;
7574 }
7575
7576 if (typeof value === 'number' && isNaN(value)) {
7577 warning$1(false, 'Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
7578 warnedProperties$1[name] = true;
7579 return true;
7580 }
7581
7582 var propertyInfo = getPropertyInfo(name);
7583 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
7584
7585 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
7586 var standardName = possibleStandardNames[lowerCasedName];
7587
7588 if (standardName !== name) {
7589 warning$1(false, 'Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
7590 warnedProperties$1[name] = true;
7591 return true;
7592 }
7593 } else if (!isReserved && name !== lowerCasedName) {
7594 // Unknown attributes should have lowercase casing since that's how they
7595 // will be cased anyway with server rendering.
7596 warning$1(false, 'React does not recognize the `%s` prop on a DOM element. If you ' + 'intentionally want it to appear in the DOM as a custom ' + 'attribute, spell it as lowercase `%s` instead. ' + 'If you accidentally passed it from a parent component, remove ' + 'it from the DOM element.', name, lowerCasedName);
7597 warnedProperties$1[name] = true;
7598 return true;
7599 }
7600
7601 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7602 if (value) {
7603 warning$1(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.', value, name, name, value, name);
7604 } else {
7605 warning$1(false, 'Received `%s` for a non-boolean attribute `%s`.\n\n' + 'If you want to write it to the DOM, pass a string instead: ' + '%s="%s" or %s={value.toString()}.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', value, name, name, value, name, name, name);
7606 }
7607
7608 warnedProperties$1[name] = true;
7609 return true;
7610 } // Now that we've validated casing, do not validate
7611 // data types for reserved props
7612
7613
7614 if (isReserved) {
7615 return true;
7616 } // Warn when a known attribute is a bad type
7617
7618
7619 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
7620 warnedProperties$1[name] = true;
7621 return false;
7622 } // Warn when passing the strings 'false' or 'true' into a boolean prop
7623
7624
7625 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
7626 warning$1(false, 'Received the string `%s` for the boolean attribute `%s`. ' + '%s ' + 'Did you mean %s={%s}?', value, name, value === 'false' ? 'The browser will interpret it as a truthy value.' : 'Although this works, it will not work as expected if you pass the string "false".', name, value);
7627 warnedProperties$1[name] = true;
7628 return true;
7629 }
7630
7631 return true;
7632 };
7633}
7634
7635var warnUnknownProperties = function (type, props, canUseEventSystem) {
7636 var unknownProps = [];
7637
7638 for (var key in props) {
7639 var isValid = validateProperty$1(type, key, props[key], canUseEventSystem);
7640
7641 if (!isValid) {
7642 unknownProps.push(key);
7643 }
7644 }
7645
7646 var unknownPropString = unknownProps.map(function (prop) {
7647 return '`' + prop + '`';
7648 }).join(', ');
7649
7650 if (unknownProps.length === 1) {
7651 warning$1(false, 'Invalid value for prop %s on <%s> tag. Either remove it from the element, ' + 'or pass a string or number value to keep it in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type);
7652 } else if (unknownProps.length > 1) {
7653 warning$1(false, 'Invalid values for props %s on <%s> tag. Either remove them from the element, ' + 'or pass a string or number value to keep them in the DOM. ' + 'For details, see https://fb.me/react-attribute-behavior', unknownPropString, type);
7654 }
7655};
7656
7657function validateProperties$2(type, props, canUseEventSystem) {
7658 if (isCustomComponent(type, props)) {
7659 return;
7660 }
7661
7662 warnUnknownProperties(type, props, canUseEventSystem);
7663}
7664
7665// TODO: direct imports like some-package/src/* are bad. Fix me.
7666var didWarnInvalidHydration = false;
7667var didWarnShadyDOM = false;
7668var didWarnScriptTags = false;
7669var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
7670var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
7671var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
7672var AUTOFOCUS = 'autoFocus';
7673var CHILDREN = 'children';
7674var STYLE$1 = 'style';
7675var HTML = '__html';
7676var LISTENERS = 'listeners';
7677var HTML_NAMESPACE = Namespaces.html;
7678var warnedUnknownTags;
7679var suppressHydrationWarning;
7680var validatePropertiesInDevelopment;
7681var warnForTextDifference;
7682var warnForPropDifference;
7683var warnForExtraAttributes;
7684var warnForInvalidEventListener;
7685var canDiffStyleForHydrationWarning;
7686var normalizeMarkupForTextOrAttribute;
7687var normalizeHTML;
7688
7689{
7690 warnedUnknownTags = {
7691 // Chrome is the only major browser not shipping <time>. But as of July
7692 // 2017 it intends to ship it due to widespread usage. We intentionally
7693 // *don't* warn for <time> even if it's unrecognized by Chrome because
7694 // it soon will be, and many apps have been using it anyway.
7695 time: true,
7696 // There are working polyfills for <dialog>. Let people use it.
7697 dialog: true,
7698 // Electron ships a custom <webview> tag to display external web content in
7699 // an isolated frame and process.
7700 // This tag is not present in non Electron environments such as JSDom which
7701 // is often used for testing purposes.
7702 // @see https://electronjs.org/docs/api/webview-tag
7703 webview: true
7704 };
7705
7706 validatePropertiesInDevelopment = function (type, props) {
7707 validateProperties(type, props);
7708 validateProperties$1(type, props);
7709 validateProperties$2(type, props,
7710 /* canUseEventSystem */
7711 true);
7712 }; // IE 11 parses & normalizes the style attribute as opposed to other
7713 // browsers. It adds spaces and sorts the properties in some
7714 // non-alphabetical order. Handling that would require sorting CSS
7715 // properties in the client & server versions or applying
7716 // `expectedStyle` to a temporary DOM node to read its `style` attribute
7717 // normalized. Since it only affects IE, we're skipping style warnings
7718 // in that browser completely in favor of doing all that work.
7719 // See https://github.com/facebook/react/issues/11807
7720
7721
7722 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; // HTML parsing normalizes CR and CRLF to LF.
7723 // It also can turn \u0000 into \uFFFD inside attributes.
7724 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
7725 // If we have a mismatch, it might be caused by that.
7726 // We will still patch up in this case but not fire the warning.
7727
7728 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
7729 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
7730
7731 normalizeMarkupForTextOrAttribute = function (markup) {
7732 var markupString = typeof markup === 'string' ? markup : '' + markup;
7733 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
7734 };
7735
7736 warnForTextDifference = function (serverText, clientText) {
7737 if (didWarnInvalidHydration) {
7738 return;
7739 }
7740
7741 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
7742 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
7743
7744 if (normalizedServerText === normalizedClientText) {
7745 return;
7746 }
7747
7748 didWarnInvalidHydration = true;
7749 warningWithoutStack$1(false, 'Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
7750 };
7751
7752 warnForPropDifference = function (propName, serverValue, clientValue) {
7753 if (didWarnInvalidHydration) {
7754 return;
7755 }
7756
7757 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
7758 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
7759
7760 if (normalizedServerValue === normalizedClientValue) {
7761 return;
7762 }
7763
7764 didWarnInvalidHydration = true;
7765 warningWithoutStack$1(false, 'Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
7766 };
7767
7768 warnForExtraAttributes = function (attributeNames) {
7769 if (didWarnInvalidHydration) {
7770 return;
7771 }
7772
7773 didWarnInvalidHydration = true;
7774 var names = [];
7775 attributeNames.forEach(function (name) {
7776 names.push(name);
7777 });
7778 warningWithoutStack$1(false, 'Extra attributes from the server: %s', names);
7779 };
7780
7781 warnForInvalidEventListener = function (registrationName, listener) {
7782 if (listener === false) {
7783 warning$1(false, 'Expected `%s` listener to be a function, instead got `false`.\n\n' + 'If you used to conditionally omit it with %s={condition && value}, ' + 'pass %s={condition ? value : undefined} instead.', registrationName, registrationName, registrationName);
7784 } else {
7785 warning$1(false, 'Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
7786 }
7787 }; // Parse the HTML and read it back to normalize the HTML string so that it
7788 // can be used for comparison.
7789
7790
7791 normalizeHTML = function (parent, html) {
7792 // We could have created a separate document here to avoid
7793 // re-initializing custom elements if they exist. But this breaks
7794 // how <noscript> is being handled. So we use the same document.
7795 // See the discussion in https://github.com/facebook/react/pull/11157.
7796 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
7797 testElement.innerHTML = html;
7798 return testElement.innerHTML;
7799 };
7800}
7801
7802function ensureListeningTo(rootContainerElement, registrationName) {
7803 var isDocumentOrFragment = rootContainerElement.nodeType === DOCUMENT_NODE || rootContainerElement.nodeType === DOCUMENT_FRAGMENT_NODE;
7804 var doc = isDocumentOrFragment ? rootContainerElement : rootContainerElement.ownerDocument;
7805 listenTo(registrationName, doc);
7806}
7807
7808function getOwnerDocumentFromRootContainer(rootContainerElement) {
7809 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
7810}
7811
7812function noop() {}
7813
7814function trapClickOnNonInteractiveElement(node) {
7815 // Mobile Safari does not fire properly bubble click events on
7816 // non-interactive elements, which means delegated click listeners do not
7817 // fire. The workaround for this bug involves attaching an empty click
7818 // listener on the target node.
7819 // http://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
7820 // Just set it using the onclick property so that we don't have to manage any
7821 // bookkeeping for it. Not sure if we need to clear it when the listener is
7822 // removed.
7823 // TODO: Only do this for the relevant Safaris maybe?
7824 node.onclick = noop;
7825}
7826
7827function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
7828 for (var propKey in nextProps) {
7829 if (!nextProps.hasOwnProperty(propKey)) {
7830 continue;
7831 }
7832
7833 var nextProp = nextProps[propKey];
7834
7835 if (propKey === STYLE$1) {
7836 {
7837 if (nextProp) {
7838 // Freeze the next style object so that we can assume it won't be
7839 // mutated. We have already warned for this in the past.
7840 Object.freeze(nextProp);
7841 }
7842 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
7843
7844
7845 setValueForStyles(domElement, nextProp);
7846 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7847 var nextHtml = nextProp ? nextProp[HTML] : undefined;
7848
7849 if (nextHtml != null) {
7850 setInnerHTML(domElement, nextHtml);
7851 }
7852 } else if (propKey === CHILDREN) {
7853 if (typeof nextProp === 'string') {
7854 // Avoid setting initial textContent when the text is empty. In IE11 setting
7855 // textContent on a <textarea> will cause the placeholder to not
7856 // show within the <textarea> until it has been focused and blurred again.
7857 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
7858 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
7859
7860 if (canSetTextContent) {
7861 setTextContent(domElement, nextProp);
7862 }
7863 } else if (typeof nextProp === 'number') {
7864 setTextContent(domElement, '' + nextProp);
7865 }
7866 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {// Noop
7867 } else if (propKey === AUTOFOCUS) {// We polyfill it separately on the client during commit.
7868 // We could have excluded it in the property list instead of
7869 // adding a special case here, but then it wouldn't be emitted
7870 // on server rendering (but we *do* want to emit it in SSR).
7871 } else if (registrationNameModules.hasOwnProperty(propKey)) {
7872 if (nextProp != null) {
7873 if (true && typeof nextProp !== 'function') {
7874 warnForInvalidEventListener(propKey, nextProp);
7875 }
7876
7877 ensureListeningTo(rootContainerElement, propKey);
7878 }
7879 } else if (nextProp != null) {
7880 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
7881 }
7882 }
7883}
7884
7885function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
7886 // TODO: Handle wasCustomComponentTag
7887 for (var i = 0; i < updatePayload.length; i += 2) {
7888 var propKey = updatePayload[i];
7889 var propValue = updatePayload[i + 1];
7890
7891 if (propKey === STYLE$1) {
7892 setValueForStyles(domElement, propValue);
7893 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
7894 setInnerHTML(domElement, propValue);
7895 } else if (propKey === CHILDREN) {
7896 setTextContent(domElement, propValue);
7897 } else {
7898 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
7899 }
7900 }
7901}
7902
7903function createElement(type, props, rootContainerElement, parentNamespace) {
7904 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
7905 // tags get no namespace.
7906
7907 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
7908 var domElement;
7909 var namespaceURI = parentNamespace;
7910
7911 if (namespaceURI === HTML_NAMESPACE) {
7912 namespaceURI = getIntrinsicNamespace(type);
7913 }
7914
7915 if (namespaceURI === HTML_NAMESPACE) {
7916 {
7917 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
7918 // allow <SVG> or <mATH>.
7919
7920 !(isCustomComponentTag || type === type.toLowerCase()) ? warning$1(false, '<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type) : void 0;
7921 }
7922
7923 if (type === 'script') {
7924 // Create the script via .innerHTML so its "parser-inserted" flag is
7925 // set to true and it does not execute
7926 var div = ownerDocument.createElement('div');
7927
7928 {
7929 if (enableTrustedTypesIntegration && !didWarnScriptTags) {
7930 warning$1(false, 'Encountered a script tag while rendering React component. ' + 'Scripts inside React components are never executed when rendering ' + 'on the client. Consider using template tag instead ' + '(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).');
7931 didWarnScriptTags = true;
7932 }
7933 }
7934
7935 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
7936 // This is guaranteed to yield a script element.
7937
7938 var firstChild = div.firstChild;
7939 domElement = div.removeChild(firstChild);
7940 } else if (typeof props.is === 'string') {
7941 // $FlowIssue `createElement` should be updated for Web Components
7942 domElement = ownerDocument.createElement(type, {
7943 is: props.is
7944 });
7945 } else {
7946 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
7947 // See discussion in https://github.com/facebook/react/pull/6896
7948 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
7949 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
7950 // attributes on `select`s needs to be added before `option`s are inserted.
7951 // This prevents:
7952 // - a bug where the `select` does not scroll to the correct option because singular
7953 // `select` elements automatically pick the first item #13222
7954 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
7955 // See https://github.com/facebook/react/issues/13222
7956 // and https://github.com/facebook/react/issues/14239
7957
7958 if (type === 'select') {
7959 var node = domElement;
7960
7961 if (props.multiple) {
7962 node.multiple = true;
7963 } else if (props.size) {
7964 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
7965 // it is possible that no option is selected.
7966 //
7967 // This is only necessary when a select in "single selection mode".
7968 node.size = props.size;
7969 }
7970 }
7971 }
7972 } else {
7973 domElement = ownerDocument.createElementNS(namespaceURI, type);
7974 }
7975
7976 {
7977 if (namespaceURI === HTML_NAMESPACE) {
7978 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !Object.prototype.hasOwnProperty.call(warnedUnknownTags, type)) {
7979 warnedUnknownTags[type] = true;
7980 warning$1(false, 'The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
7981 }
7982 }
7983 }
7984
7985 return domElement;
7986}
7987function createTextNode(text, rootContainerElement) {
7988 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
7989}
7990function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
7991 var isCustomComponentTag = isCustomComponent(tag, rawProps);
7992
7993 {
7994 validatePropertiesInDevelopment(tag, rawProps);
7995
7996 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
7997 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
7998 didWarnShadyDOM = true;
7999 }
8000 } // TODO: Make sure that we check isMounted before firing any of these events.
8001
8002
8003 var props;
8004
8005 switch (tag) {
8006 case 'iframe':
8007 case 'object':
8008 case 'embed':
8009 trapBubbledEvent(TOP_LOAD, domElement);
8010 props = rawProps;
8011 break;
8012
8013 case 'video':
8014 case 'audio':
8015 // Create listener for each media event
8016 for (var i = 0; i < mediaEventTypes.length; i++) {
8017 trapBubbledEvent(mediaEventTypes[i], domElement);
8018 }
8019
8020 props = rawProps;
8021 break;
8022
8023 case 'source':
8024 trapBubbledEvent(TOP_ERROR, domElement);
8025 props = rawProps;
8026 break;
8027
8028 case 'img':
8029 case 'image':
8030 case 'link':
8031 trapBubbledEvent(TOP_ERROR, domElement);
8032 trapBubbledEvent(TOP_LOAD, domElement);
8033 props = rawProps;
8034 break;
8035
8036 case 'form':
8037 trapBubbledEvent(TOP_RESET, domElement);
8038 trapBubbledEvent(TOP_SUBMIT, domElement);
8039 props = rawProps;
8040 break;
8041
8042 case 'details':
8043 trapBubbledEvent(TOP_TOGGLE, domElement);
8044 props = rawProps;
8045 break;
8046
8047 case 'input':
8048 initWrapperState(domElement, rawProps);
8049 props = getHostProps(domElement, rawProps);
8050 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
8051 // to onChange. Even if there is no listener.
8052
8053 ensureListeningTo(rootContainerElement, 'onChange');
8054 break;
8055
8056 case 'option':
8057 validateProps(domElement, rawProps);
8058 props = getHostProps$1(domElement, rawProps);
8059 break;
8060
8061 case 'select':
8062 initWrapperState$1(domElement, rawProps);
8063 props = getHostProps$2(domElement, rawProps);
8064 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
8065 // to onChange. Even if there is no listener.
8066
8067 ensureListeningTo(rootContainerElement, 'onChange');
8068 break;
8069
8070 case 'textarea':
8071 initWrapperState$2(domElement, rawProps);
8072 props = getHostProps$3(domElement, rawProps);
8073 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
8074 // to onChange. Even if there is no listener.
8075
8076 ensureListeningTo(rootContainerElement, 'onChange');
8077 break;
8078
8079 default:
8080 props = rawProps;
8081 }
8082
8083 assertValidProps(tag, props);
8084 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
8085
8086 switch (tag) {
8087 case 'input':
8088 // TODO: Make sure we check if this is still unmounted or do any clean
8089 // up necessary since we never stop tracking anymore.
8090 track(domElement);
8091 postMountWrapper(domElement, rawProps, false);
8092 break;
8093
8094 case 'textarea':
8095 // TODO: Make sure we check if this is still unmounted or do any clean
8096 // up necessary since we never stop tracking anymore.
8097 track(domElement);
8098 postMountWrapper$3(domElement, rawProps);
8099 break;
8100
8101 case 'option':
8102 postMountWrapper$1(domElement, rawProps);
8103 break;
8104
8105 case 'select':
8106 postMountWrapper$2(domElement, rawProps);
8107 break;
8108
8109 default:
8110 if (typeof props.onClick === 'function') {
8111 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8112 trapClickOnNonInteractiveElement(domElement);
8113 }
8114
8115 break;
8116 }
8117} // Calculate the diff between the two objects.
8118
8119function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
8120 {
8121 validatePropertiesInDevelopment(tag, nextRawProps);
8122 }
8123
8124 var updatePayload = null;
8125 var lastProps;
8126 var nextProps;
8127
8128 switch (tag) {
8129 case 'input':
8130 lastProps = getHostProps(domElement, lastRawProps);
8131 nextProps = getHostProps(domElement, nextRawProps);
8132 updatePayload = [];
8133 break;
8134
8135 case 'option':
8136 lastProps = getHostProps$1(domElement, lastRawProps);
8137 nextProps = getHostProps$1(domElement, nextRawProps);
8138 updatePayload = [];
8139 break;
8140
8141 case 'select':
8142 lastProps = getHostProps$2(domElement, lastRawProps);
8143 nextProps = getHostProps$2(domElement, nextRawProps);
8144 updatePayload = [];
8145 break;
8146
8147 case 'textarea':
8148 lastProps = getHostProps$3(domElement, lastRawProps);
8149 nextProps = getHostProps$3(domElement, nextRawProps);
8150 updatePayload = [];
8151 break;
8152
8153 default:
8154 lastProps = lastRawProps;
8155 nextProps = nextRawProps;
8156
8157 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
8158 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8159 trapClickOnNonInteractiveElement(domElement);
8160 }
8161
8162 break;
8163 }
8164
8165 assertValidProps(tag, nextProps);
8166 var propKey;
8167 var styleName;
8168 var styleUpdates = null;
8169
8170 for (propKey in lastProps) {
8171 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
8172 continue;
8173 }
8174
8175 if (propKey === STYLE$1) {
8176 var lastStyle = lastProps[propKey];
8177
8178 for (styleName in lastStyle) {
8179 if (lastStyle.hasOwnProperty(styleName)) {
8180 if (!styleUpdates) {
8181 styleUpdates = {};
8182 }
8183
8184 styleUpdates[styleName] = '';
8185 }
8186 }
8187 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) {// Noop. This is handled by the clear text mechanism.
8188 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {// Noop
8189 } else if (propKey === AUTOFOCUS) {// Noop. It doesn't work on updates anyway.
8190 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8191 // This is a special case. If any listener updates we need to ensure
8192 // that the "current" fiber pointer gets updated so we need a commit
8193 // to update this element.
8194 if (!updatePayload) {
8195 updatePayload = [];
8196 }
8197 } else {
8198 // For all other deleted properties we add it to the queue. We use
8199 // the whitelist in the commit phase instead.
8200 (updatePayload = updatePayload || []).push(propKey, null);
8201 }
8202 }
8203
8204 for (propKey in nextProps) {
8205 var nextProp = nextProps[propKey];
8206 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
8207
8208 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
8209 continue;
8210 }
8211
8212 if (propKey === STYLE$1) {
8213 {
8214 if (nextProp) {
8215 // Freeze the next style object so that we can assume it won't be
8216 // mutated. We have already warned for this in the past.
8217 Object.freeze(nextProp);
8218 }
8219 }
8220
8221 if (lastProp) {
8222 // Unset styles on `lastProp` but not on `nextProp`.
8223 for (styleName in lastProp) {
8224 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
8225 if (!styleUpdates) {
8226 styleUpdates = {};
8227 }
8228
8229 styleUpdates[styleName] = '';
8230 }
8231 } // Update styles that changed since `lastProp`.
8232
8233
8234 for (styleName in nextProp) {
8235 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
8236 if (!styleUpdates) {
8237 styleUpdates = {};
8238 }
8239
8240 styleUpdates[styleName] = nextProp[styleName];
8241 }
8242 }
8243 } else {
8244 // Relies on `updateStylesByID` not mutating `styleUpdates`.
8245 if (!styleUpdates) {
8246 if (!updatePayload) {
8247 updatePayload = [];
8248 }
8249
8250 updatePayload.push(propKey, styleUpdates);
8251 }
8252
8253 styleUpdates = nextProp;
8254 }
8255 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8256 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8257 var lastHtml = lastProp ? lastProp[HTML] : undefined;
8258
8259 if (nextHtml != null) {
8260 if (lastHtml !== nextHtml) {
8261 (updatePayload = updatePayload || []).push(propKey, toStringOrTrustedType(nextHtml));
8262 }
8263 } else {// TODO: It might be too late to clear this if we have children
8264 // inserted already.
8265 }
8266 } else if (propKey === CHILDREN) {
8267 if (lastProp !== nextProp && (typeof nextProp === 'string' || typeof nextProp === 'number')) {
8268 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
8269 }
8270 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1) {// Noop
8271 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8272 if (nextProp != null) {
8273 // We eagerly listen to this even though we haven't committed yet.
8274 if (true && typeof nextProp !== 'function') {
8275 warnForInvalidEventListener(propKey, nextProp);
8276 }
8277
8278 ensureListeningTo(rootContainerElement, propKey);
8279 }
8280
8281 if (!updatePayload && lastProp !== nextProp) {
8282 // This is a special case. If any listener updates we need to ensure
8283 // that the "current" props pointer gets updated so we need a commit
8284 // to update this element.
8285 updatePayload = [];
8286 }
8287 } else {
8288 // For any other property we always add it to the queue and then we
8289 // filter it out using the whitelist during the commit.
8290 (updatePayload = updatePayload || []).push(propKey, nextProp);
8291 }
8292 }
8293
8294 if (styleUpdates) {
8295 {
8296 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE$1]);
8297 }
8298
8299 (updatePayload = updatePayload || []).push(STYLE$1, styleUpdates);
8300 }
8301
8302 return updatePayload;
8303} // Apply the diff.
8304
8305function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
8306 // Update checked *before* name.
8307 // In the middle of an update, it is possible to have multiple checked.
8308 // When a checked radio tries to change name, browser makes another radio's checked false.
8309 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
8310 updateChecked(domElement, nextRawProps);
8311 }
8312
8313 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
8314 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
8315
8316 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
8317 // changed.
8318
8319 switch (tag) {
8320 case 'input':
8321 // Update the wrapper around inputs *after* updating props. This has to
8322 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
8323 // raise warnings and prevent the new value from being assigned.
8324 updateWrapper(domElement, nextRawProps);
8325 break;
8326
8327 case 'textarea':
8328 updateWrapper$1(domElement, nextRawProps);
8329 break;
8330
8331 case 'select':
8332 // <select> value update needs to occur after <option> children
8333 // reconciliation
8334 postUpdateWrapper(domElement, nextRawProps);
8335 break;
8336 }
8337}
8338
8339function getPossibleStandardName(propName) {
8340 {
8341 var lowerCasedName = propName.toLowerCase();
8342
8343 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
8344 return null;
8345 }
8346
8347 return possibleStandardNames[lowerCasedName] || null;
8348 }
8349
8350 return null;
8351}
8352
8353function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement) {
8354 var isCustomComponentTag;
8355 var extraAttributeNames;
8356
8357 {
8358 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING$1] === true;
8359 isCustomComponentTag = isCustomComponent(tag, rawProps);
8360 validatePropertiesInDevelopment(tag, rawProps);
8361
8362 if (isCustomComponentTag && !didWarnShadyDOM && domElement.shadyRoot) {
8363 warning$1(false, '%s is using shady DOM. Using shady DOM with React can ' + 'cause things to break subtly.', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
8364 didWarnShadyDOM = true;
8365 }
8366 } // TODO: Make sure that we check isMounted before firing any of these events.
8367
8368
8369 switch (tag) {
8370 case 'iframe':
8371 case 'object':
8372 case 'embed':
8373 trapBubbledEvent(TOP_LOAD, domElement);
8374 break;
8375
8376 case 'video':
8377 case 'audio':
8378 // Create listener for each media event
8379 for (var i = 0; i < mediaEventTypes.length; i++) {
8380 trapBubbledEvent(mediaEventTypes[i], domElement);
8381 }
8382
8383 break;
8384
8385 case 'source':
8386 trapBubbledEvent(TOP_ERROR, domElement);
8387 break;
8388
8389 case 'img':
8390 case 'image':
8391 case 'link':
8392 trapBubbledEvent(TOP_ERROR, domElement);
8393 trapBubbledEvent(TOP_LOAD, domElement);
8394 break;
8395
8396 case 'form':
8397 trapBubbledEvent(TOP_RESET, domElement);
8398 trapBubbledEvent(TOP_SUBMIT, domElement);
8399 break;
8400
8401 case 'details':
8402 trapBubbledEvent(TOP_TOGGLE, domElement);
8403 break;
8404
8405 case 'input':
8406 initWrapperState(domElement, rawProps);
8407 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
8408 // to onChange. Even if there is no listener.
8409
8410 ensureListeningTo(rootContainerElement, 'onChange');
8411 break;
8412
8413 case 'option':
8414 validateProps(domElement, rawProps);
8415 break;
8416
8417 case 'select':
8418 initWrapperState$1(domElement, rawProps);
8419 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
8420 // to onChange. Even if there is no listener.
8421
8422 ensureListeningTo(rootContainerElement, 'onChange');
8423 break;
8424
8425 case 'textarea':
8426 initWrapperState$2(domElement, rawProps);
8427 trapBubbledEvent(TOP_INVALID, domElement); // For controlled components we always need to ensure we're listening
8428 // to onChange. Even if there is no listener.
8429
8430 ensureListeningTo(rootContainerElement, 'onChange');
8431 break;
8432 }
8433
8434 assertValidProps(tag, rawProps);
8435
8436 {
8437 extraAttributeNames = new Set();
8438 var attributes = domElement.attributes;
8439
8440 for (var _i = 0; _i < attributes.length; _i++) {
8441 var name = attributes[_i].name.toLowerCase();
8442
8443 switch (name) {
8444 // Built-in SSR attribute is whitelisted
8445 case 'data-reactroot':
8446 break;
8447 // Controlled attributes are not validated
8448 // TODO: Only ignore them on controlled tags.
8449
8450 case 'value':
8451 break;
8452
8453 case 'checked':
8454 break;
8455
8456 case 'selected':
8457 break;
8458
8459 default:
8460 // Intentionally use the original name.
8461 // See discussion in https://github.com/facebook/react/pull/10676.
8462 extraAttributeNames.add(attributes[_i].name);
8463 }
8464 }
8465 }
8466
8467 var updatePayload = null;
8468
8469 for (var propKey in rawProps) {
8470 if (!rawProps.hasOwnProperty(propKey)) {
8471 continue;
8472 }
8473
8474 var nextProp = rawProps[propKey];
8475
8476 if (propKey === CHILDREN) {
8477 // For text content children we compare against textContent. This
8478 // might match additional HTML that is hidden when we read it using
8479 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
8480 // satisfies our requirement. Our requirement is not to produce perfect
8481 // HTML and attributes. Ideally we should preserve structure but it's
8482 // ok not to if the visible content is still enough to indicate what
8483 // even listeners these nodes might be wired up to.
8484 // TODO: Warn if there is more than a single textNode as a child.
8485 // TODO: Should we use domElement.firstChild.nodeValue to compare?
8486 if (typeof nextProp === 'string') {
8487 if (domElement.textContent !== nextProp) {
8488 if (true && !suppressHydrationWarning) {
8489 warnForTextDifference(domElement.textContent, nextProp);
8490 }
8491
8492 updatePayload = [CHILDREN, nextProp];
8493 }
8494 } else if (typeof nextProp === 'number') {
8495 if (domElement.textContent !== '' + nextProp) {
8496 if (true && !suppressHydrationWarning) {
8497 warnForTextDifference(domElement.textContent, nextProp);
8498 }
8499
8500 updatePayload = [CHILDREN, '' + nextProp];
8501 }
8502 }
8503 } else if (registrationNameModules.hasOwnProperty(propKey)) {
8504 if (nextProp != null) {
8505 if (true && typeof nextProp !== 'function') {
8506 warnForInvalidEventListener(propKey, nextProp);
8507 }
8508
8509 ensureListeningTo(rootContainerElement, propKey);
8510 }
8511 } else if (true && // Convince Flow we've calculated it (it's DEV-only in this method.)
8512 typeof isCustomComponentTag === 'boolean') {
8513 // Validate that the properties correspond to their expected values.
8514 var serverValue = void 0;
8515 var propertyInfo = getPropertyInfo(propKey);
8516
8517 if (suppressHydrationWarning) {// Don't bother comparing. We're ignoring all these warnings.
8518 } else if (enableFlareAPI && propKey === LISTENERS || propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING$1 || // Controlled attributes are not validated
8519 // TODO: Only ignore them on controlled tags.
8520 propKey === 'value' || propKey === 'checked' || propKey === 'selected') {// Noop
8521 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
8522 var serverHTML = domElement.innerHTML;
8523 var nextHtml = nextProp ? nextProp[HTML] : undefined;
8524 var expectedHTML = normalizeHTML(domElement, nextHtml != null ? nextHtml : '');
8525
8526 if (expectedHTML !== serverHTML) {
8527 warnForPropDifference(propKey, serverHTML, expectedHTML);
8528 }
8529 } else if (propKey === STYLE$1) {
8530 // $FlowFixMe - Should be inferred as not undefined.
8531 extraAttributeNames.delete(propKey);
8532
8533 if (canDiffStyleForHydrationWarning) {
8534 var expectedStyle = createDangerousStringForStyles(nextProp);
8535 serverValue = domElement.getAttribute('style');
8536
8537 if (expectedStyle !== serverValue) {
8538 warnForPropDifference(propKey, serverValue, expectedStyle);
8539 }
8540 }
8541 } else if (isCustomComponentTag) {
8542 // $FlowFixMe - Should be inferred as not undefined.
8543 extraAttributeNames.delete(propKey.toLowerCase());
8544 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8545
8546 if (nextProp !== serverValue) {
8547 warnForPropDifference(propKey, serverValue, nextProp);
8548 }
8549 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
8550 var isMismatchDueToBadCasing = false;
8551
8552 if (propertyInfo !== null) {
8553 // $FlowFixMe - Should be inferred as not undefined.
8554 extraAttributeNames.delete(propertyInfo.attributeName);
8555 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
8556 } else {
8557 var ownNamespace = parentNamespace;
8558
8559 if (ownNamespace === HTML_NAMESPACE) {
8560 ownNamespace = getIntrinsicNamespace(tag);
8561 }
8562
8563 if (ownNamespace === HTML_NAMESPACE) {
8564 // $FlowFixMe - Should be inferred as not undefined.
8565 extraAttributeNames.delete(propKey.toLowerCase());
8566 } else {
8567 var standardName = getPossibleStandardName(propKey);
8568
8569 if (standardName !== null && standardName !== propKey) {
8570 // If an SVG prop is supplied with bad casing, it will
8571 // be successfully parsed from HTML, but will produce a mismatch
8572 // (and would be incorrectly rendered on the client).
8573 // However, we already warn about bad casing elsewhere.
8574 // So we'll skip the misleading extra mismatch warning in this case.
8575 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
8576
8577 extraAttributeNames.delete(standardName);
8578 } // $FlowFixMe - Should be inferred as not undefined.
8579
8580
8581 extraAttributeNames.delete(propKey);
8582 }
8583
8584 serverValue = getValueForAttribute(domElement, propKey, nextProp);
8585 }
8586
8587 if (nextProp !== serverValue && !isMismatchDueToBadCasing) {
8588 warnForPropDifference(propKey, serverValue, nextProp);
8589 }
8590 }
8591 }
8592 }
8593
8594 {
8595 // $FlowFixMe - Should be inferred as not undefined.
8596 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
8597 // $FlowFixMe - Should be inferred as not undefined.
8598 warnForExtraAttributes(extraAttributeNames);
8599 }
8600 }
8601
8602 switch (tag) {
8603 case 'input':
8604 // TODO: Make sure we check if this is still unmounted or do any clean
8605 // up necessary since we never stop tracking anymore.
8606 track(domElement);
8607 postMountWrapper(domElement, rawProps, true);
8608 break;
8609
8610 case 'textarea':
8611 // TODO: Make sure we check if this is still unmounted or do any clean
8612 // up necessary since we never stop tracking anymore.
8613 track(domElement);
8614 postMountWrapper$3(domElement, rawProps);
8615 break;
8616
8617 case 'select':
8618 case 'option':
8619 // For input and textarea we current always set the value property at
8620 // post mount to force it to diverge from attributes. However, for
8621 // option and select we don't quite do the same thing and select
8622 // is not resilient to the DOM state changing so we don't do that here.
8623 // TODO: Consider not doing this for input and textarea.
8624 break;
8625
8626 default:
8627 if (typeof rawProps.onClick === 'function') {
8628 // TODO: This cast may not be sound for SVG, MathML or custom elements.
8629 trapClickOnNonInteractiveElement(domElement);
8630 }
8631
8632 break;
8633 }
8634
8635 return updatePayload;
8636}
8637function diffHydratedText(textNode, text) {
8638 var isDifferent = textNode.nodeValue !== text;
8639 return isDifferent;
8640}
8641function warnForUnmatchedText(textNode, text) {
8642 {
8643 warnForTextDifference(textNode.nodeValue, text);
8644 }
8645}
8646function warnForDeletedHydratableElement(parentNode, child) {
8647 {
8648 if (didWarnInvalidHydration) {
8649 return;
8650 }
8651
8652 didWarnInvalidHydration = true;
8653 warningWithoutStack$1(false, 'Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
8654 }
8655}
8656function warnForDeletedHydratableText(parentNode, child) {
8657 {
8658 if (didWarnInvalidHydration) {
8659 return;
8660 }
8661
8662 didWarnInvalidHydration = true;
8663 warningWithoutStack$1(false, 'Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
8664 }
8665}
8666function warnForInsertedHydratedElement(parentNode, tag, props) {
8667 {
8668 if (didWarnInvalidHydration) {
8669 return;
8670 }
8671
8672 didWarnInvalidHydration = true;
8673 warningWithoutStack$1(false, 'Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
8674 }
8675}
8676function warnForInsertedHydratedText(parentNode, text) {
8677 {
8678 if (text === '') {
8679 // We expect to insert empty text nodes since they're not represented in
8680 // the HTML.
8681 // TODO: Remove this special case if we can just avoid inserting empty
8682 // text nodes.
8683 return;
8684 }
8685
8686 if (didWarnInvalidHydration) {
8687 return;
8688 }
8689
8690 didWarnInvalidHydration = true;
8691 warningWithoutStack$1(false, 'Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
8692 }
8693}
8694function restoreControlledState$$1(domElement, tag, props) {
8695 switch (tag) {
8696 case 'input':
8697 restoreControlledState$1(domElement, props);
8698 return;
8699
8700 case 'textarea':
8701 restoreControlledState$3(domElement, props);
8702 return;
8703
8704 case 'select':
8705 restoreControlledState$2(domElement, props);
8706 return;
8707 }
8708}
8709function listenToEventResponderEventTypes(eventTypes, element) {
8710 if (enableFlareAPI) {
8711 // Get the listening Set for this element. We use this to track
8712 // what events we're listening to.
8713 var listeningSet = getListeningSetForElement(element); // Go through each target event type of the event responder
8714
8715 for (var i = 0, length = eventTypes.length; i < length; ++i) {
8716 var eventType = eventTypes[i];
8717 var isPassive = !endsWith(eventType, '_active');
8718 var eventKey = isPassive ? eventType + '_passive' : eventType;
8719 var targetEventType = isPassive ? eventType : eventType.substring(0, eventType.length - 7);
8720
8721 if (!listeningSet.has(eventKey)) {
8722 trapEventForResponderEventSystem(element, targetEventType, isPassive);
8723 listeningSet.add(eventKey);
8724 }
8725 }
8726 }
8727} // We can remove this once the event API is stable and out of a flag
8728
8729if (enableFlareAPI) {
8730 setListenToResponderEventTypes(listenToEventResponderEventTypes);
8731}
8732
8733function getActiveElement(doc) {
8734 doc = doc || (typeof document !== 'undefined' ? document : undefined);
8735
8736 if (typeof doc === 'undefined') {
8737 return null;
8738 }
8739
8740 try {
8741 return doc.activeElement || doc.body;
8742 } catch (e) {
8743 return doc.body;
8744 }
8745}
8746
8747/**
8748 * Given any node return the first leaf node without children.
8749 *
8750 * @param {DOMElement|DOMTextNode} node
8751 * @return {DOMElement|DOMTextNode}
8752 */
8753
8754function getLeafNode(node) {
8755 while (node && node.firstChild) {
8756 node = node.firstChild;
8757 }
8758
8759 return node;
8760}
8761/**
8762 * Get the next sibling within a container. This will walk up the
8763 * DOM if a node's siblings have been exhausted.
8764 *
8765 * @param {DOMElement|DOMTextNode} node
8766 * @return {?DOMElement|DOMTextNode}
8767 */
8768
8769
8770function getSiblingNode(node) {
8771 while (node) {
8772 if (node.nextSibling) {
8773 return node.nextSibling;
8774 }
8775
8776 node = node.parentNode;
8777 }
8778}
8779/**
8780 * Get object describing the nodes which contain characters at offset.
8781 *
8782 * @param {DOMElement|DOMTextNode} root
8783 * @param {number} offset
8784 * @return {?object}
8785 */
8786
8787
8788function getNodeForCharacterOffset(root, offset) {
8789 var node = getLeafNode(root);
8790 var nodeStart = 0;
8791 var nodeEnd = 0;
8792
8793 while (node) {
8794 if (node.nodeType === TEXT_NODE) {
8795 nodeEnd = nodeStart + node.textContent.length;
8796
8797 if (nodeStart <= offset && nodeEnd >= offset) {
8798 return {
8799 node: node,
8800 offset: offset - nodeStart
8801 };
8802 }
8803
8804 nodeStart = nodeEnd;
8805 }
8806
8807 node = getLeafNode(getSiblingNode(node));
8808 }
8809}
8810
8811/**
8812 * @param {DOMElement} outerNode
8813 * @return {?object}
8814 */
8815
8816function getOffsets(outerNode) {
8817 var ownerDocument = outerNode.ownerDocument;
8818 var win = ownerDocument && ownerDocument.defaultView || window;
8819 var selection = win.getSelection && win.getSelection();
8820
8821 if (!selection || selection.rangeCount === 0) {
8822 return null;
8823 }
8824
8825 var anchorNode = selection.anchorNode,
8826 anchorOffset = selection.anchorOffset,
8827 focusNode = selection.focusNode,
8828 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
8829 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
8830 // expose properties, triggering a "Permission denied error" if any of its
8831 // properties are accessed. The only seemingly possible way to avoid erroring
8832 // is to access a property that typically works for non-anonymous divs and
8833 // catch any error that may otherwise arise. See
8834 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
8835
8836 try {
8837 /* eslint-disable no-unused-expressions */
8838 anchorNode.nodeType;
8839 focusNode.nodeType;
8840 /* eslint-enable no-unused-expressions */
8841 } catch (e) {
8842 return null;
8843 }
8844
8845 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
8846}
8847/**
8848 * Returns {start, end} where `start` is the character/codepoint index of
8849 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
8850 * `end` is the index of (focusNode, focusOffset).
8851 *
8852 * Returns null if you pass in garbage input but we should probably just crash.
8853 *
8854 * Exported only for testing.
8855 */
8856
8857function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
8858 var length = 0;
8859 var start = -1;
8860 var end = -1;
8861 var indexWithinAnchor = 0;
8862 var indexWithinFocus = 0;
8863 var node = outerNode;
8864 var parentNode = null;
8865
8866 outer: while (true) {
8867 var next = null;
8868
8869 while (true) {
8870 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
8871 start = length + anchorOffset;
8872 }
8873
8874 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
8875 end = length + focusOffset;
8876 }
8877
8878 if (node.nodeType === TEXT_NODE) {
8879 length += node.nodeValue.length;
8880 }
8881
8882 if ((next = node.firstChild) === null) {
8883 break;
8884 } // Moving from `node` to its first child `next`.
8885
8886
8887 parentNode = node;
8888 node = next;
8889 }
8890
8891 while (true) {
8892 if (node === outerNode) {
8893 // If `outerNode` has children, this is always the second time visiting
8894 // it. If it has no children, this is still the first loop, and the only
8895 // valid selection is anchorNode and focusNode both equal to this node
8896 // and both offsets 0, in which case we will have handled above.
8897 break outer;
8898 }
8899
8900 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
8901 start = length;
8902 }
8903
8904 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
8905 end = length;
8906 }
8907
8908 if ((next = node.nextSibling) !== null) {
8909 break;
8910 }
8911
8912 node = parentNode;
8913 parentNode = node.parentNode;
8914 } // Moving from `node` to its next sibling `next`.
8915
8916
8917 node = next;
8918 }
8919
8920 if (start === -1 || end === -1) {
8921 // This should never happen. (Would happen if the anchor/focus nodes aren't
8922 // actually inside the passed-in node.)
8923 return null;
8924 }
8925
8926 return {
8927 start: start,
8928 end: end
8929 };
8930}
8931/**
8932 * In modern non-IE browsers, we can support both forward and backward
8933 * selections.
8934 *
8935 * Note: IE10+ supports the Selection object, but it does not support
8936 * the `extend` method, which means that even in modern IE, it's not possible
8937 * to programmatically create a backward selection. Thus, for all IE
8938 * versions, we use the old IE API to create our selections.
8939 *
8940 * @param {DOMElement|DOMTextNode} node
8941 * @param {object} offsets
8942 */
8943
8944function setOffsets(node, offsets) {
8945 var doc = node.ownerDocument || document;
8946 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
8947 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
8948 // fails when pasting 100+ items)
8949
8950 if (!win.getSelection) {
8951 return;
8952 }
8953
8954 var selection = win.getSelection();
8955 var length = node.textContent.length;
8956 var start = Math.min(offsets.start, length);
8957 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
8958 // Flip backward selections, so we can set with a single range.
8959
8960 if (!selection.extend && start > end) {
8961 var temp = end;
8962 end = start;
8963 start = temp;
8964 }
8965
8966 var startMarker = getNodeForCharacterOffset(node, start);
8967 var endMarker = getNodeForCharacterOffset(node, end);
8968
8969 if (startMarker && endMarker) {
8970 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
8971 return;
8972 }
8973
8974 var range = doc.createRange();
8975 range.setStart(startMarker.node, startMarker.offset);
8976 selection.removeAllRanges();
8977
8978 if (start > end) {
8979 selection.addRange(range);
8980 selection.extend(endMarker.node, endMarker.offset);
8981 } else {
8982 range.setEnd(endMarker.node, endMarker.offset);
8983 selection.addRange(range);
8984 }
8985 }
8986}
8987
8988function isTextNode(node) {
8989 return node && node.nodeType === TEXT_NODE;
8990}
8991
8992function containsNode(outerNode, innerNode) {
8993 if (!outerNode || !innerNode) {
8994 return false;
8995 } else if (outerNode === innerNode) {
8996 return true;
8997 } else if (isTextNode(outerNode)) {
8998 return false;
8999 } else if (isTextNode(innerNode)) {
9000 return containsNode(outerNode, innerNode.parentNode);
9001 } else if ('contains' in outerNode) {
9002 return outerNode.contains(innerNode);
9003 } else if (outerNode.compareDocumentPosition) {
9004 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
9005 } else {
9006 return false;
9007 }
9008}
9009
9010function isInDocument(node) {
9011 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
9012}
9013
9014function isSameOriginFrame(iframe) {
9015 try {
9016 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
9017 // to throw, e.g. if it has a cross-origin src attribute.
9018 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
9019 // iframe.contentDocument.defaultView;
9020 // A safety way is to access one of the cross origin properties: Window or Location
9021 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
9022 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
9023 return typeof iframe.contentWindow.location.href === 'string';
9024 } catch (err) {
9025 return false;
9026 }
9027}
9028
9029function getActiveElementDeep() {
9030 var win = window;
9031 var element = getActiveElement();
9032
9033 while (element instanceof win.HTMLIFrameElement) {
9034 if (isSameOriginFrame(element)) {
9035 win = element.contentWindow;
9036 } else {
9037 return element;
9038 }
9039
9040 element = getActiveElement(win.document);
9041 }
9042
9043 return element;
9044}
9045/**
9046 * @ReactInputSelection: React input selection module. Based on Selection.js,
9047 * but modified to be suitable for react and has a couple of bug fixes (doesn't
9048 * assume buttons have range selections allowed).
9049 * Input selection module for React.
9050 */
9051
9052/**
9053 * @hasSelectionCapabilities: we get the element types that support selection
9054 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
9055 * and `selectionEnd` rows.
9056 */
9057
9058
9059function hasSelectionCapabilities(elem) {
9060 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
9061 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
9062}
9063function getSelectionInformation() {
9064 var focusedElem = getActiveElementDeep();
9065 return {
9066 focusedElem: focusedElem,
9067 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
9068 };
9069}
9070/**
9071 * @restoreSelection: If any selection information was potentially lost,
9072 * restore it. This is useful when performing operations that could remove dom
9073 * nodes and place them back in, resulting in focus being lost.
9074 */
9075
9076function restoreSelection(priorSelectionInformation) {
9077 var curFocusedElem = getActiveElementDeep();
9078 var priorFocusedElem = priorSelectionInformation.focusedElem;
9079 var priorSelectionRange = priorSelectionInformation.selectionRange;
9080
9081 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
9082 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
9083 setSelection(priorFocusedElem, priorSelectionRange);
9084 } // Focusing a node can change the scroll position, which is undesirable
9085
9086
9087 var ancestors = [];
9088 var ancestor = priorFocusedElem;
9089
9090 while (ancestor = ancestor.parentNode) {
9091 if (ancestor.nodeType === ELEMENT_NODE) {
9092 ancestors.push({
9093 element: ancestor,
9094 left: ancestor.scrollLeft,
9095 top: ancestor.scrollTop
9096 });
9097 }
9098 }
9099
9100 if (typeof priorFocusedElem.focus === 'function') {
9101 priorFocusedElem.focus();
9102 }
9103
9104 for (var i = 0; i < ancestors.length; i++) {
9105 var info = ancestors[i];
9106 info.element.scrollLeft = info.left;
9107 info.element.scrollTop = info.top;
9108 }
9109 }
9110}
9111/**
9112 * @getSelection: Gets the selection bounds of a focused textarea, input or
9113 * contentEditable node.
9114 * -@input: Look up selection bounds of this input
9115 * -@return {start: selectionStart, end: selectionEnd}
9116 */
9117
9118function getSelection(input) {
9119 var selection;
9120
9121 if ('selectionStart' in input) {
9122 // Modern browser with input or textarea.
9123 selection = {
9124 start: input.selectionStart,
9125 end: input.selectionEnd
9126 };
9127 } else {
9128 // Content editable or old IE textarea.
9129 selection = getOffsets(input);
9130 }
9131
9132 return selection || {
9133 start: 0,
9134 end: 0
9135 };
9136}
9137/**
9138 * @setSelection: Sets the selection bounds of a textarea or input and focuses
9139 * the input.
9140 * -@input Set selection bounds of this input or textarea
9141 * -@offsets Object of same form that is returned from get*
9142 */
9143
9144function setSelection(input, offsets) {
9145 var start = offsets.start,
9146 end = offsets.end;
9147
9148 if (end === undefined) {
9149 end = start;
9150 }
9151
9152 if ('selectionStart' in input) {
9153 input.selectionStart = start;
9154 input.selectionEnd = Math.min(end, input.value.length);
9155 } else {
9156 setOffsets(input, offsets);
9157 }
9158}
9159
9160var validateDOMNesting = function () {};
9161
9162var updatedAncestorInfo = function () {};
9163
9164{
9165 // This validation code was written based on the HTML5 parsing spec:
9166 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9167 //
9168 // Note: this does not catch all invalid nesting, nor does it try to (as it's
9169 // not clear what practical benefit doing so provides); instead, we warn only
9170 // for cases where the parser will give a parse tree differing from what React
9171 // intended. For example, <b><div></div></b> is invalid but we don't warn
9172 // because it still parses correctly; we do warn for other cases like nested
9173 // <p> tags where the beginning of the second element implicitly closes the
9174 // first, causing a confusing mess.
9175 // https://html.spec.whatwg.org/multipage/syntax.html#special
9176 var specialTags = ['address', 'applet', 'area', 'article', 'aside', 'base', 'basefont', 'bgsound', 'blockquote', 'body', 'br', 'button', 'caption', 'center', 'col', 'colgroup', 'dd', 'details', 'dir', 'div', 'dl', 'dt', 'embed', 'fieldset', 'figcaption', 'figure', 'footer', 'form', 'frame', 'frameset', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'head', 'header', 'hgroup', 'hr', 'html', 'iframe', 'img', 'input', 'isindex', 'li', 'link', 'listing', 'main', 'marquee', 'menu', 'menuitem', 'meta', 'nav', 'noembed', 'noframes', 'noscript', 'object', 'ol', 'p', 'param', 'plaintext', 'pre', 'script', 'section', 'select', 'source', 'style', 'summary', 'table', 'tbody', 'td', 'template', 'textarea', 'tfoot', 'th', 'thead', 'title', 'tr', 'track', 'ul', 'wbr', 'xmp']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
9177
9178 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
9179 // TODO: Distinguish by namespace here -- for <title>, including it here
9180 // errs on the side of fewer warnings
9181 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
9182
9183 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
9184
9185 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
9186 var emptyAncestorInfo = {
9187 current: null,
9188 formTag: null,
9189 aTagInScope: null,
9190 buttonTagInScope: null,
9191 nobrTagInScope: null,
9192 pTagInButtonScope: null,
9193 listItemTagAutoclosing: null,
9194 dlItemTagAutoclosing: null
9195 };
9196
9197 updatedAncestorInfo = function (oldInfo, tag) {
9198 var ancestorInfo = _assign({}, oldInfo || emptyAncestorInfo);
9199
9200 var info = {
9201 tag: tag
9202 };
9203
9204 if (inScopeTags.indexOf(tag) !== -1) {
9205 ancestorInfo.aTagInScope = null;
9206 ancestorInfo.buttonTagInScope = null;
9207 ancestorInfo.nobrTagInScope = null;
9208 }
9209
9210 if (buttonScopeTags.indexOf(tag) !== -1) {
9211 ancestorInfo.pTagInButtonScope = null;
9212 } // See rules for 'li', 'dd', 'dt' start tags in
9213 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9214
9215
9216 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
9217 ancestorInfo.listItemTagAutoclosing = null;
9218 ancestorInfo.dlItemTagAutoclosing = null;
9219 }
9220
9221 ancestorInfo.current = info;
9222
9223 if (tag === 'form') {
9224 ancestorInfo.formTag = info;
9225 }
9226
9227 if (tag === 'a') {
9228 ancestorInfo.aTagInScope = info;
9229 }
9230
9231 if (tag === 'button') {
9232 ancestorInfo.buttonTagInScope = info;
9233 }
9234
9235 if (tag === 'nobr') {
9236 ancestorInfo.nobrTagInScope = info;
9237 }
9238
9239 if (tag === 'p') {
9240 ancestorInfo.pTagInButtonScope = info;
9241 }
9242
9243 if (tag === 'li') {
9244 ancestorInfo.listItemTagAutoclosing = info;
9245 }
9246
9247 if (tag === 'dd' || tag === 'dt') {
9248 ancestorInfo.dlItemTagAutoclosing = info;
9249 }
9250
9251 return ancestorInfo;
9252 };
9253 /**
9254 * Returns whether
9255 */
9256
9257
9258 var isTagValidWithParent = function (tag, parentTag) {
9259 // First, let's check if we're in an unusual parsing mode...
9260 switch (parentTag) {
9261 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
9262 case 'select':
9263 return tag === 'option' || tag === 'optgroup' || tag === '#text';
9264
9265 case 'optgroup':
9266 return tag === 'option' || tag === '#text';
9267 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
9268 // but
9269
9270 case 'option':
9271 return tag === '#text';
9272 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
9273 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
9274 // No special behavior since these rules fall back to "in body" mode for
9275 // all except special table nodes which cause bad parsing behavior anyway.
9276 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
9277
9278 case 'tr':
9279 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
9280 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
9281
9282 case 'tbody':
9283 case 'thead':
9284 case 'tfoot':
9285 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
9286 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
9287
9288 case 'colgroup':
9289 return tag === 'col' || tag === 'template';
9290 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
9291
9292 case 'table':
9293 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
9294 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
9295
9296 case 'head':
9297 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
9298 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
9299
9300 case 'html':
9301 return tag === 'head' || tag === 'body' || tag === 'frameset';
9302
9303 case 'frameset':
9304 return tag === 'frame';
9305
9306 case '#document':
9307 return tag === 'html';
9308 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
9309 // where the parsing rules cause implicit opens or closes to be added.
9310 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
9311
9312
9313 switch (tag) {
9314 case 'h1':
9315 case 'h2':
9316 case 'h3':
9317 case 'h4':
9318 case 'h5':
9319 case 'h6':
9320 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
9321
9322 case 'rp':
9323 case 'rt':
9324 return impliedEndTags.indexOf(parentTag) === -1;
9325
9326 case 'body':
9327 case 'caption':
9328 case 'col':
9329 case 'colgroup':
9330 case 'frameset':
9331 case 'frame':
9332 case 'head':
9333 case 'html':
9334 case 'tbody':
9335 case 'td':
9336 case 'tfoot':
9337 case 'th':
9338 case 'thead':
9339 case 'tr':
9340 // These tags are only valid with a few parents that have special child
9341 // parsing rules -- if we're down here, then none of those matched and
9342 // so we allow it only if we don't know what the parent is, as all other
9343 // cases are invalid.
9344 return parentTag == null;
9345 }
9346
9347 return true;
9348 };
9349 /**
9350 * Returns whether
9351 */
9352
9353
9354 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
9355 switch (tag) {
9356 case 'address':
9357 case 'article':
9358 case 'aside':
9359 case 'blockquote':
9360 case 'center':
9361 case 'details':
9362 case 'dialog':
9363 case 'dir':
9364 case 'div':
9365 case 'dl':
9366 case 'fieldset':
9367 case 'figcaption':
9368 case 'figure':
9369 case 'footer':
9370 case 'header':
9371 case 'hgroup':
9372 case 'main':
9373 case 'menu':
9374 case 'nav':
9375 case 'ol':
9376 case 'p':
9377 case 'section':
9378 case 'summary':
9379 case 'ul':
9380 case 'pre':
9381 case 'listing':
9382 case 'table':
9383 case 'hr':
9384 case 'xmp':
9385 case 'h1':
9386 case 'h2':
9387 case 'h3':
9388 case 'h4':
9389 case 'h5':
9390 case 'h6':
9391 return ancestorInfo.pTagInButtonScope;
9392
9393 case 'form':
9394 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
9395
9396 case 'li':
9397 return ancestorInfo.listItemTagAutoclosing;
9398
9399 case 'dd':
9400 case 'dt':
9401 return ancestorInfo.dlItemTagAutoclosing;
9402
9403 case 'button':
9404 return ancestorInfo.buttonTagInScope;
9405
9406 case 'a':
9407 // Spec says something about storing a list of markers, but it sounds
9408 // equivalent to this check.
9409 return ancestorInfo.aTagInScope;
9410
9411 case 'nobr':
9412 return ancestorInfo.nobrTagInScope;
9413 }
9414
9415 return null;
9416 };
9417
9418 var didWarn$1 = {};
9419
9420 validateDOMNesting = function (childTag, childText, ancestorInfo) {
9421 ancestorInfo = ancestorInfo || emptyAncestorInfo;
9422 var parentInfo = ancestorInfo.current;
9423 var parentTag = parentInfo && parentInfo.tag;
9424
9425 if (childText != null) {
9426 !(childTag == null) ? warningWithoutStack$1(false, 'validateDOMNesting: when childText is passed, childTag should be null') : void 0;
9427 childTag = '#text';
9428 }
9429
9430 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
9431 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
9432 var invalidParentOrAncestor = invalidParent || invalidAncestor;
9433
9434 if (!invalidParentOrAncestor) {
9435 return;
9436 }
9437
9438 var ancestorTag = invalidParentOrAncestor.tag;
9439 var addendum = getCurrentFiberStackInDev();
9440 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag + '|' + addendum;
9441
9442 if (didWarn$1[warnKey]) {
9443 return;
9444 }
9445
9446 didWarn$1[warnKey] = true;
9447 var tagDisplayName = childTag;
9448 var whitespaceInfo = '';
9449
9450 if (childTag === '#text') {
9451 if (/\S/.test(childText)) {
9452 tagDisplayName = 'Text nodes';
9453 } else {
9454 tagDisplayName = 'Whitespace text nodes';
9455 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
9456 }
9457 } else {
9458 tagDisplayName = '<' + childTag + '>';
9459 }
9460
9461 if (invalidParent) {
9462 var info = '';
9463
9464 if (ancestorTag === 'table' && childTag === 'tr') {
9465 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
9466 }
9467
9468 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info, addendum);
9469 } else {
9470 warningWithoutStack$1(false, 'validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.%s', tagDisplayName, ancestorTag, addendum);
9471 }
9472 };
9473}
9474
9475// can re-export everything from this module.
9476
9477function shim() {
9478 {
9479 {
9480 throw Error("The current renderer does not support persistence. This error is likely caused by a bug in React. Please file an issue.");
9481 }
9482 }
9483} // Persistence (when unsupported)
9484
9485
9486var supportsPersistence = false;
9487var cloneInstance = shim;
9488var cloneFundamentalInstance = shim;
9489var createContainerChildSet = shim;
9490var appendChildToContainerChildSet = shim;
9491var finalizeContainerChildren = shim;
9492var replaceContainerChildren = shim;
9493var cloneHiddenInstance = shim;
9494var cloneHiddenTextInstance = shim;
9495
9496var SUPPRESS_HYDRATION_WARNING;
9497
9498{
9499 SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
9500}
9501
9502var SUSPENSE_START_DATA = '$';
9503var SUSPENSE_END_DATA = '/$';
9504var SUSPENSE_PENDING_START_DATA = '$?';
9505var SUSPENSE_FALLBACK_START_DATA = '$!';
9506var STYLE = 'style';
9507var eventsEnabled = null;
9508var selectionInformation = null;
9509
9510function shouldAutoFocusHostComponent(type, props) {
9511 switch (type) {
9512 case 'button':
9513 case 'input':
9514 case 'select':
9515 case 'textarea':
9516 return !!props.autoFocus;
9517 }
9518
9519 return false;
9520}
9521
9522function getRootHostContext(rootContainerInstance) {
9523 var type;
9524 var namespace;
9525 var nodeType = rootContainerInstance.nodeType;
9526
9527 switch (nodeType) {
9528 case DOCUMENT_NODE:
9529 case DOCUMENT_FRAGMENT_NODE:
9530 {
9531 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
9532 var root = rootContainerInstance.documentElement;
9533 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
9534 break;
9535 }
9536
9537 default:
9538 {
9539 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
9540 var ownNamespace = container.namespaceURI || null;
9541 type = container.tagName;
9542 namespace = getChildNamespace(ownNamespace, type);
9543 break;
9544 }
9545 }
9546
9547 {
9548 var validatedTag = type.toLowerCase();
9549 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
9550 return {
9551 namespace: namespace,
9552 ancestorInfo: ancestorInfo
9553 };
9554 }
9555
9556 return namespace;
9557}
9558function getChildHostContext(parentHostContext, type, rootContainerInstance) {
9559 {
9560 var parentHostContextDev = parentHostContext;
9561 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
9562 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
9563 return {
9564 namespace: namespace,
9565 ancestorInfo: ancestorInfo
9566 };
9567 }
9568
9569 var parentNamespace = parentHostContext;
9570 return getChildNamespace(parentNamespace, type);
9571}
9572function getPublicInstance(instance) {
9573 return instance;
9574}
9575function prepareForCommit(containerInfo) {
9576 eventsEnabled = isEnabled();
9577 selectionInformation = getSelectionInformation();
9578 setEnabled(false);
9579}
9580function resetAfterCommit(containerInfo) {
9581 restoreSelection(selectionInformation);
9582 selectionInformation = null;
9583 setEnabled(eventsEnabled);
9584 eventsEnabled = null;
9585}
9586function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
9587 var parentNamespace;
9588
9589 {
9590 // TODO: take namespace into account when validating.
9591 var hostContextDev = hostContext;
9592 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
9593
9594 if (typeof props.children === 'string' || typeof props.children === 'number') {
9595 var string = '' + props.children;
9596 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
9597 validateDOMNesting(null, string, ownAncestorInfo);
9598 }
9599
9600 parentNamespace = hostContextDev.namespace;
9601 }
9602
9603 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
9604 precacheFiberNode(internalInstanceHandle, domElement);
9605 updateFiberProps(domElement, props);
9606 return domElement;
9607}
9608function appendInitialChild(parentInstance, child) {
9609 parentInstance.appendChild(child);
9610}
9611function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
9612 setInitialProperties(domElement, type, props, rootContainerInstance);
9613 return shouldAutoFocusHostComponent(type, props);
9614}
9615function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
9616 {
9617 var hostContextDev = hostContext;
9618
9619 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
9620 var string = '' + newProps.children;
9621 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
9622 validateDOMNesting(null, string, ownAncestorInfo);
9623 }
9624 }
9625
9626 return diffProperties(domElement, type, oldProps, newProps, rootContainerInstance);
9627}
9628function shouldSetTextContent(type, props) {
9629 return type === 'textarea' || type === 'option' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
9630}
9631function shouldDeprioritizeSubtree(type, props) {
9632 return !!props.hidden;
9633}
9634function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
9635 {
9636 var hostContextDev = hostContext;
9637 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
9638 }
9639
9640 var textNode = createTextNode(text, rootContainerInstance);
9641 precacheFiberNode(internalInstanceHandle, textNode);
9642 return textNode;
9643}
9644var isPrimaryRenderer = true;
9645var warnsIfNotActing = true; // This initialization code may run even on server environments
9646// if a component just imports ReactDOM (e.g. for findDOMNode).
9647// Some environments might not have setTimeout or clearTimeout.
9648
9649var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
9650var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
9651var noTimeout = -1; // -------------------
9652// Mutation
9653// -------------------
9654
9655var supportsMutation = true;
9656function commitMount(domElement, type, newProps, internalInstanceHandle) {
9657 // Despite the naming that might imply otherwise, this method only
9658 // fires if there is an `Update` effect scheduled during mounting.
9659 // This happens if `finalizeInitialChildren` returns `true` (which it
9660 // does to implement the `autoFocus` attribute on the client). But
9661 // there are also other cases when this might happen (such as patching
9662 // up text content during hydration mismatch). So we'll check this again.
9663 if (shouldAutoFocusHostComponent(type, newProps)) {
9664 domElement.focus();
9665 }
9666}
9667function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
9668 // Update the props handle so that we know which props are the ones with
9669 // with current event handlers.
9670 updateFiberProps(domElement, newProps); // Apply the diff to the DOM node.
9671
9672 updateProperties(domElement, updatePayload, type, oldProps, newProps);
9673}
9674function resetTextContent(domElement) {
9675 setTextContent(domElement, '');
9676}
9677function commitTextUpdate(textInstance, oldText, newText) {
9678 textInstance.nodeValue = newText;
9679}
9680function appendChild(parentInstance, child) {
9681 parentInstance.appendChild(child);
9682}
9683function appendChildToContainer(container, child) {
9684 var parentNode;
9685
9686 if (container.nodeType === COMMENT_NODE) {
9687 parentNode = container.parentNode;
9688 parentNode.insertBefore(child, container);
9689 } else {
9690 parentNode = container;
9691 parentNode.appendChild(child);
9692 } // This container might be used for a portal.
9693 // If something inside a portal is clicked, that click should bubble
9694 // through the React tree. However, on Mobile Safari the click would
9695 // never bubble through the *DOM* tree unless an ancestor with onclick
9696 // event exists. So we wouldn't see it and dispatch it.
9697 // This is why we ensure that non React root containers have inline onclick
9698 // defined.
9699 // https://github.com/facebook/react/issues/11918
9700
9701
9702 var reactRootContainer = container._reactRootContainer;
9703
9704 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
9705 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9706 trapClickOnNonInteractiveElement(parentNode);
9707 }
9708}
9709function insertBefore(parentInstance, child, beforeChild) {
9710 parentInstance.insertBefore(child, beforeChild);
9711}
9712function insertInContainerBefore(container, child, beforeChild) {
9713 if (container.nodeType === COMMENT_NODE) {
9714 container.parentNode.insertBefore(child, beforeChild);
9715 } else {
9716 container.insertBefore(child, beforeChild);
9717 }
9718} // This is a specific event for the React Flare
9719// event system, so event responders can act
9720// accordingly to a DOM node being unmounted that
9721// previously had active document focus.
9722
9723function dispatchDetachedVisibleNodeEvent(child) {
9724 if (enableFlareAPI && selectionInformation && child === selectionInformation.focusedElem) {
9725 var targetFiber = getClosestInstanceFromNode(child); // Simlulate a blur event to the React Flare responder system.
9726
9727 dispatchEventForResponderEventSystem('detachedvisiblenode', targetFiber, {
9728 target: child,
9729 timeStamp: Date.now()
9730 }, child, RESPONDER_EVENT_SYSTEM | IS_PASSIVE);
9731 }
9732}
9733
9734function removeChild(parentInstance, child) {
9735 dispatchDetachedVisibleNodeEvent(child);
9736 parentInstance.removeChild(child);
9737}
9738function removeChildFromContainer(container, child) {
9739 if (container.nodeType === COMMENT_NODE) {
9740 container.parentNode.removeChild(child);
9741 } else {
9742 dispatchDetachedVisibleNodeEvent(child);
9743 container.removeChild(child);
9744 }
9745}
9746function clearSuspenseBoundary(parentInstance, suspenseInstance) {
9747 var node = suspenseInstance; // Delete all nodes within this suspense boundary.
9748 // There might be nested nodes so we need to keep track of how
9749 // deep we are and only break out when we're back on top.
9750
9751 var depth = 0;
9752
9753 do {
9754 var nextNode = node.nextSibling;
9755 parentInstance.removeChild(node);
9756
9757 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
9758 var data = nextNode.data;
9759
9760 if (data === SUSPENSE_END_DATA) {
9761 if (depth === 0) {
9762 parentInstance.removeChild(nextNode); // Retry if any event replaying was blocked on this.
9763
9764 retryIfBlockedOn(suspenseInstance);
9765 return;
9766 } else {
9767 depth--;
9768 }
9769 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) {
9770 depth++;
9771 }
9772 }
9773
9774 node = nextNode;
9775 } while (node); // TODO: Warn, we didn't find the end comment boundary.
9776 // Retry if any event replaying was blocked on this.
9777
9778
9779 retryIfBlockedOn(suspenseInstance);
9780}
9781function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
9782 if (container.nodeType === COMMENT_NODE) {
9783 clearSuspenseBoundary(container.parentNode, suspenseInstance);
9784 } else if (container.nodeType === ELEMENT_NODE) {
9785 clearSuspenseBoundary(container, suspenseInstance);
9786 } else {} // Document nodes should never contain suspense boundaries.
9787 // Retry if any event replaying was blocked on this.
9788
9789
9790 retryIfBlockedOn(container);
9791}
9792function hideInstance(instance) {
9793 // TODO: Does this work for all element types? What about MathML? Should we
9794 // pass host context to this method?
9795 instance = instance;
9796 var style = instance.style;
9797
9798 if (typeof style.setProperty === 'function') {
9799 style.setProperty('display', 'none', 'important');
9800 } else {
9801 style.display = 'none';
9802 }
9803}
9804function hideTextInstance(textInstance) {
9805 textInstance.nodeValue = '';
9806}
9807function unhideInstance(instance, props) {
9808 instance = instance;
9809 var styleProp = props[STYLE];
9810 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
9811 instance.style.display = dangerousStyleValue('display', display);
9812}
9813function unhideTextInstance(textInstance, text) {
9814 textInstance.nodeValue = text;
9815} // -------------------
9816// Hydration
9817// -------------------
9818
9819var supportsHydration = true;
9820function canHydrateInstance(instance, type, props) {
9821 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
9822 return null;
9823 } // This has now been refined to an element node.
9824
9825
9826 return instance;
9827}
9828function canHydrateTextInstance(instance, text) {
9829 if (text === '' || instance.nodeType !== TEXT_NODE) {
9830 // Empty strings are not parsed by HTML so there won't be a correct match here.
9831 return null;
9832 } // This has now been refined to a text node.
9833
9834
9835 return instance;
9836}
9837function canHydrateSuspenseInstance(instance) {
9838 if (instance.nodeType !== COMMENT_NODE) {
9839 // Empty strings are not parsed by HTML so there won't be a correct match here.
9840 return null;
9841 } // This has now been refined to a suspense node.
9842
9843
9844 return instance;
9845}
9846function isSuspenseInstancePending(instance) {
9847 return instance.data === SUSPENSE_PENDING_START_DATA;
9848}
9849function isSuspenseInstanceFallback(instance) {
9850 return instance.data === SUSPENSE_FALLBACK_START_DATA;
9851}
9852function registerSuspenseInstanceRetry(instance, callback) {
9853 instance._reactRetry = callback;
9854}
9855
9856function getNextHydratable(node) {
9857 // Skip non-hydratable nodes.
9858 for (; node != null; node = node.nextSibling) {
9859 var nodeType = node.nodeType;
9860
9861 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
9862 break;
9863 }
9864
9865 if (enableSuspenseServerRenderer) {
9866 if (nodeType === COMMENT_NODE) {
9867 var nodeData = node.data;
9868
9869 if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) {
9870 break;
9871 }
9872 }
9873 }
9874 }
9875
9876 return node;
9877}
9878
9879function getNextHydratableSibling(instance) {
9880 return getNextHydratable(instance.nextSibling);
9881}
9882function getFirstHydratableChild(parentInstance) {
9883 return getNextHydratable(parentInstance.firstChild);
9884}
9885function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
9886 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
9887 // get attached.
9888
9889 updateFiberProps(instance, props);
9890 var parentNamespace;
9891
9892 {
9893 var hostContextDev = hostContext;
9894 parentNamespace = hostContextDev.namespace;
9895 }
9896
9897 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance);
9898}
9899function hydrateTextInstance(textInstance, text, internalInstanceHandle) {
9900 precacheFiberNode(internalInstanceHandle, textInstance);
9901 return diffHydratedText(textInstance, text);
9902}
9903function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) {
9904 precacheFiberNode(internalInstanceHandle, suspenseInstance);
9905}
9906function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
9907 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
9908 // There might be nested nodes so we need to keep track of how
9909 // deep we are and only break out when we're back on top.
9910
9911 var depth = 0;
9912
9913 while (node) {
9914 if (node.nodeType === COMMENT_NODE) {
9915 var data = node.data;
9916
9917 if (data === SUSPENSE_END_DATA) {
9918 if (depth === 0) {
9919 return getNextHydratableSibling(node);
9920 } else {
9921 depth--;
9922 }
9923 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
9924 depth++;
9925 }
9926 }
9927
9928 node = node.nextSibling;
9929 } // TODO: Warn, we didn't find the end comment boundary.
9930
9931
9932 return null;
9933} // Returns the SuspenseInstance if this node is a direct child of a
9934// SuspenseInstance. I.e. if its previous sibling is a Comment with
9935// SUSPENSE_x_START_DATA. Otherwise, null.
9936
9937function getParentSuspenseInstance(targetInstance) {
9938 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
9939 // There might be nested nodes so we need to keep track of how
9940 // deep we are and only break out when we're back on top.
9941
9942 var depth = 0;
9943
9944 while (node) {
9945 if (node.nodeType === COMMENT_NODE) {
9946 var data = node.data;
9947
9948 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
9949 if (depth === 0) {
9950 return node;
9951 } else {
9952 depth--;
9953 }
9954 } else if (data === SUSPENSE_END_DATA) {
9955 depth++;
9956 }
9957 }
9958
9959 node = node.previousSibling;
9960 }
9961
9962 return null;
9963}
9964function commitHydratedContainer(container) {
9965 // Retry if any event replaying was blocked on this.
9966 retryIfBlockedOn(container);
9967}
9968function commitHydratedSuspenseInstance(suspenseInstance) {
9969 // Retry if any event replaying was blocked on this.
9970 retryIfBlockedOn(suspenseInstance);
9971}
9972function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text) {
9973 {
9974 warnForUnmatchedText(textInstance, text);
9975 }
9976}
9977function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text) {
9978 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9979 warnForUnmatchedText(textInstance, text);
9980 }
9981}
9982function didNotHydrateContainerInstance(parentContainer, instance) {
9983 {
9984 if (instance.nodeType === ELEMENT_NODE) {
9985 warnForDeletedHydratableElement(parentContainer, instance);
9986 } else if (instance.nodeType === COMMENT_NODE) {// TODO: warnForDeletedHydratableSuspenseBoundary
9987 } else {
9988 warnForDeletedHydratableText(parentContainer, instance);
9989 }
9990 }
9991}
9992function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
9993 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
9994 if (instance.nodeType === ELEMENT_NODE) {
9995 warnForDeletedHydratableElement(parentInstance, instance);
9996 } else if (instance.nodeType === COMMENT_NODE) {// TODO: warnForDeletedHydratableSuspenseBoundary
9997 } else {
9998 warnForDeletedHydratableText(parentInstance, instance);
9999 }
10000 }
10001}
10002function didNotFindHydratableContainerInstance(parentContainer, type, props) {
10003 {
10004 warnForInsertedHydratedElement(parentContainer, type, props);
10005 }
10006}
10007function didNotFindHydratableContainerTextInstance(parentContainer, text) {
10008 {
10009 warnForInsertedHydratedText(parentContainer, text);
10010 }
10011}
10012
10013function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
10014 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10015 warnForInsertedHydratedElement(parentInstance, type, props);
10016 }
10017}
10018function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
10019 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10020 warnForInsertedHydratedText(parentInstance, text);
10021 }
10022}
10023function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
10024 if (true && parentProps[SUPPRESS_HYDRATION_WARNING] !== true) {// TODO: warnForInsertedHydratedSuspense(parentInstance);
10025 }
10026}
10027function mountResponderInstance(responder, responderInstance, responderProps, responderState, instance) {
10028 // Listen to events
10029 var doc = instance.ownerDocument;
10030 var _ref = responder,
10031 rootEventTypes = _ref.rootEventTypes,
10032 targetEventTypes = _ref.targetEventTypes;
10033
10034 if (targetEventTypes !== null) {
10035 listenToEventResponderEventTypes(targetEventTypes, doc);
10036 }
10037
10038 if (rootEventTypes !== null) {
10039 addRootEventTypesForResponderInstance(responderInstance, rootEventTypes);
10040 listenToEventResponderEventTypes(rootEventTypes, doc);
10041 }
10042
10043 mountEventResponder(responder, responderInstance, responderProps, responderState);
10044 return responderInstance;
10045}
10046function unmountResponderInstance(responderInstance) {
10047 if (enableFlareAPI) {
10048 // TODO stop listening to targetEventTypes
10049 unmountEventResponder(responderInstance);
10050 }
10051}
10052function getFundamentalComponentInstance(fundamentalInstance) {
10053 if (enableFundamentalAPI) {
10054 var currentFiber = fundamentalInstance.currentFiber,
10055 impl = fundamentalInstance.impl,
10056 props = fundamentalInstance.props,
10057 state = fundamentalInstance.state;
10058 var instance = impl.getInstance(null, props, state);
10059 precacheFiberNode(currentFiber, instance);
10060 return instance;
10061 } // Because of the flag above, this gets around the Flow error;
10062
10063
10064 return null;
10065}
10066function mountFundamentalComponent(fundamentalInstance) {
10067 if (enableFundamentalAPI) {
10068 var impl = fundamentalInstance.impl,
10069 instance = fundamentalInstance.instance,
10070 props = fundamentalInstance.props,
10071 state = fundamentalInstance.state;
10072 var onMount = impl.onMount;
10073
10074 if (onMount !== undefined) {
10075 onMount(null, instance, props, state);
10076 }
10077 }
10078}
10079function shouldUpdateFundamentalComponent(fundamentalInstance) {
10080 if (enableFundamentalAPI) {
10081 var impl = fundamentalInstance.impl,
10082 prevProps = fundamentalInstance.prevProps,
10083 props = fundamentalInstance.props,
10084 state = fundamentalInstance.state;
10085 var shouldUpdate = impl.shouldUpdate;
10086
10087 if (shouldUpdate !== undefined) {
10088 return shouldUpdate(null, prevProps, props, state);
10089 }
10090 }
10091
10092 return true;
10093}
10094function updateFundamentalComponent(fundamentalInstance) {
10095 if (enableFundamentalAPI) {
10096 var impl = fundamentalInstance.impl,
10097 instance = fundamentalInstance.instance,
10098 prevProps = fundamentalInstance.prevProps,
10099 props = fundamentalInstance.props,
10100 state = fundamentalInstance.state;
10101 var onUpdate = impl.onUpdate;
10102
10103 if (onUpdate !== undefined) {
10104 onUpdate(null, instance, prevProps, props, state);
10105 }
10106 }
10107}
10108function unmountFundamentalComponent(fundamentalInstance) {
10109 if (enableFundamentalAPI) {
10110 var impl = fundamentalInstance.impl,
10111 instance = fundamentalInstance.instance,
10112 props = fundamentalInstance.props,
10113 state = fundamentalInstance.state;
10114 var onUnmount = impl.onUnmount;
10115
10116 if (onUnmount !== undefined) {
10117 onUnmount(null, instance, props, state);
10118 }
10119 }
10120}
10121function getInstanceFromNode$2(node) {
10122 return getClosestInstanceFromNode(node) || null;
10123}
10124
10125var randomKey = Math.random().toString(36).slice(2);
10126var internalInstanceKey = '__reactInternalInstance$' + randomKey;
10127var internalEventHandlersKey = '__reactEventHandlers$' + randomKey;
10128var internalContainerInstanceKey = '__reactContainere$' + randomKey;
10129function precacheFiberNode(hostInst, node) {
10130 node[internalInstanceKey] = hostInst;
10131}
10132function markContainerAsRoot(hostRoot, node) {
10133 node[internalContainerInstanceKey] = hostRoot;
10134}
10135function unmarkContainerAsRoot(node) {
10136 node[internalContainerInstanceKey] = null;
10137}
10138function isContainerMarkedAsRoot(node) {
10139 return !!node[internalContainerInstanceKey];
10140} // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
10141// If the target node is part of a hydrated or not yet rendered subtree, then
10142// this may also return a SuspenseComponent or HostRoot to indicate that.
10143// Conceptually the HostRoot fiber is a child of the Container node. So if you
10144// pass the Container node as the targetNode, you will not actually get the
10145// HostRoot back. To get to the HostRoot, you need to pass a child of it.
10146// The same thing applies to Suspense boundaries.
10147
10148function getClosestInstanceFromNode(targetNode) {
10149 var targetInst = targetNode[internalInstanceKey];
10150
10151 if (targetInst) {
10152 // Don't return HostRoot or SuspenseComponent here.
10153 return targetInst;
10154 } // If the direct event target isn't a React owned DOM node, we need to look
10155 // to see if one of its parents is a React owned DOM node.
10156
10157
10158 var parentNode = targetNode.parentNode;
10159
10160 while (parentNode) {
10161 // We'll check if this is a container root that could include
10162 // React nodes in the future. We need to check this first because
10163 // if we're a child of a dehydrated container, we need to first
10164 // find that inner container before moving on to finding the parent
10165 // instance. Note that we don't check this field on the targetNode
10166 // itself because the fibers are conceptually between the container
10167 // node and the first child. It isn't surrounding the container node.
10168 // If it's not a container, we check if it's an instance.
10169 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
10170
10171 if (targetInst) {
10172 // Since this wasn't the direct target of the event, we might have
10173 // stepped past dehydrated DOM nodes to get here. However they could
10174 // also have been non-React nodes. We need to answer which one.
10175 // If we the instance doesn't have any children, then there can't be
10176 // a nested suspense boundary within it. So we can use this as a fast
10177 // bailout. Most of the time, when people add non-React children to
10178 // the tree, it is using a ref to a child-less DOM node.
10179 // Normally we'd only need to check one of the fibers because if it
10180 // has ever gone from having children to deleting them or vice versa
10181 // it would have deleted the dehydrated boundary nested inside already.
10182 // However, since the HostRoot starts out with an alternate it might
10183 // have one on the alternate so we need to check in case this was a
10184 // root.
10185 var alternate = targetInst.alternate;
10186
10187 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
10188 // Next we need to figure out if the node that skipped past is
10189 // nested within a dehydrated boundary and if so, which one.
10190 var suspenseInstance = getParentSuspenseInstance(targetNode);
10191
10192 while (suspenseInstance !== null) {
10193 // We found a suspense instance. That means that we haven't
10194 // hydrated it yet. Even though we leave the comments in the
10195 // DOM after hydrating, and there are boundaries in the DOM
10196 // that could already be hydrated, we wouldn't have found them
10197 // through this pass since if the target is hydrated it would
10198 // have had an internalInstanceKey on it.
10199 // Let's get the fiber associated with the SuspenseComponent
10200 // as the deepest instance.
10201 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
10202
10203 if (targetSuspenseInst) {
10204 return targetSuspenseInst;
10205 } // If we don't find a Fiber on the comment, it might be because
10206 // we haven't gotten to hydrate it yet. There might still be a
10207 // parent boundary that hasn't above this one so we need to find
10208 // the outer most that is known.
10209
10210
10211 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
10212 // host component also hasn't hydrated yet. We can return it
10213 // below since it will bail out on the isMounted check later.
10214 }
10215 }
10216
10217 return targetInst;
10218 }
10219
10220 targetNode = parentNode;
10221 parentNode = targetNode.parentNode;
10222 }
10223
10224 return null;
10225}
10226/**
10227 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
10228 * instance, or null if the node was not rendered by this React.
10229 */
10230
10231function getInstanceFromNode$1(node) {
10232 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
10233
10234 if (inst) {
10235 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
10236 return inst;
10237 } else {
10238 return null;
10239 }
10240 }
10241
10242 return null;
10243}
10244/**
10245 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
10246 * DOM node.
10247 */
10248
10249function getNodeFromInstance$1(inst) {
10250 if (inst.tag === HostComponent || inst.tag === HostText) {
10251 // In Fiber this, is just the state node right now. We assume it will be
10252 // a host component or host text.
10253 return inst.stateNode;
10254 } // Without this first invariant, passing a non-DOM-component triggers the next
10255 // invariant for a missing parent, which is super confusing.
10256
10257
10258 {
10259 {
10260 throw Error("getNodeFromInstance: Invalid argument.");
10261 }
10262 }
10263}
10264function getFiberCurrentPropsFromNode$1(node) {
10265 return node[internalEventHandlersKey] || null;
10266}
10267function updateFiberProps(node, props) {
10268 node[internalEventHandlersKey] = props;
10269}
10270
10271/**
10272 * These variables store information about text content of a target node,
10273 * allowing comparison of content before and after a given event.
10274 *
10275 * Identify the node where selection currently begins, then observe
10276 * both its text content and its current position in the DOM. Since the
10277 * browser may natively replace the target node during composition, we can
10278 * use its position to find its replacement.
10279 *
10280 *
10281 */
10282var root = null;
10283var startText = null;
10284var fallbackText = null;
10285function initialize(nativeEventTarget) {
10286 root = nativeEventTarget;
10287 startText = getText();
10288 return true;
10289}
10290function reset() {
10291 root = null;
10292 startText = null;
10293 fallbackText = null;
10294}
10295function getData() {
10296 if (fallbackText) {
10297 return fallbackText;
10298 }
10299
10300 var start;
10301 var startValue = startText;
10302 var startLength = startValue.length;
10303 var end;
10304 var endValue = getText();
10305 var endLength = endValue.length;
10306
10307 for (start = 0; start < startLength; start++) {
10308 if (startValue[start] !== endValue[start]) {
10309 break;
10310 }
10311 }
10312
10313 var minEnd = startLength - start;
10314
10315 for (end = 1; end <= minEnd; end++) {
10316 if (startValue[startLength - end] !== endValue[endLength - end]) {
10317 break;
10318 }
10319 }
10320
10321 var sliceTail = end > 1 ? 1 - end : undefined;
10322 fallbackText = endValue.slice(start, sliceTail);
10323 return fallbackText;
10324}
10325function getText() {
10326 if ('value' in root) {
10327 return root.value;
10328 }
10329
10330 return root.textContent;
10331}
10332
10333/**
10334 * @interface Event
10335 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
10336 */
10337
10338var SyntheticCompositionEvent = SyntheticEvent.extend({
10339 data: null
10340});
10341
10342/**
10343 * @interface Event
10344 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
10345 * /#events-inputevents
10346 */
10347
10348var SyntheticInputEvent = SyntheticEvent.extend({
10349 data: null
10350});
10351
10352var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
10353
10354var START_KEYCODE = 229;
10355var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
10356var documentMode = null;
10357
10358if (canUseDOM && 'documentMode' in document) {
10359 documentMode = document.documentMode;
10360} // Webkit offers a very useful `textInput` event that can be used to
10361// directly represent `beforeInput`. The IE `textinput` event is not as
10362// useful, so we don't use it.
10363
10364
10365var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
10366// by the native compositionend event may be incorrect. Japanese ideographic
10367// spaces, for instance (\u3000) are not recorded correctly.
10368
10369var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
10370var SPACEBAR_CODE = 32;
10371var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE); // Events and their corresponding property names.
10372
10373var eventTypes$1 = {
10374 beforeInput: {
10375 phasedRegistrationNames: {
10376 bubbled: 'onBeforeInput',
10377 captured: 'onBeforeInputCapture'
10378 },
10379 dependencies: [TOP_COMPOSITION_END, TOP_KEY_PRESS, TOP_TEXT_INPUT, TOP_PASTE]
10380 },
10381 compositionEnd: {
10382 phasedRegistrationNames: {
10383 bubbled: 'onCompositionEnd',
10384 captured: 'onCompositionEndCapture'
10385 },
10386 dependencies: [TOP_BLUR, TOP_COMPOSITION_END, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
10387 },
10388 compositionStart: {
10389 phasedRegistrationNames: {
10390 bubbled: 'onCompositionStart',
10391 captured: 'onCompositionStartCapture'
10392 },
10393 dependencies: [TOP_BLUR, TOP_COMPOSITION_START, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
10394 },
10395 compositionUpdate: {
10396 phasedRegistrationNames: {
10397 bubbled: 'onCompositionUpdate',
10398 captured: 'onCompositionUpdateCapture'
10399 },
10400 dependencies: [TOP_BLUR, TOP_COMPOSITION_UPDATE, TOP_KEY_DOWN, TOP_KEY_PRESS, TOP_KEY_UP, TOP_MOUSE_DOWN]
10401 }
10402}; // Track whether we've ever handled a keypress on the space key.
10403
10404var hasSpaceKeypress = false;
10405/**
10406 * Return whether a native keypress event is assumed to be a command.
10407 * This is required because Firefox fires `keypress` events for key commands
10408 * (cut, copy, select-all, etc.) even though no character is inserted.
10409 */
10410
10411function isKeypressCommand(nativeEvent) {
10412 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
10413 !(nativeEvent.ctrlKey && nativeEvent.altKey);
10414}
10415/**
10416 * Translate native top level events into event types.
10417 *
10418 * @param {string} topLevelType
10419 * @return {object}
10420 */
10421
10422
10423function getCompositionEventType(topLevelType) {
10424 switch (topLevelType) {
10425 case TOP_COMPOSITION_START:
10426 return eventTypes$1.compositionStart;
10427
10428 case TOP_COMPOSITION_END:
10429 return eventTypes$1.compositionEnd;
10430
10431 case TOP_COMPOSITION_UPDATE:
10432 return eventTypes$1.compositionUpdate;
10433 }
10434}
10435/**
10436 * Does our fallback best-guess model think this event signifies that
10437 * composition has begun?
10438 *
10439 * @param {string} topLevelType
10440 * @param {object} nativeEvent
10441 * @return {boolean}
10442 */
10443
10444
10445function isFallbackCompositionStart(topLevelType, nativeEvent) {
10446 return topLevelType === TOP_KEY_DOWN && nativeEvent.keyCode === START_KEYCODE;
10447}
10448/**
10449 * Does our fallback mode think that this event is the end of composition?
10450 *
10451 * @param {string} topLevelType
10452 * @param {object} nativeEvent
10453 * @return {boolean}
10454 */
10455
10456
10457function isFallbackCompositionEnd(topLevelType, nativeEvent) {
10458 switch (topLevelType) {
10459 case TOP_KEY_UP:
10460 // Command keys insert or clear IME input.
10461 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
10462
10463 case TOP_KEY_DOWN:
10464 // Expect IME keyCode on each keydown. If we get any other
10465 // code we must have exited earlier.
10466 return nativeEvent.keyCode !== START_KEYCODE;
10467
10468 case TOP_KEY_PRESS:
10469 case TOP_MOUSE_DOWN:
10470 case TOP_BLUR:
10471 // Events are not possible without cancelling IME.
10472 return true;
10473
10474 default:
10475 return false;
10476 }
10477}
10478/**
10479 * Google Input Tools provides composition data via a CustomEvent,
10480 * with the `data` property populated in the `detail` object. If this
10481 * is available on the event object, use it. If not, this is a plain
10482 * composition event and we have nothing special to extract.
10483 *
10484 * @param {object} nativeEvent
10485 * @return {?string}
10486 */
10487
10488
10489function getDataFromCustomEvent(nativeEvent) {
10490 var detail = nativeEvent.detail;
10491
10492 if (typeof detail === 'object' && 'data' in detail) {
10493 return detail.data;
10494 }
10495
10496 return null;
10497}
10498/**
10499 * Check if a composition event was triggered by Korean IME.
10500 * Our fallback mode does not work well with IE's Korean IME,
10501 * so just use native composition events when Korean IME is used.
10502 * Although CompositionEvent.locale property is deprecated,
10503 * it is available in IE, where our fallback mode is enabled.
10504 *
10505 * @param {object} nativeEvent
10506 * @return {boolean}
10507 */
10508
10509
10510function isUsingKoreanIME(nativeEvent) {
10511 return nativeEvent.locale === 'ko';
10512} // Track the current IME composition status, if any.
10513
10514
10515var isComposing = false;
10516/**
10517 * @return {?object} A SyntheticCompositionEvent.
10518 */
10519
10520function extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
10521 var eventType;
10522 var fallbackData;
10523
10524 if (canUseCompositionEvent) {
10525 eventType = getCompositionEventType(topLevelType);
10526 } else if (!isComposing) {
10527 if (isFallbackCompositionStart(topLevelType, nativeEvent)) {
10528 eventType = eventTypes$1.compositionStart;
10529 }
10530 } else if (isFallbackCompositionEnd(topLevelType, nativeEvent)) {
10531 eventType = eventTypes$1.compositionEnd;
10532 }
10533
10534 if (!eventType) {
10535 return null;
10536 }
10537
10538 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
10539 // The current composition is stored statically and must not be
10540 // overwritten while composition continues.
10541 if (!isComposing && eventType === eventTypes$1.compositionStart) {
10542 isComposing = initialize(nativeEventTarget);
10543 } else if (eventType === eventTypes$1.compositionEnd) {
10544 if (isComposing) {
10545 fallbackData = getData();
10546 }
10547 }
10548 }
10549
10550 var event = SyntheticCompositionEvent.getPooled(eventType, targetInst, nativeEvent, nativeEventTarget);
10551
10552 if (fallbackData) {
10553 // Inject data generated from fallback path into the synthetic event.
10554 // This matches the property of native CompositionEventInterface.
10555 event.data = fallbackData;
10556 } else {
10557 var customData = getDataFromCustomEvent(nativeEvent);
10558
10559 if (customData !== null) {
10560 event.data = customData;
10561 }
10562 }
10563
10564 accumulateTwoPhaseDispatches(event);
10565 return event;
10566}
10567/**
10568 * @param {TopLevelType} topLevelType Number from `TopLevelType`.
10569 * @param {object} nativeEvent Native browser event.
10570 * @return {?string} The string corresponding to this `beforeInput` event.
10571 */
10572
10573
10574function getNativeBeforeInputChars(topLevelType, nativeEvent) {
10575 switch (topLevelType) {
10576 case TOP_COMPOSITION_END:
10577 return getDataFromCustomEvent(nativeEvent);
10578
10579 case TOP_KEY_PRESS:
10580 /**
10581 * If native `textInput` events are available, our goal is to make
10582 * use of them. However, there is a special case: the spacebar key.
10583 * In Webkit, preventing default on a spacebar `textInput` event
10584 * cancels character insertion, but it *also* causes the browser
10585 * to fall back to its default spacebar behavior of scrolling the
10586 * page.
10587 *
10588 * Tracking at:
10589 * https://code.google.com/p/chromium/issues/detail?id=355103
10590 *
10591 * To avoid this issue, use the keypress event as if no `textInput`
10592 * event is available.
10593 */
10594 var which = nativeEvent.which;
10595
10596 if (which !== SPACEBAR_CODE) {
10597 return null;
10598 }
10599
10600 hasSpaceKeypress = true;
10601 return SPACEBAR_CHAR;
10602
10603 case TOP_TEXT_INPUT:
10604 // Record the characters to be added to the DOM.
10605 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
10606 // it at the keypress level and bail immediately. Android Chrome
10607 // doesn't give us keycodes, so we need to ignore it.
10608
10609 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
10610 return null;
10611 }
10612
10613 return chars;
10614
10615 default:
10616 // For other native event types, do nothing.
10617 return null;
10618 }
10619}
10620/**
10621 * For browsers that do not provide the `textInput` event, extract the
10622 * appropriate string to use for SyntheticInputEvent.
10623 *
10624 * @param {number} topLevelType Number from `TopLevelEventTypes`.
10625 * @param {object} nativeEvent Native browser event.
10626 * @return {?string} The fallback string for this `beforeInput` event.
10627 */
10628
10629
10630function getFallbackBeforeInputChars(topLevelType, nativeEvent) {
10631 // If we are currently composing (IME) and using a fallback to do so,
10632 // try to extract the composed characters from the fallback object.
10633 // If composition event is available, we extract a string only at
10634 // compositionevent, otherwise extract it at fallback events.
10635 if (isComposing) {
10636 if (topLevelType === TOP_COMPOSITION_END || !canUseCompositionEvent && isFallbackCompositionEnd(topLevelType, nativeEvent)) {
10637 var chars = getData();
10638 reset();
10639 isComposing = false;
10640 return chars;
10641 }
10642
10643 return null;
10644 }
10645
10646 switch (topLevelType) {
10647 case TOP_PASTE:
10648 // If a paste event occurs after a keypress, throw out the input
10649 // chars. Paste events should not lead to BeforeInput events.
10650 return null;
10651
10652 case TOP_KEY_PRESS:
10653 /**
10654 * As of v27, Firefox may fire keypress events even when no character
10655 * will be inserted. A few possibilities:
10656 *
10657 * - `which` is `0`. Arrow keys, Esc key, etc.
10658 *
10659 * - `which` is the pressed key code, but no char is available.
10660 * Ex: 'AltGr + d` in Polish. There is no modified character for
10661 * this key combination and no character is inserted into the
10662 * document, but FF fires the keypress for char code `100` anyway.
10663 * No `input` event will occur.
10664 *
10665 * - `which` is the pressed key code, but a command combination is
10666 * being used. Ex: `Cmd+C`. No character is inserted, and no
10667 * `input` event will occur.
10668 */
10669 if (!isKeypressCommand(nativeEvent)) {
10670 // IE fires the `keypress` event when a user types an emoji via
10671 // Touch keyboard of Windows. In such a case, the `char` property
10672 // holds an emoji character like `\uD83D\uDE0A`. Because its length
10673 // is 2, the property `which` does not represent an emoji correctly.
10674 // In such a case, we directly return the `char` property instead of
10675 // using `which`.
10676 if (nativeEvent.char && nativeEvent.char.length > 1) {
10677 return nativeEvent.char;
10678 } else if (nativeEvent.which) {
10679 return String.fromCharCode(nativeEvent.which);
10680 }
10681 }
10682
10683 return null;
10684
10685 case TOP_COMPOSITION_END:
10686 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
10687
10688 default:
10689 return null;
10690 }
10691}
10692/**
10693 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
10694 * `textInput` or fallback behavior.
10695 *
10696 * @return {?object} A SyntheticInputEvent.
10697 */
10698
10699
10700function extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget) {
10701 var chars;
10702
10703 if (canUseTextInputEvent) {
10704 chars = getNativeBeforeInputChars(topLevelType, nativeEvent);
10705 } else {
10706 chars = getFallbackBeforeInputChars(topLevelType, nativeEvent);
10707 } // If no characters are being inserted, no BeforeInput event should
10708 // be fired.
10709
10710
10711 if (!chars) {
10712 return null;
10713 }
10714
10715 var event = SyntheticInputEvent.getPooled(eventTypes$1.beforeInput, targetInst, nativeEvent, nativeEventTarget);
10716 event.data = chars;
10717 accumulateTwoPhaseDispatches(event);
10718 return event;
10719}
10720/**
10721 * Create an `onBeforeInput` event to match
10722 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
10723 *
10724 * This event plugin is based on the native `textInput` event
10725 * available in Chrome, Safari, Opera, and IE. This event fires after
10726 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
10727 *
10728 * `beforeInput` is spec'd but not implemented in any browsers, and
10729 * the `input` event does not provide any useful information about what has
10730 * actually been added, contrary to the spec. Thus, `textInput` is the best
10731 * available event to identify the characters that have actually been inserted
10732 * into the target node.
10733 *
10734 * This plugin is also responsible for emitting `composition` events, thus
10735 * allowing us to share composition fallback code for both `beforeInput` and
10736 * `composition` event types.
10737 */
10738
10739
10740var BeforeInputEventPlugin = {
10741 eventTypes: eventTypes$1,
10742 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
10743 var composition = extractCompositionEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
10744 var beforeInput = extractBeforeInputEvent(topLevelType, targetInst, nativeEvent, nativeEventTarget);
10745
10746 if (composition === null) {
10747 return beforeInput;
10748 }
10749
10750 if (beforeInput === null) {
10751 return composition;
10752 }
10753
10754 return [composition, beforeInput];
10755 }
10756};
10757
10758/**
10759 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
10760 */
10761var supportedInputTypes = {
10762 color: true,
10763 date: true,
10764 datetime: true,
10765 'datetime-local': true,
10766 email: true,
10767 month: true,
10768 number: true,
10769 password: true,
10770 range: true,
10771 search: true,
10772 tel: true,
10773 text: true,
10774 time: true,
10775 url: true,
10776 week: true
10777};
10778
10779function isTextInputElement(elem) {
10780 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
10781
10782 if (nodeName === 'input') {
10783 return !!supportedInputTypes[elem.type];
10784 }
10785
10786 if (nodeName === 'textarea') {
10787 return true;
10788 }
10789
10790 return false;
10791}
10792
10793var eventTypes$2 = {
10794 change: {
10795 phasedRegistrationNames: {
10796 bubbled: 'onChange',
10797 captured: 'onChangeCapture'
10798 },
10799 dependencies: [TOP_BLUR, TOP_CHANGE, TOP_CLICK, TOP_FOCUS, TOP_INPUT, TOP_KEY_DOWN, TOP_KEY_UP, TOP_SELECTION_CHANGE]
10800 }
10801};
10802
10803function createAndAccumulateChangeEvent(inst, nativeEvent, target) {
10804 var event = SyntheticEvent.getPooled(eventTypes$2.change, inst, nativeEvent, target);
10805 event.type = 'change'; // Flag this event loop as needing state restore.
10806
10807 enqueueStateRestore(target);
10808 accumulateTwoPhaseDispatches(event);
10809 return event;
10810}
10811/**
10812 * For IE shims
10813 */
10814
10815
10816var activeElement = null;
10817var activeElementInst = null;
10818/**
10819 * SECTION: handle `change` event
10820 */
10821
10822function shouldUseChangeEvent(elem) {
10823 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
10824 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
10825}
10826
10827function manualDispatchChangeEvent(nativeEvent) {
10828 var event = createAndAccumulateChangeEvent(activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
10829 // other events and have it go through ReactBrowserEventEmitter. Since it
10830 // doesn't, we manually listen for the events and so we have to enqueue and
10831 // process the abstract event manually.
10832 //
10833 // Batching is necessary here in order to ensure that all event handlers run
10834 // before the next rerender (including event handlers attached to ancestor
10835 // elements instead of directly on the input). Without this, controlled
10836 // components don't work properly in conjunction with event bubbling because
10837 // the component is rerendered and the value reverted before all the event
10838 // handlers can run. See https://github.com/facebook/react/issues/708.
10839
10840 batchedUpdates(runEventInBatch, event);
10841}
10842
10843function runEventInBatch(event) {
10844 runEventsInBatch(event);
10845}
10846
10847function getInstIfValueChanged(targetInst) {
10848 var targetNode = getNodeFromInstance$1(targetInst);
10849
10850 if (updateValueIfChanged(targetNode)) {
10851 return targetInst;
10852 }
10853}
10854
10855function getTargetInstForChangeEvent(topLevelType, targetInst) {
10856 if (topLevelType === TOP_CHANGE) {
10857 return targetInst;
10858 }
10859}
10860/**
10861 * SECTION: handle `input` event
10862 */
10863
10864
10865var isInputEventSupported = false;
10866
10867if (canUseDOM) {
10868 // IE9 claims to support the input event but fails to trigger it when
10869 // deleting text, so we ignore its input events.
10870 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
10871}
10872/**
10873 * (For IE <=9) Starts tracking propertychange events on the passed-in element
10874 * and override the value property so that we can distinguish user events from
10875 * value changes in JS.
10876 */
10877
10878
10879function startWatchingForValueChange(target, targetInst) {
10880 activeElement = target;
10881 activeElementInst = targetInst;
10882 activeElement.attachEvent('onpropertychange', handlePropertyChange);
10883}
10884/**
10885 * (For IE <=9) Removes the event listeners from the currently-tracked element,
10886 * if any exists.
10887 */
10888
10889
10890function stopWatchingForValueChange() {
10891 if (!activeElement) {
10892 return;
10893 }
10894
10895 activeElement.detachEvent('onpropertychange', handlePropertyChange);
10896 activeElement = null;
10897 activeElementInst = null;
10898}
10899/**
10900 * (For IE <=9) Handles a propertychange event, sending a `change` event if
10901 * the value of the active element has changed.
10902 */
10903
10904
10905function handlePropertyChange(nativeEvent) {
10906 if (nativeEvent.propertyName !== 'value') {
10907 return;
10908 }
10909
10910 if (getInstIfValueChanged(activeElementInst)) {
10911 manualDispatchChangeEvent(nativeEvent);
10912 }
10913}
10914
10915function handleEventsForInputEventPolyfill(topLevelType, target, targetInst) {
10916 if (topLevelType === TOP_FOCUS) {
10917 // In IE9, propertychange fires for most input events but is buggy and
10918 // doesn't fire when text is deleted, but conveniently, selectionchange
10919 // appears to fire in all of the remaining cases so we catch those and
10920 // forward the event if the value has changed
10921 // In either case, we don't want to call the event handler if the value
10922 // is changed from JS so we redefine a setter for `.value` that updates
10923 // our activeElementValue variable, allowing us to ignore those changes
10924 //
10925 // stopWatching() should be a noop here but we call it just in case we
10926 // missed a blur event somehow.
10927 stopWatchingForValueChange();
10928 startWatchingForValueChange(target, targetInst);
10929 } else if (topLevelType === TOP_BLUR) {
10930 stopWatchingForValueChange();
10931 }
10932} // For IE8 and IE9.
10933
10934
10935function getTargetInstForInputEventPolyfill(topLevelType, targetInst) {
10936 if (topLevelType === TOP_SELECTION_CHANGE || topLevelType === TOP_KEY_UP || topLevelType === TOP_KEY_DOWN) {
10937 // On the selectionchange event, the target is just document which isn't
10938 // helpful for us so just check activeElement instead.
10939 //
10940 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
10941 // propertychange on the first input event after setting `value` from a
10942 // script and fires only keydown, keypress, keyup. Catching keyup usually
10943 // gets it and catching keydown lets us fire an event for the first
10944 // keystroke if user does a key repeat (it'll be a little delayed: right
10945 // before the second keystroke). Other input methods (e.g., paste) seem to
10946 // fire selectionchange normally.
10947 return getInstIfValueChanged(activeElementInst);
10948 }
10949}
10950/**
10951 * SECTION: handle `click` event
10952 */
10953
10954
10955function shouldUseClickEvent(elem) {
10956 // Use the `click` event to detect changes to checkbox and radio inputs.
10957 // This approach works across all browsers, whereas `change` does not fire
10958 // until `blur` in IE8.
10959 var nodeName = elem.nodeName;
10960 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
10961}
10962
10963function getTargetInstForClickEvent(topLevelType, targetInst) {
10964 if (topLevelType === TOP_CLICK) {
10965 return getInstIfValueChanged(targetInst);
10966 }
10967}
10968
10969function getTargetInstForInputOrChangeEvent(topLevelType, targetInst) {
10970 if (topLevelType === TOP_INPUT || topLevelType === TOP_CHANGE) {
10971 return getInstIfValueChanged(targetInst);
10972 }
10973}
10974
10975function handleControlledInputBlur(node) {
10976 var state = node._wrapperState;
10977
10978 if (!state || !state.controlled || node.type !== 'number') {
10979 return;
10980 }
10981
10982 if (!disableInputAttributeSyncing) {
10983 // If controlled, assign the value attribute to the current value on blur
10984 setDefaultValue(node, 'number', node.value);
10985 }
10986}
10987/**
10988 * This plugin creates an `onChange` event that normalizes change events
10989 * across form elements. This event fires at a time when it's possible to
10990 * change the element's value without seeing a flicker.
10991 *
10992 * Supported elements are:
10993 * - input (see `isTextInputElement`)
10994 * - textarea
10995 * - select
10996 */
10997
10998
10999var ChangeEventPlugin = {
11000 eventTypes: eventTypes$2,
11001 _isInputEventSupported: isInputEventSupported,
11002 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
11003 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
11004 var getTargetInstFunc, handleEventFunc;
11005
11006 if (shouldUseChangeEvent(targetNode)) {
11007 getTargetInstFunc = getTargetInstForChangeEvent;
11008 } else if (isTextInputElement(targetNode)) {
11009 if (isInputEventSupported) {
11010 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
11011 } else {
11012 getTargetInstFunc = getTargetInstForInputEventPolyfill;
11013 handleEventFunc = handleEventsForInputEventPolyfill;
11014 }
11015 } else if (shouldUseClickEvent(targetNode)) {
11016 getTargetInstFunc = getTargetInstForClickEvent;
11017 }
11018
11019 if (getTargetInstFunc) {
11020 var inst = getTargetInstFunc(topLevelType, targetInst);
11021
11022 if (inst) {
11023 var event = createAndAccumulateChangeEvent(inst, nativeEvent, nativeEventTarget);
11024 return event;
11025 }
11026 }
11027
11028 if (handleEventFunc) {
11029 handleEventFunc(topLevelType, targetNode, targetInst);
11030 } // When blurring, set the value attribute for number inputs
11031
11032
11033 if (topLevelType === TOP_BLUR) {
11034 handleControlledInputBlur(targetNode);
11035 }
11036 }
11037};
11038
11039/**
11040 * Module that is injectable into `EventPluginHub`, that specifies a
11041 * deterministic ordering of `EventPlugin`s. A convenient way to reason about
11042 * plugins, without having to package every one of them. This is better than
11043 * having plugins be ordered in the same order that they are injected because
11044 * that ordering would be influenced by the packaging order.
11045 * `ResponderEventPlugin` must occur before `SimpleEventPlugin` so that
11046 * preventing default on events is convenient in `SimpleEventPlugin` handlers.
11047 */
11048var DOMEventPluginOrder = ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'];
11049
11050var eventTypes$3 = {
11051 mouseEnter: {
11052 registrationName: 'onMouseEnter',
11053 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
11054 },
11055 mouseLeave: {
11056 registrationName: 'onMouseLeave',
11057 dependencies: [TOP_MOUSE_OUT, TOP_MOUSE_OVER]
11058 },
11059 pointerEnter: {
11060 registrationName: 'onPointerEnter',
11061 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
11062 },
11063 pointerLeave: {
11064 registrationName: 'onPointerLeave',
11065 dependencies: [TOP_POINTER_OUT, TOP_POINTER_OVER]
11066 }
11067}; // We track the lastNativeEvent to ensure that when we encounter
11068// cases where we process the same nativeEvent multiple times,
11069// which can happen when have multiple ancestors, that we don't
11070// duplicate enter
11071
11072var lastNativeEvent;
11073var EnterLeaveEventPlugin = {
11074 eventTypes: eventTypes$3,
11075
11076 /**
11077 * For almost every interaction we care about, there will be both a top-level
11078 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
11079 * we do not extract duplicate events. However, moving the mouse into the
11080 * browser from outside will not fire a `mouseout` event. In this case, we use
11081 * the `mouseover` top-level event.
11082 */
11083 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
11084 var isOverEvent = topLevelType === TOP_MOUSE_OVER || topLevelType === TOP_POINTER_OVER;
11085 var isOutEvent = topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_POINTER_OUT;
11086
11087 if (isOverEvent && (eventSystemFlags & IS_REPLAYED) === 0 && (nativeEvent.relatedTarget || nativeEvent.fromElement)) {
11088 // If this is an over event with a target, then we've already dispatched
11089 // the event in the out event of the other target. If this is replayed,
11090 // then it's because we couldn't dispatch against this target previously
11091 // so we have to do it now instead.
11092 return null;
11093 }
11094
11095 if (!isOutEvent && !isOverEvent) {
11096 // Must not be a mouse or pointer in or out - ignoring.
11097 return null;
11098 }
11099
11100 var win;
11101
11102 if (nativeEventTarget.window === nativeEventTarget) {
11103 // `nativeEventTarget` is probably a window object.
11104 win = nativeEventTarget;
11105 } else {
11106 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
11107 var doc = nativeEventTarget.ownerDocument;
11108
11109 if (doc) {
11110 win = doc.defaultView || doc.parentWindow;
11111 } else {
11112 win = window;
11113 }
11114 }
11115
11116 var from;
11117 var to;
11118
11119 if (isOutEvent) {
11120 from = targetInst;
11121 var related = nativeEvent.relatedTarget || nativeEvent.toElement;
11122 to = related ? getClosestInstanceFromNode(related) : null;
11123
11124 if (to !== null) {
11125 var nearestMounted = getNearestMountedFiber(to);
11126
11127 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
11128 to = null;
11129 }
11130 }
11131 } else {
11132 // Moving to a node from outside the window.
11133 from = null;
11134 to = targetInst;
11135 }
11136
11137 if (from === to) {
11138 // Nothing pertains to our managed components.
11139 return null;
11140 }
11141
11142 var eventInterface, leaveEventType, enterEventType, eventTypePrefix;
11143
11144 if (topLevelType === TOP_MOUSE_OUT || topLevelType === TOP_MOUSE_OVER) {
11145 eventInterface = SyntheticMouseEvent;
11146 leaveEventType = eventTypes$3.mouseLeave;
11147 enterEventType = eventTypes$3.mouseEnter;
11148 eventTypePrefix = 'mouse';
11149 } else if (topLevelType === TOP_POINTER_OUT || topLevelType === TOP_POINTER_OVER) {
11150 eventInterface = SyntheticPointerEvent;
11151 leaveEventType = eventTypes$3.pointerLeave;
11152 enterEventType = eventTypes$3.pointerEnter;
11153 eventTypePrefix = 'pointer';
11154 }
11155
11156 var fromNode = from == null ? win : getNodeFromInstance$1(from);
11157 var toNode = to == null ? win : getNodeFromInstance$1(to);
11158 var leave = eventInterface.getPooled(leaveEventType, from, nativeEvent, nativeEventTarget);
11159 leave.type = eventTypePrefix + 'leave';
11160 leave.target = fromNode;
11161 leave.relatedTarget = toNode;
11162 var enter = eventInterface.getPooled(enterEventType, to, nativeEvent, nativeEventTarget);
11163 enter.type = eventTypePrefix + 'enter';
11164 enter.target = toNode;
11165 enter.relatedTarget = fromNode;
11166 accumulateEnterLeaveDispatches(leave, enter, from, to);
11167
11168 if (nativeEvent === lastNativeEvent) {
11169 lastNativeEvent = null;
11170 return [leave];
11171 }
11172
11173 lastNativeEvent = nativeEvent;
11174 return [leave, enter];
11175 }
11176};
11177
11178/**
11179 * inlined Object.is polyfill to avoid requiring consumers ship their own
11180 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
11181 */
11182function is(x, y) {
11183 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
11184 ;
11185}
11186
11187var is$1 = typeof Object.is === 'function' ? Object.is : is;
11188
11189var hasOwnProperty$2 = Object.prototype.hasOwnProperty;
11190/**
11191 * Performs equality by iterating through keys on an object and returning false
11192 * when any key has values which are not strictly equal between the arguments.
11193 * Returns true when the values of all keys are strictly equal.
11194 */
11195
11196function shallowEqual(objA, objB) {
11197 if (is$1(objA, objB)) {
11198 return true;
11199 }
11200
11201 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
11202 return false;
11203 }
11204
11205 var keysA = Object.keys(objA);
11206 var keysB = Object.keys(objB);
11207
11208 if (keysA.length !== keysB.length) {
11209 return false;
11210 } // Test for A's keys different from B.
11211
11212
11213 for (var i = 0; i < keysA.length; i++) {
11214 if (!hasOwnProperty$2.call(objB, keysA[i]) || !is$1(objA[keysA[i]], objB[keysA[i]])) {
11215 return false;
11216 }
11217 }
11218
11219 return true;
11220}
11221
11222var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
11223var eventTypes$4 = {
11224 select: {
11225 phasedRegistrationNames: {
11226 bubbled: 'onSelect',
11227 captured: 'onSelectCapture'
11228 },
11229 dependencies: [TOP_BLUR, TOP_CONTEXT_MENU, TOP_DRAG_END, TOP_FOCUS, TOP_KEY_DOWN, TOP_KEY_UP, TOP_MOUSE_DOWN, TOP_MOUSE_UP, TOP_SELECTION_CHANGE]
11230 }
11231};
11232var activeElement$1 = null;
11233var activeElementInst$1 = null;
11234var lastSelection = null;
11235var mouseDown = false;
11236/**
11237 * Get an object which is a unique representation of the current selection.
11238 *
11239 * The return value will not be consistent across nodes or browsers, but
11240 * two identical selections on the same node will return identical objects.
11241 *
11242 * @param {DOMElement} node
11243 * @return {object}
11244 */
11245
11246function getSelection$1(node) {
11247 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
11248 return {
11249 start: node.selectionStart,
11250 end: node.selectionEnd
11251 };
11252 } else {
11253 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
11254 var selection = win.getSelection();
11255 return {
11256 anchorNode: selection.anchorNode,
11257 anchorOffset: selection.anchorOffset,
11258 focusNode: selection.focusNode,
11259 focusOffset: selection.focusOffset
11260 };
11261 }
11262}
11263/**
11264 * Get document associated with the event target.
11265 *
11266 * @param {object} nativeEventTarget
11267 * @return {Document}
11268 */
11269
11270
11271function getEventTargetDocument(eventTarget) {
11272 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
11273}
11274/**
11275 * Poll selection to see whether it's changed.
11276 *
11277 * @param {object} nativeEvent
11278 * @param {object} nativeEventTarget
11279 * @return {?SyntheticEvent}
11280 */
11281
11282
11283function constructSelectEvent(nativeEvent, nativeEventTarget) {
11284 // Ensure we have the right element, and that the user is not dragging a
11285 // selection (this matches native `select` event behavior). In HTML5, select
11286 // fires only on input and textarea thus if there's no focused element we
11287 // won't dispatch.
11288 var doc = getEventTargetDocument(nativeEventTarget);
11289
11290 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
11291 return null;
11292 } // Only fire when selection has actually changed.
11293
11294
11295 var currentSelection = getSelection$1(activeElement$1);
11296
11297 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
11298 lastSelection = currentSelection;
11299 var syntheticEvent = SyntheticEvent.getPooled(eventTypes$4.select, activeElementInst$1, nativeEvent, nativeEventTarget);
11300 syntheticEvent.type = 'select';
11301 syntheticEvent.target = activeElement$1;
11302 accumulateTwoPhaseDispatches(syntheticEvent);
11303 return syntheticEvent;
11304 }
11305
11306 return null;
11307}
11308/**
11309 * This plugin creates an `onSelect` event that normalizes select events
11310 * across form elements.
11311 *
11312 * Supported elements are:
11313 * - input (see `isTextInputElement`)
11314 * - textarea
11315 * - contentEditable
11316 *
11317 * This differs from native browser implementations in the following ways:
11318 * - Fires on contentEditable fields as well as inputs.
11319 * - Fires for collapsed selection.
11320 * - Fires after user input.
11321 */
11322
11323
11324var SelectEventPlugin = {
11325 eventTypes: eventTypes$4,
11326 extractEvents: function (topLevelType, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags) {
11327 var doc = getEventTargetDocument(nativeEventTarget); // Track whether all listeners exists for this plugin. If none exist, we do
11328 // not extract events. See #3639.
11329
11330 if (!doc || !isListeningToAllDependencies('onSelect', doc)) {
11331 return null;
11332 }
11333
11334 var targetNode = targetInst ? getNodeFromInstance$1(targetInst) : window;
11335
11336 switch (topLevelType) {
11337 // Track the input node that has focus.
11338 case TOP_FOCUS:
11339 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
11340 activeElement$1 = targetNode;
11341 activeElementInst$1 = targetInst;
11342 lastSelection = null;
11343 }
11344
11345 break;
11346
11347 case TOP_BLUR:
11348 activeElement$1 = null;
11349 activeElementInst$1 = null;
11350 lastSelection = null;
11351 break;
11352 // Don't fire the event while the user is dragging. This matches the
11353 // semantics of the native select event.
11354
11355 case TOP_MOUSE_DOWN:
11356 mouseDown = true;
11357 break;
11358
11359 case TOP_CONTEXT_MENU:
11360 case TOP_MOUSE_UP:
11361 case TOP_DRAG_END:
11362 mouseDown = false;
11363 return constructSelectEvent(nativeEvent, nativeEventTarget);
11364 // Chrome and IE fire non-standard event when selection is changed (and
11365 // sometimes when it hasn't). IE's event fires out of order with respect
11366 // to key and input events on deletion, so we discard it.
11367 //
11368 // Firefox doesn't support selectionchange, so check selection status
11369 // after each key entry. The selection changes after keydown and before
11370 // keyup, but we check on keydown as well in the case of holding down a
11371 // key, when multiple keydown events are fired but only one keyup is.
11372 // This is also our approach for IE handling, for the reason above.
11373
11374 case TOP_SELECTION_CHANGE:
11375 if (skipSelectionChangeEvent) {
11376 break;
11377 }
11378
11379 // falls through
11380
11381 case TOP_KEY_DOWN:
11382 case TOP_KEY_UP:
11383 return constructSelectEvent(nativeEvent, nativeEventTarget);
11384 }
11385
11386 return null;
11387 }
11388};
11389
11390/**
11391 * Inject modules for resolving DOM hierarchy and plugin ordering.
11392 */
11393
11394injection.injectEventPluginOrder(DOMEventPluginOrder);
11395setComponentTree(getFiberCurrentPropsFromNode$1, getInstanceFromNode$1, getNodeFromInstance$1);
11396/**
11397 * Some important event plugins included by default (without having to require
11398 * them).
11399 */
11400
11401injection.injectEventPluginsByName({
11402 SimpleEventPlugin: SimpleEventPlugin,
11403 EnterLeaveEventPlugin: EnterLeaveEventPlugin,
11404 ChangeEventPlugin: ChangeEventPlugin,
11405 SelectEventPlugin: SelectEventPlugin,
11406 BeforeInputEventPlugin: BeforeInputEventPlugin
11407});
11408
11409// Prefix measurements so that it's possible to filter them.
11410// Longer prefixes are hard to read in DevTools.
11411var reactEmoji = "\u269B";
11412var warningEmoji = "\u26D4";
11413var supportsUserTiming = typeof performance !== 'undefined' && typeof performance.mark === 'function' && typeof performance.clearMarks === 'function' && typeof performance.measure === 'function' && typeof performance.clearMeasures === 'function'; // Keep track of current fiber so that we know the path to unwind on pause.
11414// TODO: this looks the same as nextUnitOfWork in scheduler. Can we unify them?
11415
11416var currentFiber = null; // If we're in the middle of user code, which fiber and method is it?
11417// Reusing `currentFiber` would be confusing for this because user code fiber
11418// can change during commit phase too, but we don't need to unwind it (since
11419// lifecycles in the commit phase don't resemble a tree).
11420
11421var currentPhase = null;
11422var currentPhaseFiber = null; // Did lifecycle hook schedule an update? This is often a performance problem,
11423// so we will keep track of it, and include it in the report.
11424// Track commits caused by cascading updates.
11425
11426var isCommitting = false;
11427var hasScheduledUpdateInCurrentCommit = false;
11428var hasScheduledUpdateInCurrentPhase = false;
11429var commitCountInCurrentWorkLoop = 0;
11430var effectCountInCurrentCommit = 0;
11431// to avoid stretch the commit phase with measurement overhead.
11432
11433var labelsInCurrentCommit = new Set();
11434
11435var formatMarkName = function (markName) {
11436 return reactEmoji + " " + markName;
11437};
11438
11439var formatLabel = function (label, warning) {
11440 var prefix = warning ? warningEmoji + " " : reactEmoji + " ";
11441 var suffix = warning ? " Warning: " + warning : '';
11442 return "" + prefix + label + suffix;
11443};
11444
11445var beginMark = function (markName) {
11446 performance.mark(formatMarkName(markName));
11447};
11448
11449var clearMark = function (markName) {
11450 performance.clearMarks(formatMarkName(markName));
11451};
11452
11453var endMark = function (label, markName, warning) {
11454 var formattedMarkName = formatMarkName(markName);
11455 var formattedLabel = formatLabel(label, warning);
11456
11457 try {
11458 performance.measure(formattedLabel, formattedMarkName);
11459 } catch (err) {} // If previous mark was missing for some reason, this will throw.
11460 // This could only happen if React crashed in an unexpected place earlier.
11461 // Don't pile on with more errors.
11462 // Clear marks immediately to avoid growing buffer.
11463
11464
11465 performance.clearMarks(formattedMarkName);
11466 performance.clearMeasures(formattedLabel);
11467};
11468
11469var getFiberMarkName = function (label, debugID) {
11470 return label + " (#" + debugID + ")";
11471};
11472
11473var getFiberLabel = function (componentName, isMounted, phase) {
11474 if (phase === null) {
11475 // These are composite component total time measurements.
11476 return componentName + " [" + (isMounted ? 'update' : 'mount') + "]";
11477 } else {
11478 // Composite component methods.
11479 return componentName + "." + phase;
11480 }
11481};
11482
11483var beginFiberMark = function (fiber, phase) {
11484 var componentName = getComponentName(fiber.type) || 'Unknown';
11485 var debugID = fiber._debugID;
11486 var isMounted = fiber.alternate !== null;
11487 var label = getFiberLabel(componentName, isMounted, phase);
11488
11489 if (isCommitting && labelsInCurrentCommit.has(label)) {
11490 // During the commit phase, we don't show duplicate labels because
11491 // there is a fixed overhead for every measurement, and we don't
11492 // want to stretch the commit phase beyond necessary.
11493 return false;
11494 }
11495
11496 labelsInCurrentCommit.add(label);
11497 var markName = getFiberMarkName(label, debugID);
11498 beginMark(markName);
11499 return true;
11500};
11501
11502var clearFiberMark = function (fiber, phase) {
11503 var componentName = getComponentName(fiber.type) || 'Unknown';
11504 var debugID = fiber._debugID;
11505 var isMounted = fiber.alternate !== null;
11506 var label = getFiberLabel(componentName, isMounted, phase);
11507 var markName = getFiberMarkName(label, debugID);
11508 clearMark(markName);
11509};
11510
11511var endFiberMark = function (fiber, phase, warning) {
11512 var componentName = getComponentName(fiber.type) || 'Unknown';
11513 var debugID = fiber._debugID;
11514 var isMounted = fiber.alternate !== null;
11515 var label = getFiberLabel(componentName, isMounted, phase);
11516 var markName = getFiberMarkName(label, debugID);
11517 endMark(label, markName, warning);
11518};
11519
11520var shouldIgnoreFiber = function (fiber) {
11521 // Host components should be skipped in the timeline.
11522 // We could check typeof fiber.type, but does this work with RN?
11523 switch (fiber.tag) {
11524 case HostRoot:
11525 case HostComponent:
11526 case HostText:
11527 case HostPortal:
11528 case Fragment:
11529 case ContextProvider:
11530 case ContextConsumer:
11531 case Mode:
11532 return true;
11533
11534 default:
11535 return false;
11536 }
11537};
11538
11539var clearPendingPhaseMeasurement = function () {
11540 if (currentPhase !== null && currentPhaseFiber !== null) {
11541 clearFiberMark(currentPhaseFiber, currentPhase);
11542 }
11543
11544 currentPhaseFiber = null;
11545 currentPhase = null;
11546 hasScheduledUpdateInCurrentPhase = false;
11547};
11548
11549var pauseTimers = function () {
11550 // Stops all currently active measurements so that they can be resumed
11551 // if we continue in a later deferred loop from the same unit of work.
11552 var fiber = currentFiber;
11553
11554 while (fiber) {
11555 if (fiber._debugIsCurrentlyTiming) {
11556 endFiberMark(fiber, null, null);
11557 }
11558
11559 fiber = fiber.return;
11560 }
11561};
11562
11563var resumeTimersRecursively = function (fiber) {
11564 if (fiber.return !== null) {
11565 resumeTimersRecursively(fiber.return);
11566 }
11567
11568 if (fiber._debugIsCurrentlyTiming) {
11569 beginFiberMark(fiber, null);
11570 }
11571};
11572
11573var resumeTimers = function () {
11574 // Resumes all measurements that were active during the last deferred loop.
11575 if (currentFiber !== null) {
11576 resumeTimersRecursively(currentFiber);
11577 }
11578};
11579
11580function recordEffect() {
11581 if (enableUserTimingAPI) {
11582 effectCountInCurrentCommit++;
11583 }
11584}
11585function recordScheduleUpdate() {
11586 if (enableUserTimingAPI) {
11587 if (isCommitting) {
11588 hasScheduledUpdateInCurrentCommit = true;
11589 }
11590
11591 if (currentPhase !== null && currentPhase !== 'componentWillMount' && currentPhase !== 'componentWillReceiveProps') {
11592 hasScheduledUpdateInCurrentPhase = true;
11593 }
11594 }
11595}
11596
11597
11598function startWorkTimer(fiber) {
11599 if (enableUserTimingAPI) {
11600 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
11601 return;
11602 } // If we pause, this is the fiber to unwind from.
11603
11604
11605 currentFiber = fiber;
11606
11607 if (!beginFiberMark(fiber, null)) {
11608 return;
11609 }
11610
11611 fiber._debugIsCurrentlyTiming = true;
11612 }
11613}
11614function cancelWorkTimer(fiber) {
11615 if (enableUserTimingAPI) {
11616 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
11617 return;
11618 } // Remember we shouldn't complete measurement for this fiber.
11619 // Otherwise flamechart will be deep even for small updates.
11620
11621
11622 fiber._debugIsCurrentlyTiming = false;
11623 clearFiberMark(fiber, null);
11624 }
11625}
11626function stopWorkTimer(fiber) {
11627 if (enableUserTimingAPI) {
11628 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
11629 return;
11630 } // If we pause, its parent is the fiber to unwind from.
11631
11632
11633 currentFiber = fiber.return;
11634
11635 if (!fiber._debugIsCurrentlyTiming) {
11636 return;
11637 }
11638
11639 fiber._debugIsCurrentlyTiming = false;
11640 endFiberMark(fiber, null, null);
11641 }
11642}
11643function stopFailedWorkTimer(fiber) {
11644 if (enableUserTimingAPI) {
11645 if (!supportsUserTiming || shouldIgnoreFiber(fiber)) {
11646 return;
11647 } // If we pause, its parent is the fiber to unwind from.
11648
11649
11650 currentFiber = fiber.return;
11651
11652 if (!fiber._debugIsCurrentlyTiming) {
11653 return;
11654 }
11655
11656 fiber._debugIsCurrentlyTiming = false;
11657 var warning = fiber.tag === SuspenseComponent ? 'Rendering was suspended' : 'An error was thrown inside this error boundary';
11658 endFiberMark(fiber, null, warning);
11659 }
11660}
11661function startPhaseTimer(fiber, phase) {
11662 if (enableUserTimingAPI) {
11663 if (!supportsUserTiming) {
11664 return;
11665 }
11666
11667 clearPendingPhaseMeasurement();
11668
11669 if (!beginFiberMark(fiber, phase)) {
11670 return;
11671 }
11672
11673 currentPhaseFiber = fiber;
11674 currentPhase = phase;
11675 }
11676}
11677function stopPhaseTimer() {
11678 if (enableUserTimingAPI) {
11679 if (!supportsUserTiming) {
11680 return;
11681 }
11682
11683 if (currentPhase !== null && currentPhaseFiber !== null) {
11684 var warning = hasScheduledUpdateInCurrentPhase ? 'Scheduled a cascading update' : null;
11685 endFiberMark(currentPhaseFiber, currentPhase, warning);
11686 }
11687
11688 currentPhase = null;
11689 currentPhaseFiber = null;
11690 }
11691}
11692function startWorkLoopTimer(nextUnitOfWork) {
11693 if (enableUserTimingAPI) {
11694 currentFiber = nextUnitOfWork;
11695
11696 if (!supportsUserTiming) {
11697 return;
11698 }
11699
11700 commitCountInCurrentWorkLoop = 0; // This is top level call.
11701 // Any other measurements are performed within.
11702
11703 beginMark('(React Tree Reconciliation)'); // Resume any measurements that were in progress during the last loop.
11704
11705 resumeTimers();
11706 }
11707}
11708function stopWorkLoopTimer(interruptedBy, didCompleteRoot) {
11709 if (enableUserTimingAPI) {
11710 if (!supportsUserTiming) {
11711 return;
11712 }
11713
11714 var warning = null;
11715
11716 if (interruptedBy !== null) {
11717 if (interruptedBy.tag === HostRoot) {
11718 warning = 'A top-level update interrupted the previous render';
11719 } else {
11720 var componentName = getComponentName(interruptedBy.type) || 'Unknown';
11721 warning = "An update to " + componentName + " interrupted the previous render";
11722 }
11723 } else if (commitCountInCurrentWorkLoop > 1) {
11724 warning = 'There were cascading updates';
11725 }
11726
11727 commitCountInCurrentWorkLoop = 0;
11728 var label = didCompleteRoot ? '(React Tree Reconciliation: Completed Root)' : '(React Tree Reconciliation: Yielded)'; // Pause any measurements until the next loop.
11729
11730 pauseTimers();
11731 endMark(label, '(React Tree Reconciliation)', warning);
11732 }
11733}
11734function startCommitTimer() {
11735 if (enableUserTimingAPI) {
11736 if (!supportsUserTiming) {
11737 return;
11738 }
11739
11740 isCommitting = true;
11741 hasScheduledUpdateInCurrentCommit = false;
11742 labelsInCurrentCommit.clear();
11743 beginMark('(Committing Changes)');
11744 }
11745}
11746function stopCommitTimer() {
11747 if (enableUserTimingAPI) {
11748 if (!supportsUserTiming) {
11749 return;
11750 }
11751
11752 var warning = null;
11753
11754 if (hasScheduledUpdateInCurrentCommit) {
11755 warning = 'Lifecycle hook scheduled a cascading update';
11756 } else if (commitCountInCurrentWorkLoop > 0) {
11757 warning = 'Caused by a cascading update in earlier commit';
11758 }
11759
11760 hasScheduledUpdateInCurrentCommit = false;
11761 commitCountInCurrentWorkLoop++;
11762 isCommitting = false;
11763 labelsInCurrentCommit.clear();
11764 endMark('(Committing Changes)', '(Committing Changes)', warning);
11765 }
11766}
11767function startCommitSnapshotEffectsTimer() {
11768 if (enableUserTimingAPI) {
11769 if (!supportsUserTiming) {
11770 return;
11771 }
11772
11773 effectCountInCurrentCommit = 0;
11774 beginMark('(Committing Snapshot Effects)');
11775 }
11776}
11777function stopCommitSnapshotEffectsTimer() {
11778 if (enableUserTimingAPI) {
11779 if (!supportsUserTiming) {
11780 return;
11781 }
11782
11783 var count = effectCountInCurrentCommit;
11784 effectCountInCurrentCommit = 0;
11785 endMark("(Committing Snapshot Effects: " + count + " Total)", '(Committing Snapshot Effects)', null);
11786 }
11787}
11788function startCommitHostEffectsTimer() {
11789 if (enableUserTimingAPI) {
11790 if (!supportsUserTiming) {
11791 return;
11792 }
11793
11794 effectCountInCurrentCommit = 0;
11795 beginMark('(Committing Host Effects)');
11796 }
11797}
11798function stopCommitHostEffectsTimer() {
11799 if (enableUserTimingAPI) {
11800 if (!supportsUserTiming) {
11801 return;
11802 }
11803
11804 var count = effectCountInCurrentCommit;
11805 effectCountInCurrentCommit = 0;
11806 endMark("(Committing Host Effects: " + count + " Total)", '(Committing Host Effects)', null);
11807 }
11808}
11809function startCommitLifeCyclesTimer() {
11810 if (enableUserTimingAPI) {
11811 if (!supportsUserTiming) {
11812 return;
11813 }
11814
11815 effectCountInCurrentCommit = 0;
11816 beginMark('(Calling Lifecycle Methods)');
11817 }
11818}
11819function stopCommitLifeCyclesTimer() {
11820 if (enableUserTimingAPI) {
11821 if (!supportsUserTiming) {
11822 return;
11823 }
11824
11825 var count = effectCountInCurrentCommit;
11826 effectCountInCurrentCommit = 0;
11827 endMark("(Calling Lifecycle Methods: " + count + " Total)", '(Calling Lifecycle Methods)', null);
11828 }
11829}
11830
11831var valueStack = [];
11832var fiberStack;
11833
11834{
11835 fiberStack = [];
11836}
11837
11838var index = -1;
11839
11840function createCursor(defaultValue) {
11841 return {
11842 current: defaultValue
11843 };
11844}
11845
11846function pop(cursor, fiber) {
11847 if (index < 0) {
11848 {
11849 warningWithoutStack$1(false, 'Unexpected pop.');
11850 }
11851
11852 return;
11853 }
11854
11855 {
11856 if (fiber !== fiberStack[index]) {
11857 warningWithoutStack$1(false, 'Unexpected Fiber popped.');
11858 }
11859 }
11860
11861 cursor.current = valueStack[index];
11862 valueStack[index] = null;
11863
11864 {
11865 fiberStack[index] = null;
11866 }
11867
11868 index--;
11869}
11870
11871function push(cursor, value, fiber) {
11872 index++;
11873 valueStack[index] = cursor.current;
11874
11875 {
11876 fiberStack[index] = fiber;
11877 }
11878
11879 cursor.current = value;
11880}
11881
11882var warnedAboutMissingGetChildContext;
11883
11884{
11885 warnedAboutMissingGetChildContext = {};
11886}
11887
11888var emptyContextObject = {};
11889
11890{
11891 Object.freeze(emptyContextObject);
11892} // A cursor to the current merged context object on the stack.
11893
11894
11895var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
11896
11897var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
11898// We use this to get access to the parent context after we have already
11899// pushed the next context provider, and now need to merge their contexts.
11900
11901var previousContext = emptyContextObject;
11902
11903function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
11904 if (disableLegacyContext) {
11905 return emptyContextObject;
11906 } else {
11907 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
11908 // If the fiber is a context provider itself, when we read its context
11909 // we may have already pushed its own child context on the stack. A context
11910 // provider should not "see" its own child context. Therefore we read the
11911 // previous (parent) context instead for a context provider.
11912 return previousContext;
11913 }
11914
11915 return contextStackCursor.current;
11916 }
11917}
11918
11919function cacheContext(workInProgress, unmaskedContext, maskedContext) {
11920 if (disableLegacyContext) {
11921 return;
11922 } else {
11923 var instance = workInProgress.stateNode;
11924 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
11925 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
11926 }
11927}
11928
11929function getMaskedContext(workInProgress, unmaskedContext) {
11930 if (disableLegacyContext) {
11931 return emptyContextObject;
11932 } else {
11933 var type = workInProgress.type;
11934 var contextTypes = type.contextTypes;
11935
11936 if (!contextTypes) {
11937 return emptyContextObject;
11938 } // Avoid recreating masked context unless unmasked context has changed.
11939 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
11940 // This may trigger infinite loops if componentWillReceiveProps calls setState.
11941
11942
11943 var instance = workInProgress.stateNode;
11944
11945 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
11946 return instance.__reactInternalMemoizedMaskedChildContext;
11947 }
11948
11949 var context = {};
11950
11951 for (var key in contextTypes) {
11952 context[key] = unmaskedContext[key];
11953 }
11954
11955 {
11956 var name = getComponentName(type) || 'Unknown';
11957 checkPropTypes_1(contextTypes, context, 'context', name, getCurrentFiberStackInDev);
11958 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
11959 // Context is created before the class component is instantiated so check for instance.
11960
11961
11962 if (instance) {
11963 cacheContext(workInProgress, unmaskedContext, context);
11964 }
11965
11966 return context;
11967 }
11968}
11969
11970function hasContextChanged() {
11971 if (disableLegacyContext) {
11972 return false;
11973 } else {
11974 return didPerformWorkStackCursor.current;
11975 }
11976}
11977
11978function isContextProvider(type) {
11979 if (disableLegacyContext) {
11980 return false;
11981 } else {
11982 var childContextTypes = type.childContextTypes;
11983 return childContextTypes !== null && childContextTypes !== undefined;
11984 }
11985}
11986
11987function popContext(fiber) {
11988 if (disableLegacyContext) {
11989 return;
11990 } else {
11991 pop(didPerformWorkStackCursor, fiber);
11992 pop(contextStackCursor, fiber);
11993 }
11994}
11995
11996function popTopLevelContextObject(fiber) {
11997 if (disableLegacyContext) {
11998 return;
11999 } else {
12000 pop(didPerformWorkStackCursor, fiber);
12001 pop(contextStackCursor, fiber);
12002 }
12003}
12004
12005function pushTopLevelContextObject(fiber, context, didChange) {
12006 if (disableLegacyContext) {
12007 return;
12008 } else {
12009 if (!(contextStackCursor.current === emptyContextObject)) {
12010 {
12011 throw Error("Unexpected context found on stack. This error is likely caused by a bug in React. Please file an issue.");
12012 }
12013 }
12014
12015 push(contextStackCursor, context, fiber);
12016 push(didPerformWorkStackCursor, didChange, fiber);
12017 }
12018}
12019
12020function processChildContext(fiber, type, parentContext) {
12021 if (disableLegacyContext) {
12022 return parentContext;
12023 } else {
12024 var instance = fiber.stateNode;
12025 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
12026 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
12027
12028 if (typeof instance.getChildContext !== 'function') {
12029 {
12030 var componentName = getComponentName(type) || 'Unknown';
12031
12032 if (!warnedAboutMissingGetChildContext[componentName]) {
12033 warnedAboutMissingGetChildContext[componentName] = true;
12034 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);
12035 }
12036 }
12037
12038 return parentContext;
12039 }
12040
12041 var childContext;
12042
12043 {
12044 setCurrentPhase('getChildContext');
12045 }
12046
12047 startPhaseTimer(fiber, 'getChildContext');
12048 childContext = instance.getChildContext();
12049 stopPhaseTimer();
12050
12051 {
12052 setCurrentPhase(null);
12053 }
12054
12055 for (var contextKey in childContext) {
12056 if (!(contextKey in childContextTypes)) {
12057 {
12058 throw Error((getComponentName(type) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes.");
12059 }
12060 }
12061 }
12062
12063 {
12064 var name = getComponentName(type) || 'Unknown';
12065 checkPropTypes_1(childContextTypes, childContext, 'child context', name, // In practice, there is one case in which we won't get a stack. It's when
12066 // somebody calls unstable_renderSubtreeIntoContainer() and we process
12067 // context from the parent component instance. The stack will be missing
12068 // because it's outside of the reconciliation, and so the pointer has not
12069 // been set. This is rare and doesn't matter. We'll also remove that API.
12070 getCurrentFiberStackInDev);
12071 }
12072
12073 return _assign({}, parentContext, {}, childContext);
12074 }
12075}
12076
12077function pushContextProvider(workInProgress) {
12078 if (disableLegacyContext) {
12079 return false;
12080 } else {
12081 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
12082 // If the instance does not exist yet, we will push null at first,
12083 // and replace it on the stack later when invalidating the context.
12084
12085 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
12086 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
12087
12088 previousContext = contextStackCursor.current;
12089 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
12090 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
12091 return true;
12092 }
12093}
12094
12095function invalidateContextProvider(workInProgress, type, didChange) {
12096 if (disableLegacyContext) {
12097 return;
12098 } else {
12099 var instance = workInProgress.stateNode;
12100
12101 if (!instance) {
12102 {
12103 throw Error("Expected to have an instance by this point. This error is likely caused by a bug in React. Please file an issue.");
12104 }
12105 }
12106
12107 if (didChange) {
12108 // Merge parent and own context.
12109 // Skip this if we're not updating due to sCU.
12110 // This avoids unnecessarily recomputing memoized values.
12111 var mergedContext = processChildContext(workInProgress, type, previousContext);
12112 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
12113 // It is important to unwind the context in the reverse order.
12114
12115 pop(didPerformWorkStackCursor, workInProgress);
12116 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
12117
12118 push(contextStackCursor, mergedContext, workInProgress);
12119 push(didPerformWorkStackCursor, didChange, workInProgress);
12120 } else {
12121 pop(didPerformWorkStackCursor, workInProgress);
12122 push(didPerformWorkStackCursor, didChange, workInProgress);
12123 }
12124 }
12125}
12126
12127function findCurrentUnmaskedContext(fiber) {
12128 if (disableLegacyContext) {
12129 return emptyContextObject;
12130 } else {
12131 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
12132 // makes sense elsewhere
12133 if (!(isFiberMounted(fiber) && fiber.tag === ClassComponent)) {
12134 {
12135 throw Error("Expected subtree parent to be a mounted class component. This error is likely caused by a bug in React. Please file an issue.");
12136 }
12137 }
12138
12139 var node = fiber;
12140
12141 do {
12142 switch (node.tag) {
12143 case HostRoot:
12144 return node.stateNode.context;
12145
12146 case ClassComponent:
12147 {
12148 var Component = node.type;
12149
12150 if (isContextProvider(Component)) {
12151 return node.stateNode.__reactInternalMemoizedMergedChildContext;
12152 }
12153
12154 break;
12155 }
12156 }
12157
12158 node = node.return;
12159 } while (node !== null);
12160
12161 {
12162 {
12163 throw Error("Found unexpected detached subtree parent. This error is likely caused by a bug in React. Please file an issue.");
12164 }
12165 }
12166 }
12167}
12168
12169var LegacyRoot = 0;
12170var BlockingRoot = 1;
12171var ConcurrentRoot = 2;
12172
12173var ReactInternals$2 = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
12174var _ReactInternals$Sched$1 = ReactInternals$2.SchedulerTracing;
12175var __interactionsRef = _ReactInternals$Sched$1.__interactionsRef;
12176var __subscriberRef = _ReactInternals$Sched$1.__subscriberRef;
12177var unstable_clear = _ReactInternals$Sched$1.unstable_clear;
12178var unstable_getCurrent = _ReactInternals$Sched$1.unstable_getCurrent;
12179var unstable_getThreadID = _ReactInternals$Sched$1.unstable_getThreadID;
12180var unstable_subscribe = _ReactInternals$Sched$1.unstable_subscribe;
12181var unstable_trace = _ReactInternals$Sched$1.unstable_trace;
12182var unstable_unsubscribe = _ReactInternals$Sched$1.unstable_unsubscribe;
12183var unstable_wrap = _ReactInternals$Sched$1.unstable_wrap;
12184
12185// Intentionally not named imports because Rollup would use dynamic dispatch for
12186// CommonJS interop named imports.
12187var Scheduler_runWithPriority = unstable_runWithPriority;
12188var Scheduler_scheduleCallback = unstable_scheduleCallback;
12189var Scheduler_cancelCallback = unstable_cancelCallback;
12190var Scheduler_shouldYield = unstable_shouldYield;
12191var Scheduler_requestPaint = unstable_requestPaint;
12192var Scheduler_now = unstable_now;
12193var Scheduler_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
12194var Scheduler_ImmediatePriority = unstable_ImmediatePriority;
12195var Scheduler_UserBlockingPriority = unstable_UserBlockingPriority;
12196var Scheduler_NormalPriority = unstable_NormalPriority;
12197var Scheduler_LowPriority = unstable_LowPriority;
12198var Scheduler_IdlePriority = unstable_IdlePriority;
12199
12200if (enableSchedulerTracing) {
12201 // Provide explicit error message when production+profiling bundle of e.g.
12202 // react-dom is used with production (non-profiling) bundle of
12203 // scheduler/tracing
12204 if (!(__interactionsRef != null && __interactionsRef.current != null)) {
12205 {
12206 throw Error("It is not supported to run the profiling version of a renderer (for example, `react-dom/profiling`) without also replacing the `scheduler/tracing` module with `scheduler/tracing-profiling`. Your bundler might have a setting for aliasing both modules. Learn more at http://fb.me/react-profiling");
12207 }
12208 }
12209}
12210
12211var fakeCallbackNode = {}; // Except for NoPriority, these correspond to Scheduler priorities. We use
12212// ascending numbers so we can compare them like numbers. They start at 90 to
12213// avoid clashing with Scheduler's priorities.
12214
12215var ImmediatePriority = 99;
12216var UserBlockingPriority$2 = 98;
12217var NormalPriority = 97;
12218var LowPriority = 96;
12219var IdlePriority = 95; // NoPriority is the absence of priority. Also React-only.
12220
12221var NoPriority = 90;
12222var shouldYield = Scheduler_shouldYield;
12223var requestPaint = // Fall back gracefully if we're running an older version of Scheduler.
12224Scheduler_requestPaint !== undefined ? Scheduler_requestPaint : function () {};
12225var syncQueue = null;
12226var immediateQueueCallbackNode = null;
12227var isFlushingSyncQueue = false;
12228var initialTimeMs = Scheduler_now(); // If the initial timestamp is reasonably small, use Scheduler's `now` directly.
12229// This will be the case for modern browsers that support `performance.now`. In
12230// older browsers, Scheduler falls back to `Date.now`, which returns a Unix
12231// timestamp. In that case, subtract the module initialization time to simulate
12232// the behavior of performance.now and keep our times small enough to fit
12233// within 32 bits.
12234// TODO: Consider lifting this into Scheduler.
12235
12236var now = initialTimeMs < 10000 ? Scheduler_now : function () {
12237 return Scheduler_now() - initialTimeMs;
12238};
12239function getCurrentPriorityLevel() {
12240 switch (Scheduler_getCurrentPriorityLevel()) {
12241 case Scheduler_ImmediatePriority:
12242 return ImmediatePriority;
12243
12244 case Scheduler_UserBlockingPriority:
12245 return UserBlockingPriority$2;
12246
12247 case Scheduler_NormalPriority:
12248 return NormalPriority;
12249
12250 case Scheduler_LowPriority:
12251 return LowPriority;
12252
12253 case Scheduler_IdlePriority:
12254 return IdlePriority;
12255
12256 default:
12257 {
12258 {
12259 throw Error("Unknown priority level.");
12260 }
12261 }
12262
12263 }
12264}
12265
12266function reactPriorityToSchedulerPriority(reactPriorityLevel) {
12267 switch (reactPriorityLevel) {
12268 case ImmediatePriority:
12269 return Scheduler_ImmediatePriority;
12270
12271 case UserBlockingPriority$2:
12272 return Scheduler_UserBlockingPriority;
12273
12274 case NormalPriority:
12275 return Scheduler_NormalPriority;
12276
12277 case LowPriority:
12278 return Scheduler_LowPriority;
12279
12280 case IdlePriority:
12281 return Scheduler_IdlePriority;
12282
12283 default:
12284 {
12285 {
12286 throw Error("Unknown priority level.");
12287 }
12288 }
12289
12290 }
12291}
12292
12293function runWithPriority$2(reactPriorityLevel, fn) {
12294 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
12295 return Scheduler_runWithPriority(priorityLevel, fn);
12296}
12297function scheduleCallback(reactPriorityLevel, callback, options) {
12298 var priorityLevel = reactPriorityToSchedulerPriority(reactPriorityLevel);
12299 return Scheduler_scheduleCallback(priorityLevel, callback, options);
12300}
12301function scheduleSyncCallback(callback) {
12302 // Push this callback into an internal queue. We'll flush these either in
12303 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
12304 if (syncQueue === null) {
12305 syncQueue = [callback]; // Flush the queue in the next tick, at the earliest.
12306
12307 immediateQueueCallbackNode = Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueueImpl);
12308 } else {
12309 // Push onto existing queue. Don't need to schedule a callback because
12310 // we already scheduled one when we created the queue.
12311 syncQueue.push(callback);
12312 }
12313
12314 return fakeCallbackNode;
12315}
12316function cancelCallback(callbackNode) {
12317 if (callbackNode !== fakeCallbackNode) {
12318 Scheduler_cancelCallback(callbackNode);
12319 }
12320}
12321function flushSyncCallbackQueue() {
12322 if (immediateQueueCallbackNode !== null) {
12323 var node = immediateQueueCallbackNode;
12324 immediateQueueCallbackNode = null;
12325 Scheduler_cancelCallback(node);
12326 }
12327
12328 flushSyncCallbackQueueImpl();
12329}
12330
12331function flushSyncCallbackQueueImpl() {
12332 if (!isFlushingSyncQueue && syncQueue !== null) {
12333 // Prevent re-entrancy.
12334 isFlushingSyncQueue = true;
12335 var i = 0;
12336
12337 try {
12338 var _isSync = true;
12339 var queue = syncQueue;
12340 runWithPriority$2(ImmediatePriority, function () {
12341 for (; i < queue.length; i++) {
12342 var callback = queue[i];
12343
12344 do {
12345 callback = callback(_isSync);
12346 } while (callback !== null);
12347 }
12348 });
12349 syncQueue = null;
12350 } catch (error) {
12351 // If something throws, leave the remaining callbacks on the queue.
12352 if (syncQueue !== null) {
12353 syncQueue = syncQueue.slice(i + 1);
12354 } // Resume flushing in the next tick
12355
12356
12357 Scheduler_scheduleCallback(Scheduler_ImmediatePriority, flushSyncCallbackQueue);
12358 throw error;
12359 } finally {
12360 isFlushingSyncQueue = false;
12361 }
12362 }
12363}
12364
12365var NoMode = 0;
12366var StrictMode = 1; // TODO: Remove BlockingMode and ConcurrentMode by reading from the root
12367// tag instead
12368
12369var BlockingMode = 2;
12370var ConcurrentMode = 4;
12371var ProfileMode = 8;
12372
12373// Max 31 bit integer. The max integer size in V8 for 32-bit systems.
12374// Math.pow(2, 30) - 1
12375// 0b111111111111111111111111111111
12376var MAX_SIGNED_31_BIT_INT = 1073741823;
12377
12378var NoWork = 0; // TODO: Think of a better name for Never. The key difference with Idle is that
12379// Never work can be committed in an inconsistent state without tearing the UI.
12380// The main example is offscreen content, like a hidden subtree. So one possible
12381// name is Offscreen. However, it also includes dehydrated Suspense boundaries,
12382// which are inconsistent in the sense that they haven't finished yet, but
12383// aren't visibly inconsistent because the server rendered HTML matches what the
12384// hydrated tree would look like.
12385
12386var Never = 1; // Idle is slightly higher priority than Never. It must completely finish in
12387// order to be consistent.
12388
12389var Idle = 2; // Continuous Hydration is a moving priority. It is slightly higher than Idle
12390// and is used to increase priority of hover targets. It is increasing with
12391// each usage so that last always wins.
12392
12393var ContinuousHydration = 3;
12394var Sync = MAX_SIGNED_31_BIT_INT;
12395var Batched = Sync - 1;
12396var UNIT_SIZE = 10;
12397var MAGIC_NUMBER_OFFSET = Batched - 1; // 1 unit of expiration time represents 10ms.
12398
12399function msToExpirationTime(ms) {
12400 // Always add an offset so that we don't clash with the magic number for NoWork.
12401 return MAGIC_NUMBER_OFFSET - (ms / UNIT_SIZE | 0);
12402}
12403function expirationTimeToMs(expirationTime) {
12404 return (MAGIC_NUMBER_OFFSET - expirationTime) * UNIT_SIZE;
12405}
12406
12407function ceiling(num, precision) {
12408 return ((num / precision | 0) + 1) * precision;
12409}
12410
12411function computeExpirationBucket(currentTime, expirationInMs, bucketSizeMs) {
12412 return MAGIC_NUMBER_OFFSET - ceiling(MAGIC_NUMBER_OFFSET - currentTime + expirationInMs / UNIT_SIZE, bucketSizeMs / UNIT_SIZE);
12413} // TODO: This corresponds to Scheduler's NormalPriority, not LowPriority. Update
12414// the names to reflect.
12415
12416
12417var LOW_PRIORITY_EXPIRATION = 5000;
12418var LOW_PRIORITY_BATCH_SIZE = 250;
12419function computeAsyncExpiration(currentTime) {
12420 return computeExpirationBucket(currentTime, LOW_PRIORITY_EXPIRATION, LOW_PRIORITY_BATCH_SIZE);
12421}
12422function computeSuspenseExpiration(currentTime, timeoutMs) {
12423 // TODO: Should we warn if timeoutMs is lower than the normal pri expiration time?
12424 return computeExpirationBucket(currentTime, timeoutMs, LOW_PRIORITY_BATCH_SIZE);
12425} // We intentionally set a higher expiration time for interactive updates in
12426// dev than in production.
12427//
12428// If the main thread is being blocked so long that you hit the expiration,
12429// it's a problem that could be solved with better scheduling.
12430//
12431// People will be more likely to notice this and fix it with the long
12432// expiration time in development.
12433//
12434// In production we opt for better UX at the risk of masking scheduling
12435// problems, by expiring fast.
12436
12437var HIGH_PRIORITY_EXPIRATION = 500;
12438var HIGH_PRIORITY_BATCH_SIZE = 100;
12439function computeInteractiveExpiration(currentTime) {
12440 return computeExpirationBucket(currentTime, HIGH_PRIORITY_EXPIRATION, HIGH_PRIORITY_BATCH_SIZE);
12441}
12442function computeContinuousHydrationExpiration(currentTime) {
12443 // Each time we ask for a new one of these we increase the priority.
12444 // This ensures that the last one always wins since we can't deprioritize
12445 // once we've scheduled work already.
12446 return ContinuousHydration++;
12447}
12448function inferPriorityFromExpirationTime(currentTime, expirationTime) {
12449 if (expirationTime === Sync) {
12450 return ImmediatePriority;
12451 }
12452
12453 if (expirationTime === Never || expirationTime === Idle) {
12454 return IdlePriority;
12455 }
12456
12457 var msUntil = expirationTimeToMs(expirationTime) - expirationTimeToMs(currentTime);
12458
12459 if (msUntil <= 0) {
12460 return ImmediatePriority;
12461 }
12462
12463 if (msUntil <= HIGH_PRIORITY_EXPIRATION + HIGH_PRIORITY_BATCH_SIZE) {
12464 return UserBlockingPriority$2;
12465 }
12466
12467 if (msUntil <= LOW_PRIORITY_EXPIRATION + LOW_PRIORITY_BATCH_SIZE) {
12468 return NormalPriority;
12469 } // TODO: Handle LowPriority
12470 // Assume anything lower has idle priority
12471
12472
12473 return IdlePriority;
12474}
12475
12476/**
12477 * Forked from fbjs/warning:
12478 * https://github.com/facebook/fbjs/blob/e66ba20ad5be433eb54423f2b097d829324d9de6/packages/fbjs/src/__forks__/warning.js
12479 *
12480 * Only change is we use console.warn instead of console.error,
12481 * and do nothing when 'console' is not supported.
12482 * This really simplifies the code.
12483 * ---
12484 * Similar to invariant but only logs a warning if the condition is not met.
12485 * This can be used to log issues in development environments in critical
12486 * paths. Removing the logging code for production environments will keep the
12487 * same logic and follow the same code paths.
12488 */
12489var lowPriorityWarningWithoutStack = function () {};
12490
12491{
12492 var printWarning$1 = function (format) {
12493 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
12494 args[_key - 1] = arguments[_key];
12495 }
12496
12497 var argIndex = 0;
12498 var message = 'Warning: ' + format.replace(/%s/g, function () {
12499 return args[argIndex++];
12500 });
12501
12502 if (typeof console !== 'undefined') {
12503 console.warn(message);
12504 }
12505
12506 try {
12507 // --- Welcome to debugging React ---
12508 // This error was thrown as a convenience so that you can use this stack
12509 // to find the callsite that caused this warning to fire.
12510 throw new Error(message);
12511 } catch (x) {}
12512 };
12513
12514 lowPriorityWarningWithoutStack = function (condition, format) {
12515 if (format === undefined) {
12516 throw new Error('`lowPriorityWarningWithoutStack(condition, format, ...args)` requires a warning ' + 'message argument');
12517 }
12518
12519 if (!condition) {
12520 for (var _len2 = arguments.length, args = new Array(_len2 > 2 ? _len2 - 2 : 0), _key2 = 2; _key2 < _len2; _key2++) {
12521 args[_key2 - 2] = arguments[_key2];
12522 }
12523
12524 printWarning$1.apply(void 0, [format].concat(args));
12525 }
12526 };
12527}
12528
12529var lowPriorityWarningWithoutStack$1 = lowPriorityWarningWithoutStack;
12530
12531var ReactStrictModeWarnings = {
12532 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
12533 flushPendingUnsafeLifecycleWarnings: function () {},
12534 recordLegacyContextWarning: function (fiber, instance) {},
12535 flushLegacyContextWarning: function () {},
12536 discardPendingWarnings: function () {}
12537};
12538
12539{
12540 var findStrictRoot = function (fiber) {
12541 var maybeStrictRoot = null;
12542 var node = fiber;
12543
12544 while (node !== null) {
12545 if (node.mode & StrictMode) {
12546 maybeStrictRoot = node;
12547 }
12548
12549 node = node.return;
12550 }
12551
12552 return maybeStrictRoot;
12553 };
12554
12555 var setToSortedString = function (set) {
12556 var array = [];
12557 set.forEach(function (value) {
12558 array.push(value);
12559 });
12560 return array.sort().join(', ');
12561 };
12562
12563 var pendingComponentWillMountWarnings = [];
12564 var pendingUNSAFE_ComponentWillMountWarnings = [];
12565 var pendingComponentWillReceivePropsWarnings = [];
12566 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12567 var pendingComponentWillUpdateWarnings = [];
12568 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
12569
12570 var didWarnAboutUnsafeLifecycles = new Set();
12571
12572 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
12573 // Dedup strategy: Warn once per component.
12574 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
12575 return;
12576 }
12577
12578 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
12579 instance.componentWillMount.__suppressDeprecationWarning !== true) {
12580 pendingComponentWillMountWarnings.push(fiber);
12581 }
12582
12583 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillMount === 'function') {
12584 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
12585 }
12586
12587 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12588 pendingComponentWillReceivePropsWarnings.push(fiber);
12589 }
12590
12591 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12592 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
12593 }
12594
12595 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12596 pendingComponentWillUpdateWarnings.push(fiber);
12597 }
12598
12599 if (fiber.mode & StrictMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
12600 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
12601 }
12602 };
12603
12604 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
12605 // We do an initial pass to gather component names
12606 var componentWillMountUniqueNames = new Set();
12607
12608 if (pendingComponentWillMountWarnings.length > 0) {
12609 pendingComponentWillMountWarnings.forEach(function (fiber) {
12610 componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
12611 didWarnAboutUnsafeLifecycles.add(fiber.type);
12612 });
12613 pendingComponentWillMountWarnings = [];
12614 }
12615
12616 var UNSAFE_componentWillMountUniqueNames = new Set();
12617
12618 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
12619 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
12620 UNSAFE_componentWillMountUniqueNames.add(getComponentName(fiber.type) || 'Component');
12621 didWarnAboutUnsafeLifecycles.add(fiber.type);
12622 });
12623 pendingUNSAFE_ComponentWillMountWarnings = [];
12624 }
12625
12626 var componentWillReceivePropsUniqueNames = new Set();
12627
12628 if (pendingComponentWillReceivePropsWarnings.length > 0) {
12629 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
12630 componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
12631 didWarnAboutUnsafeLifecycles.add(fiber.type);
12632 });
12633 pendingComponentWillReceivePropsWarnings = [];
12634 }
12635
12636 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
12637
12638 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
12639 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
12640 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentName(fiber.type) || 'Component');
12641 didWarnAboutUnsafeLifecycles.add(fiber.type);
12642 });
12643 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12644 }
12645
12646 var componentWillUpdateUniqueNames = new Set();
12647
12648 if (pendingComponentWillUpdateWarnings.length > 0) {
12649 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
12650 componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
12651 didWarnAboutUnsafeLifecycles.add(fiber.type);
12652 });
12653 pendingComponentWillUpdateWarnings = [];
12654 }
12655
12656 var UNSAFE_componentWillUpdateUniqueNames = new Set();
12657
12658 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
12659 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
12660 UNSAFE_componentWillUpdateUniqueNames.add(getComponentName(fiber.type) || 'Component');
12661 didWarnAboutUnsafeLifecycles.add(fiber.type);
12662 });
12663 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12664 } // Finally, we flush all the warnings
12665 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
12666
12667
12668 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
12669 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
12670 warningWithoutStack$1(false, 'Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '\nPlease update the following components: %s', sortedNames);
12671 }
12672
12673 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
12674 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
12675
12676 warningWithoutStack$1(false, 'Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, " + 'refactor your code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
12677 }
12678
12679 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
12680 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
12681
12682 warningWithoutStack$1(false, 'Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
12683 }
12684
12685 if (componentWillMountUniqueNames.size > 0) {
12686 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
12687
12688 lowPriorityWarningWithoutStack$1(false, 'componentWillMount has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move code with side effects to componentDidMount, and set initial state in the constructor.\n' + '* Rename componentWillMount to UNSAFE_componentWillMount to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames3);
12689 }
12690
12691 if (componentWillReceivePropsUniqueNames.size > 0) {
12692 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
12693
12694 lowPriorityWarningWithoutStack$1(false, 'componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + "* If you're updating state whenever props change, refactor your " + 'code to use memoization techniques or move it to ' + 'static getDerivedStateFromProps. Learn more at: https://fb.me/react-derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames4);
12695 }
12696
12697 if (componentWillUpdateUniqueNames.size > 0) {
12698 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
12699
12700 lowPriorityWarningWithoutStack$1(false, 'componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://fb.me/react-unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '* Rename componentWillUpdate to UNSAFE_componentWillUpdate to suppress ' + 'this warning in non-strict mode. In React 17.x, only the UNSAFE_ name will work. ' + 'To rename all deprecated lifecycles to their new names, you can run ' + '`npx react-codemod rename-unsafe-lifecycles` in your project source folder.\n' + '\nPlease update the following components: %s', _sortedNames5);
12701 }
12702 };
12703
12704 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
12705
12706 var didWarnAboutLegacyContext = new Set();
12707
12708 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
12709 var strictRoot = findStrictRoot(fiber);
12710
12711 if (strictRoot === null) {
12712 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.');
12713 return;
12714 } // Dedup strategy: Warn once per component.
12715
12716
12717 if (didWarnAboutLegacyContext.has(fiber.type)) {
12718 return;
12719 }
12720
12721 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
12722
12723 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
12724 if (warningsForRoot === undefined) {
12725 warningsForRoot = [];
12726 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
12727 }
12728
12729 warningsForRoot.push(fiber);
12730 }
12731 };
12732
12733 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
12734 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
12735 var uniqueNames = new Set();
12736 fiberArray.forEach(function (fiber) {
12737 uniqueNames.add(getComponentName(fiber.type) || 'Component');
12738 didWarnAboutLegacyContext.add(fiber.type);
12739 });
12740 var sortedNames = setToSortedString(uniqueNames);
12741 var strictRootComponentStack = getStackByFiberInDevAndProd(strictRoot);
12742 warningWithoutStack$1(false, 'Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://fb.me/react-legacy-context' + '%s', sortedNames, strictRootComponentStack);
12743 });
12744 };
12745
12746 ReactStrictModeWarnings.discardPendingWarnings = function () {
12747 pendingComponentWillMountWarnings = [];
12748 pendingUNSAFE_ComponentWillMountWarnings = [];
12749 pendingComponentWillReceivePropsWarnings = [];
12750 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12751 pendingComponentWillUpdateWarnings = [];
12752 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12753 pendingLegacyContextWarning = new Map();
12754 };
12755}
12756
12757var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
12758
12759var failedBoundaries = null;
12760var setRefreshHandler = function (handler) {
12761 {
12762 resolveFamily = handler;
12763 }
12764};
12765function resolveFunctionForHotReloading(type) {
12766 {
12767 if (resolveFamily === null) {
12768 // Hot reloading is disabled.
12769 return type;
12770 }
12771
12772 var family = resolveFamily(type);
12773
12774 if (family === undefined) {
12775 return type;
12776 } // Use the latest known implementation.
12777
12778
12779 return family.current;
12780 }
12781}
12782function resolveClassForHotReloading(type) {
12783 // No implementation differences.
12784 return resolveFunctionForHotReloading(type);
12785}
12786function resolveForwardRefForHotReloading(type) {
12787 {
12788 if (resolveFamily === null) {
12789 // Hot reloading is disabled.
12790 return type;
12791 }
12792
12793 var family = resolveFamily(type);
12794
12795 if (family === undefined) {
12796 // Check if we're dealing with a real forwardRef. Don't want to crash early.
12797 if (type !== null && type !== undefined && typeof type.render === 'function') {
12798 // ForwardRef is special because its resolved .type is an object,
12799 // but it's possible that we only have its inner render function in the map.
12800 // If that inner render function is different, we'll build a new forwardRef type.
12801 var currentRender = resolveFunctionForHotReloading(type.render);
12802
12803 if (type.render !== currentRender) {
12804 var syntheticType = {
12805 $$typeof: REACT_FORWARD_REF_TYPE,
12806 render: currentRender
12807 };
12808
12809 if (type.displayName !== undefined) {
12810 syntheticType.displayName = type.displayName;
12811 }
12812
12813 return syntheticType;
12814 }
12815 }
12816
12817 return type;
12818 } // Use the latest known implementation.
12819
12820
12821 return family.current;
12822 }
12823}
12824function isCompatibleFamilyForHotReloading(fiber, element) {
12825 {
12826 if (resolveFamily === null) {
12827 // Hot reloading is disabled.
12828 return false;
12829 }
12830
12831 var prevType = fiber.elementType;
12832 var nextType = element.type; // If we got here, we know types aren't === equal.
12833
12834 var needsCompareFamilies = false;
12835 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
12836
12837 switch (fiber.tag) {
12838 case ClassComponent:
12839 {
12840 if (typeof nextType === 'function') {
12841 needsCompareFamilies = true;
12842 }
12843
12844 break;
12845 }
12846
12847 case FunctionComponent:
12848 {
12849 if (typeof nextType === 'function') {
12850 needsCompareFamilies = true;
12851 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
12852 // We don't know the inner type yet.
12853 // We're going to assume that the lazy inner type is stable,
12854 // and so it is sufficient to avoid reconciling it away.
12855 // We're not going to unwrap or actually use the new lazy type.
12856 needsCompareFamilies = true;
12857 }
12858
12859 break;
12860 }
12861
12862 case ForwardRef:
12863 {
12864 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
12865 needsCompareFamilies = true;
12866 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
12867 needsCompareFamilies = true;
12868 }
12869
12870 break;
12871 }
12872
12873 case MemoComponent:
12874 case SimpleMemoComponent:
12875 {
12876 if ($$typeofNextType === REACT_MEMO_TYPE) {
12877 // TODO: if it was but can no longer be simple,
12878 // we shouldn't set this.
12879 needsCompareFamilies = true;
12880 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
12881 needsCompareFamilies = true;
12882 }
12883
12884 break;
12885 }
12886
12887 default:
12888 return false;
12889 } // Check if both types have a family and it's the same one.
12890
12891
12892 if (needsCompareFamilies) {
12893 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
12894 // This means both of them need to be registered to preserve state.
12895 // If we unwrapped and compared the inner types for wrappers instead,
12896 // then we would risk falsely saying two separate memo(Foo)
12897 // calls are equivalent because they wrap the same Foo function.
12898 var prevFamily = resolveFamily(prevType);
12899
12900 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
12901 return true;
12902 }
12903 }
12904
12905 return false;
12906 }
12907}
12908function markFailedErrorBoundaryForHotReloading(fiber) {
12909 {
12910 if (resolveFamily === null) {
12911 // Hot reloading is disabled.
12912 return;
12913 }
12914
12915 if (typeof WeakSet !== 'function') {
12916 return;
12917 }
12918
12919 if (failedBoundaries === null) {
12920 failedBoundaries = new WeakSet();
12921 }
12922
12923 failedBoundaries.add(fiber);
12924 }
12925}
12926var scheduleRefresh = function (root, update) {
12927 {
12928 if (resolveFamily === null) {
12929 // Hot reloading is disabled.
12930 return;
12931 }
12932
12933 var staleFamilies = update.staleFamilies,
12934 updatedFamilies = update.updatedFamilies;
12935 flushPassiveEffects();
12936 flushSync(function () {
12937 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
12938 });
12939 }
12940};
12941var scheduleRoot = function (root, element) {
12942 {
12943 if (root.context !== emptyContextObject) {
12944 // Super edge case: root has a legacy _renderSubtree context
12945 // but we don't know the parentComponent so we can't pass it.
12946 // Just ignore. We'll delete this with _renderSubtree code path later.
12947 return;
12948 }
12949
12950 flushPassiveEffects();
12951 syncUpdates(function () {
12952 updateContainer(element, root, null, null);
12953 });
12954 }
12955};
12956
12957function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
12958 {
12959 var alternate = fiber.alternate,
12960 child = fiber.child,
12961 sibling = fiber.sibling,
12962 tag = fiber.tag,
12963 type = fiber.type;
12964 var candidateType = null;
12965
12966 switch (tag) {
12967 case FunctionComponent:
12968 case SimpleMemoComponent:
12969 case ClassComponent:
12970 candidateType = type;
12971 break;
12972
12973 case ForwardRef:
12974 candidateType = type.render;
12975 break;
12976
12977 default:
12978 break;
12979 }
12980
12981 if (resolveFamily === null) {
12982 throw new Error('Expected resolveFamily to be set during hot reload.');
12983 }
12984
12985 var needsRender = false;
12986 var needsRemount = false;
12987
12988 if (candidateType !== null) {
12989 var family = resolveFamily(candidateType);
12990
12991 if (family !== undefined) {
12992 if (staleFamilies.has(family)) {
12993 needsRemount = true;
12994 } else if (updatedFamilies.has(family)) {
12995 if (tag === ClassComponent) {
12996 needsRemount = true;
12997 } else {
12998 needsRender = true;
12999 }
13000 }
13001 }
13002 }
13003
13004 if (failedBoundaries !== null) {
13005 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
13006 needsRemount = true;
13007 }
13008 }
13009
13010 if (needsRemount) {
13011 fiber._debugNeedsRemount = true;
13012 }
13013
13014 if (needsRemount || needsRender) {
13015 scheduleWork(fiber, Sync);
13016 }
13017
13018 if (child !== null && !needsRemount) {
13019 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
13020 }
13021
13022 if (sibling !== null) {
13023 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
13024 }
13025 }
13026}
13027
13028var findHostInstancesForRefresh = function (root, families) {
13029 {
13030 var hostInstances = new Set();
13031 var types = new Set(families.map(function (family) {
13032 return family.current;
13033 }));
13034 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
13035 return hostInstances;
13036 }
13037};
13038
13039function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
13040 {
13041 var child = fiber.child,
13042 sibling = fiber.sibling,
13043 tag = fiber.tag,
13044 type = fiber.type;
13045 var candidateType = null;
13046
13047 switch (tag) {
13048 case FunctionComponent:
13049 case SimpleMemoComponent:
13050 case ClassComponent:
13051 candidateType = type;
13052 break;
13053
13054 case ForwardRef:
13055 candidateType = type.render;
13056 break;
13057
13058 default:
13059 break;
13060 }
13061
13062 var didMatch = false;
13063
13064 if (candidateType !== null) {
13065 if (types.has(candidateType)) {
13066 didMatch = true;
13067 }
13068 }
13069
13070 if (didMatch) {
13071 // We have a match. This only drills down to the closest host components.
13072 // There's no need to search deeper because for the purpose of giving
13073 // visual feedback, "flashing" outermost parent rectangles is sufficient.
13074 findHostInstancesForFiberShallowly(fiber, hostInstances);
13075 } else {
13076 // If there's no match, maybe there will be one further down in the child tree.
13077 if (child !== null) {
13078 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
13079 }
13080 }
13081
13082 if (sibling !== null) {
13083 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
13084 }
13085 }
13086}
13087
13088function findHostInstancesForFiberShallowly(fiber, hostInstances) {
13089 {
13090 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
13091
13092 if (foundHostInstances) {
13093 return;
13094 } // If we didn't find any host children, fallback to closest host parent.
13095
13096
13097 var node = fiber;
13098
13099 while (true) {
13100 switch (node.tag) {
13101 case HostComponent:
13102 hostInstances.add(node.stateNode);
13103 return;
13104
13105 case HostPortal:
13106 hostInstances.add(node.stateNode.containerInfo);
13107 return;
13108
13109 case HostRoot:
13110 hostInstances.add(node.stateNode.containerInfo);
13111 return;
13112 }
13113
13114 if (node.return === null) {
13115 throw new Error('Expected to reach root first.');
13116 }
13117
13118 node = node.return;
13119 }
13120 }
13121}
13122
13123function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
13124 {
13125 var node = fiber;
13126 var foundHostInstances = false;
13127
13128 while (true) {
13129 if (node.tag === HostComponent) {
13130 // We got a match.
13131 foundHostInstances = true;
13132 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
13133 } else if (node.child !== null) {
13134 node.child.return = node;
13135 node = node.child;
13136 continue;
13137 }
13138
13139 if (node === fiber) {
13140 return foundHostInstances;
13141 }
13142
13143 while (node.sibling === null) {
13144 if (node.return === null || node.return === fiber) {
13145 return foundHostInstances;
13146 }
13147
13148 node = node.return;
13149 }
13150
13151 node.sibling.return = node.return;
13152 node = node.sibling;
13153 }
13154 }
13155
13156 return false;
13157}
13158
13159function resolveDefaultProps(Component, baseProps) {
13160 if (Component && Component.defaultProps) {
13161 // Resolve default props. Taken from ReactElement
13162 var props = _assign({}, baseProps);
13163
13164 var defaultProps = Component.defaultProps;
13165
13166 for (var propName in defaultProps) {
13167 if (props[propName] === undefined) {
13168 props[propName] = defaultProps[propName];
13169 }
13170 }
13171
13172 return props;
13173 }
13174
13175 return baseProps;
13176}
13177function readLazyComponentType(lazyComponent) {
13178 initializeLazyComponentType(lazyComponent);
13179
13180 if (lazyComponent._status !== Resolved) {
13181 throw lazyComponent._result;
13182 }
13183
13184 return lazyComponent._result;
13185}
13186
13187var valueCursor = createCursor(null);
13188var rendererSigil;
13189
13190{
13191 // Use this to detect multiple renderers using the same context
13192 rendererSigil = {};
13193}
13194
13195var currentlyRenderingFiber = null;
13196var lastContextDependency = null;
13197var lastContextWithAllBitsObserved = null;
13198var isDisallowedContextReadInDEV = false;
13199function resetContextDependencies() {
13200 // This is called right before React yields execution, to ensure `readContext`
13201 // cannot be called outside the render phase.
13202 currentlyRenderingFiber = null;
13203 lastContextDependency = null;
13204 lastContextWithAllBitsObserved = null;
13205
13206 {
13207 isDisallowedContextReadInDEV = false;
13208 }
13209}
13210function enterDisallowedContextReadInDEV() {
13211 {
13212 isDisallowedContextReadInDEV = true;
13213 }
13214}
13215function exitDisallowedContextReadInDEV() {
13216 {
13217 isDisallowedContextReadInDEV = false;
13218 }
13219}
13220function pushProvider(providerFiber, nextValue) {
13221 var context = providerFiber.type._context;
13222
13223 if (isPrimaryRenderer) {
13224 push(valueCursor, context._currentValue, providerFiber);
13225 context._currentValue = nextValue;
13226
13227 {
13228 !(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;
13229 context._currentRenderer = rendererSigil;
13230 }
13231 } else {
13232 push(valueCursor, context._currentValue2, providerFiber);
13233 context._currentValue2 = nextValue;
13234
13235 {
13236 !(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;
13237 context._currentRenderer2 = rendererSigil;
13238 }
13239 }
13240}
13241function popProvider(providerFiber) {
13242 var currentValue = valueCursor.current;
13243 pop(valueCursor, providerFiber);
13244 var context = providerFiber.type._context;
13245
13246 if (isPrimaryRenderer) {
13247 context._currentValue = currentValue;
13248 } else {
13249 context._currentValue2 = currentValue;
13250 }
13251}
13252function calculateChangedBits(context, newValue, oldValue) {
13253 if (is$1(oldValue, newValue)) {
13254 // No change
13255 return 0;
13256 } else {
13257 var changedBits = typeof context._calculateChangedBits === 'function' ? context._calculateChangedBits(oldValue, newValue) : MAX_SIGNED_31_BIT_INT;
13258
13259 {
13260 !((changedBits & MAX_SIGNED_31_BIT_INT) === changedBits) ? warning$1(false, 'calculateChangedBits: Expected the return value to be a ' + '31-bit integer. Instead received: %s', changedBits) : void 0;
13261 }
13262
13263 return changedBits | 0;
13264 }
13265}
13266function scheduleWorkOnParentPath(parent, renderExpirationTime) {
13267 // Update the child expiration time of all the ancestors, including
13268 // the alternates.
13269 var node = parent;
13270
13271 while (node !== null) {
13272 var alternate = node.alternate;
13273
13274 if (node.childExpirationTime < renderExpirationTime) {
13275 node.childExpirationTime = renderExpirationTime;
13276
13277 if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
13278 alternate.childExpirationTime = renderExpirationTime;
13279 }
13280 } else if (alternate !== null && alternate.childExpirationTime < renderExpirationTime) {
13281 alternate.childExpirationTime = renderExpirationTime;
13282 } else {
13283 // Neither alternate was updated, which means the rest of the
13284 // ancestor path already has sufficient priority.
13285 break;
13286 }
13287
13288 node = node.return;
13289 }
13290}
13291function propagateContextChange(workInProgress, context, changedBits, renderExpirationTime) {
13292 var fiber = workInProgress.child;
13293
13294 if (fiber !== null) {
13295 // Set the return pointer of the child to the work-in-progress fiber.
13296 fiber.return = workInProgress;
13297 }
13298
13299 while (fiber !== null) {
13300 var nextFiber = void 0; // Visit this fiber.
13301
13302 var list = fiber.dependencies;
13303
13304 if (list !== null) {
13305 nextFiber = fiber.child;
13306 var dependency = list.firstContext;
13307
13308 while (dependency !== null) {
13309 // Check if the context matches.
13310 if (dependency.context === context && (dependency.observedBits & changedBits) !== 0) {
13311 // Match! Schedule an update on this fiber.
13312 if (fiber.tag === ClassComponent) {
13313 // Schedule a force update on the work-in-progress.
13314 var update = createUpdate(renderExpirationTime, null);
13315 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
13316 // update to the current fiber, too, which means it will persist even if
13317 // this render is thrown away. Since it's a race condition, not sure it's
13318 // worth fixing.
13319
13320 enqueueUpdate(fiber, update);
13321 }
13322
13323 if (fiber.expirationTime < renderExpirationTime) {
13324 fiber.expirationTime = renderExpirationTime;
13325 }
13326
13327 var alternate = fiber.alternate;
13328
13329 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
13330 alternate.expirationTime = renderExpirationTime;
13331 }
13332
13333 scheduleWorkOnParentPath(fiber.return, renderExpirationTime); // Mark the expiration time on the list, too.
13334
13335 if (list.expirationTime < renderExpirationTime) {
13336 list.expirationTime = renderExpirationTime;
13337 } // Since we already found a match, we can stop traversing the
13338 // dependency list.
13339
13340
13341 break;
13342 }
13343
13344 dependency = dependency.next;
13345 }
13346 } else if (fiber.tag === ContextProvider) {
13347 // Don't scan deeper if this is a matching provider
13348 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
13349 } else if (enableSuspenseServerRenderer && fiber.tag === DehydratedFragment) {
13350 // If a dehydrated suspense bounudary is in this subtree, we don't know
13351 // if it will have any context consumers in it. The best we can do is
13352 // mark it as having updates.
13353 var parentSuspense = fiber.return;
13354
13355 if (!(parentSuspense !== null)) {
13356 {
13357 throw Error("We just came from a parent so we must have had a parent. This is a bug in React.");
13358 }
13359 }
13360
13361 if (parentSuspense.expirationTime < renderExpirationTime) {
13362 parentSuspense.expirationTime = renderExpirationTime;
13363 }
13364
13365 var _alternate = parentSuspense.alternate;
13366
13367 if (_alternate !== null && _alternate.expirationTime < renderExpirationTime) {
13368 _alternate.expirationTime = renderExpirationTime;
13369 } // This is intentionally passing this fiber as the parent
13370 // because we want to schedule this fiber as having work
13371 // on its children. We'll use the childExpirationTime on
13372 // this fiber to indicate that a context has changed.
13373
13374
13375 scheduleWorkOnParentPath(parentSuspense, renderExpirationTime);
13376 nextFiber = fiber.sibling;
13377 } else {
13378 // Traverse down.
13379 nextFiber = fiber.child;
13380 }
13381
13382 if (nextFiber !== null) {
13383 // Set the return pointer of the child to the work-in-progress fiber.
13384 nextFiber.return = fiber;
13385 } else {
13386 // No child. Traverse to next sibling.
13387 nextFiber = fiber;
13388
13389 while (nextFiber !== null) {
13390 if (nextFiber === workInProgress) {
13391 // We're back to the root of this subtree. Exit.
13392 nextFiber = null;
13393 break;
13394 }
13395
13396 var sibling = nextFiber.sibling;
13397
13398 if (sibling !== null) {
13399 // Set the return pointer of the sibling to the work-in-progress fiber.
13400 sibling.return = nextFiber.return;
13401 nextFiber = sibling;
13402 break;
13403 } // No more siblings. Traverse up.
13404
13405
13406 nextFiber = nextFiber.return;
13407 }
13408 }
13409
13410 fiber = nextFiber;
13411 }
13412}
13413function prepareToReadContext(workInProgress, renderExpirationTime) {
13414 currentlyRenderingFiber = workInProgress;
13415 lastContextDependency = null;
13416 lastContextWithAllBitsObserved = null;
13417 var dependencies = workInProgress.dependencies;
13418
13419 if (dependencies !== null) {
13420 var firstContext = dependencies.firstContext;
13421
13422 if (firstContext !== null) {
13423 if (dependencies.expirationTime >= renderExpirationTime) {
13424 // Context list has a pending update. Mark that this fiber performed work.
13425 markWorkInProgressReceivedUpdate();
13426 } // Reset the work-in-progress list
13427
13428
13429 dependencies.firstContext = null;
13430 }
13431 }
13432}
13433function readContext(context, observedBits) {
13434 {
13435 // This warning would fire if you read context inside a Hook like useMemo.
13436 // Unlike the class check below, it's not enforced in production for perf.
13437 !!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;
13438 }
13439
13440 if (lastContextWithAllBitsObserved === context) {// Nothing to do. We already observe everything in this context.
13441 } else if (observedBits === false || observedBits === 0) {// Do not observe any updates.
13442 } else {
13443 var resolvedObservedBits; // Avoid deopting on observable arguments or heterogeneous types.
13444
13445 if (typeof observedBits !== 'number' || observedBits === MAX_SIGNED_31_BIT_INT) {
13446 // Observe all updates.
13447 lastContextWithAllBitsObserved = context;
13448 resolvedObservedBits = MAX_SIGNED_31_BIT_INT;
13449 } else {
13450 resolvedObservedBits = observedBits;
13451 }
13452
13453 var contextItem = {
13454 context: context,
13455 observedBits: resolvedObservedBits,
13456 next: null
13457 };
13458
13459 if (lastContextDependency === null) {
13460 if (!(currentlyRenderingFiber !== null)) {
13461 {
13462 throw Error("Context can only be read while React is rendering. In classes, you can read it in the render method or getDerivedStateFromProps. In function components, you can read it directly in the function body, but not inside Hooks like useReducer() or useMemo().");
13463 }
13464 } // This is the first dependency for this component. Create a new list.
13465
13466
13467 lastContextDependency = contextItem;
13468 currentlyRenderingFiber.dependencies = {
13469 expirationTime: NoWork,
13470 firstContext: contextItem,
13471 responders: null
13472 };
13473 } else {
13474 // Append a new context item.
13475 lastContextDependency = lastContextDependency.next = contextItem;
13476 }
13477 }
13478
13479 return isPrimaryRenderer ? context._currentValue : context._currentValue2;
13480}
13481
13482// UpdateQueue is a linked list of prioritized updates.
13483//
13484// Like fibers, update queues come in pairs: a current queue, which represents
13485// the visible state of the screen, and a work-in-progress queue, which can be
13486// mutated and processed asynchronously before it is committed — a form of
13487// double buffering. If a work-in-progress render is discarded before finishing,
13488// we create a new work-in-progress by cloning the current queue.
13489//
13490// Both queues share a persistent, singly-linked list structure. To schedule an
13491// update, we append it to the end of both queues. Each queue maintains a
13492// pointer to first update in the persistent list that hasn't been processed.
13493// The work-in-progress pointer always has a position equal to or greater than
13494// the current queue, since we always work on that one. The current queue's
13495// pointer is only updated during the commit phase, when we swap in the
13496// work-in-progress.
13497//
13498// For example:
13499//
13500// Current pointer: A - B - C - D - E - F
13501// Work-in-progress pointer: D - E - F
13502// ^
13503// The work-in-progress queue has
13504// processed more updates than current.
13505//
13506// The reason we append to both queues is because otherwise we might drop
13507// updates without ever processing them. For example, if we only add updates to
13508// the work-in-progress queue, some updates could be lost whenever a work-in
13509// -progress render restarts by cloning from current. Similarly, if we only add
13510// updates to the current queue, the updates will be lost whenever an already
13511// in-progress queue commits and swaps with the current queue. However, by
13512// adding to both queues, we guarantee that the update will be part of the next
13513// work-in-progress. (And because the work-in-progress queue becomes the
13514// current queue once it commits, there's no danger of applying the same
13515// update twice.)
13516//
13517// Prioritization
13518// --------------
13519//
13520// Updates are not sorted by priority, but by insertion; new updates are always
13521// appended to the end of the list.
13522//
13523// The priority is still important, though. When processing the update queue
13524// during the render phase, only the updates with sufficient priority are
13525// included in the result. If we skip an update because it has insufficient
13526// priority, it remains in the queue to be processed later, during a lower
13527// priority render. Crucially, all updates subsequent to a skipped update also
13528// remain in the queue *regardless of their priority*. That means high priority
13529// updates are sometimes processed twice, at two separate priorities. We also
13530// keep track of a base state, that represents the state before the first
13531// update in the queue is applied.
13532//
13533// For example:
13534//
13535// Given a base state of '', and the following queue of updates
13536//
13537// A1 - B2 - C1 - D2
13538//
13539// where the number indicates the priority, and the update is applied to the
13540// previous state by appending a letter, React will process these updates as
13541// two separate renders, one per distinct priority level:
13542//
13543// First render, at priority 1:
13544// Base state: ''
13545// Updates: [A1, C1]
13546// Result state: 'AC'
13547//
13548// Second render, at priority 2:
13549// Base state: 'A' <- The base state does not include C1,
13550// because B2 was skipped.
13551// Updates: [B2, C1, D2] <- C1 was rebased on top of B2
13552// Result state: 'ABCD'
13553//
13554// Because we process updates in insertion order, and rebase high priority
13555// updates when preceding updates are skipped, the final result is deterministic
13556// regardless of priority. Intermediate state may vary according to system
13557// resources, but the final state is always the same.
13558var UpdateState = 0;
13559var ReplaceState = 1;
13560var ForceUpdate = 2;
13561var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
13562// It should only be read right after calling `processUpdateQueue`, via
13563// `checkHasForceUpdateAfterProcessing`.
13564
13565var hasForceUpdate = false;
13566var didWarnUpdateInsideUpdate;
13567var currentlyProcessingQueue;
13568
13569
13570{
13571 didWarnUpdateInsideUpdate = false;
13572 currentlyProcessingQueue = null;
13573
13574
13575}
13576
13577function createUpdateQueue(baseState) {
13578 var queue = {
13579 baseState: baseState,
13580 firstUpdate: null,
13581 lastUpdate: null,
13582 firstCapturedUpdate: null,
13583 lastCapturedUpdate: null,
13584 firstEffect: null,
13585 lastEffect: null,
13586 firstCapturedEffect: null,
13587 lastCapturedEffect: null
13588 };
13589 return queue;
13590}
13591
13592function cloneUpdateQueue(currentQueue) {
13593 var queue = {
13594 baseState: currentQueue.baseState,
13595 firstUpdate: currentQueue.firstUpdate,
13596 lastUpdate: currentQueue.lastUpdate,
13597 // TODO: With resuming, if we bail out and resuse the child tree, we should
13598 // keep these effects.
13599 firstCapturedUpdate: null,
13600 lastCapturedUpdate: null,
13601 firstEffect: null,
13602 lastEffect: null,
13603 firstCapturedEffect: null,
13604 lastCapturedEffect: null
13605 };
13606 return queue;
13607}
13608
13609function createUpdate(expirationTime, suspenseConfig) {
13610 var update = {
13611 expirationTime: expirationTime,
13612 suspenseConfig: suspenseConfig,
13613 tag: UpdateState,
13614 payload: null,
13615 callback: null,
13616 next: null,
13617 nextEffect: null
13618 };
13619
13620 {
13621 update.priority = getCurrentPriorityLevel();
13622 }
13623
13624 return update;
13625}
13626
13627function appendUpdateToQueue(queue, update) {
13628 // Append the update to the end of the list.
13629 if (queue.lastUpdate === null) {
13630 // Queue is empty
13631 queue.firstUpdate = queue.lastUpdate = update;
13632 } else {
13633 queue.lastUpdate.next = update;
13634 queue.lastUpdate = update;
13635 }
13636}
13637
13638function enqueueUpdate(fiber, update) {
13639 // Update queues are created lazily.
13640 var alternate = fiber.alternate;
13641 var queue1;
13642 var queue2;
13643
13644 if (alternate === null) {
13645 // There's only one fiber.
13646 queue1 = fiber.updateQueue;
13647 queue2 = null;
13648
13649 if (queue1 === null) {
13650 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
13651 }
13652 } else {
13653 // There are two owners.
13654 queue1 = fiber.updateQueue;
13655 queue2 = alternate.updateQueue;
13656
13657 if (queue1 === null) {
13658 if (queue2 === null) {
13659 // Neither fiber has an update queue. Create new ones.
13660 queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
13661 queue2 = alternate.updateQueue = createUpdateQueue(alternate.memoizedState);
13662 } else {
13663 // Only one fiber has an update queue. Clone to create a new one.
13664 queue1 = fiber.updateQueue = cloneUpdateQueue(queue2);
13665 }
13666 } else {
13667 if (queue2 === null) {
13668 // Only one fiber has an update queue. Clone to create a new one.
13669 queue2 = alternate.updateQueue = cloneUpdateQueue(queue1);
13670 } else {// Both owners have an update queue.
13671 }
13672 }
13673 }
13674
13675 if (queue2 === null || queue1 === queue2) {
13676 // There's only a single queue.
13677 appendUpdateToQueue(queue1, update);
13678 } else {
13679 // There are two queues. We need to append the update to both queues,
13680 // while accounting for the persistent structure of the list — we don't
13681 // want the same update to be added multiple times.
13682 if (queue1.lastUpdate === null || queue2.lastUpdate === null) {
13683 // One of the queues is not empty. We must add the update to both queues.
13684 appendUpdateToQueue(queue1, update);
13685 appendUpdateToQueue(queue2, update);
13686 } else {
13687 // Both queues are non-empty. The last update is the same in both lists,
13688 // because of structural sharing. So, only append to one of the lists.
13689 appendUpdateToQueue(queue1, update); // But we still need to update the `lastUpdate` pointer of queue2.
13690
13691 queue2.lastUpdate = update;
13692 }
13693 }
13694
13695 {
13696 if (fiber.tag === ClassComponent && (currentlyProcessingQueue === queue1 || queue2 !== null && currentlyProcessingQueue === queue2) && !didWarnUpdateInsideUpdate) {
13697 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.');
13698 didWarnUpdateInsideUpdate = true;
13699 }
13700 }
13701}
13702function enqueueCapturedUpdate(workInProgress, update) {
13703 // Captured updates go into a separate list, and only on the work-in-
13704 // progress queue.
13705 var workInProgressQueue = workInProgress.updateQueue;
13706
13707 if (workInProgressQueue === null) {
13708 workInProgressQueue = workInProgress.updateQueue = createUpdateQueue(workInProgress.memoizedState);
13709 } else {
13710 // TODO: I put this here rather than createWorkInProgress so that we don't
13711 // clone the queue unnecessarily. There's probably a better way to
13712 // structure this.
13713 workInProgressQueue = ensureWorkInProgressQueueIsAClone(workInProgress, workInProgressQueue);
13714 } // Append the update to the end of the list.
13715
13716
13717 if (workInProgressQueue.lastCapturedUpdate === null) {
13718 // This is the first render phase update
13719 workInProgressQueue.firstCapturedUpdate = workInProgressQueue.lastCapturedUpdate = update;
13720 } else {
13721 workInProgressQueue.lastCapturedUpdate.next = update;
13722 workInProgressQueue.lastCapturedUpdate = update;
13723 }
13724}
13725
13726function ensureWorkInProgressQueueIsAClone(workInProgress, queue) {
13727 var current = workInProgress.alternate;
13728
13729 if (current !== null) {
13730 // If the work-in-progress queue is equal to the current queue,
13731 // we need to clone it first.
13732 if (queue === current.updateQueue) {
13733 queue = workInProgress.updateQueue = cloneUpdateQueue(queue);
13734 }
13735 }
13736
13737 return queue;
13738}
13739
13740function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
13741 switch (update.tag) {
13742 case ReplaceState:
13743 {
13744 var payload = update.payload;
13745
13746 if (typeof payload === 'function') {
13747 // Updater function
13748 {
13749 enterDisallowedContextReadInDEV();
13750
13751 if (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
13752 payload.call(instance, prevState, nextProps);
13753 }
13754 }
13755
13756 var nextState = payload.call(instance, prevState, nextProps);
13757
13758 {
13759 exitDisallowedContextReadInDEV();
13760 }
13761
13762 return nextState;
13763 } // State object
13764
13765
13766 return payload;
13767 }
13768
13769 case CaptureUpdate:
13770 {
13771 workInProgress.effectTag = workInProgress.effectTag & ~ShouldCapture | DidCapture;
13772 }
13773 // Intentional fallthrough
13774
13775 case UpdateState:
13776 {
13777 var _payload = update.payload;
13778 var partialState;
13779
13780 if (typeof _payload === 'function') {
13781 // Updater function
13782 {
13783 enterDisallowedContextReadInDEV();
13784
13785 if (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
13786 _payload.call(instance, prevState, nextProps);
13787 }
13788 }
13789
13790 partialState = _payload.call(instance, prevState, nextProps);
13791
13792 {
13793 exitDisallowedContextReadInDEV();
13794 }
13795 } else {
13796 // Partial state object
13797 partialState = _payload;
13798 }
13799
13800 if (partialState === null || partialState === undefined) {
13801 // Null and undefined are treated as no-ops.
13802 return prevState;
13803 } // Merge the partial state and the previous state.
13804
13805
13806 return _assign({}, prevState, partialState);
13807 }
13808
13809 case ForceUpdate:
13810 {
13811 hasForceUpdate = true;
13812 return prevState;
13813 }
13814 }
13815
13816 return prevState;
13817}
13818
13819function processUpdateQueue(workInProgress, queue, props, instance, renderExpirationTime) {
13820 hasForceUpdate = false;
13821 queue = ensureWorkInProgressQueueIsAClone(workInProgress, queue);
13822
13823 {
13824 currentlyProcessingQueue = queue;
13825 } // These values may change as we process the queue.
13826
13827
13828 var newBaseState = queue.baseState;
13829 var newFirstUpdate = null;
13830 var newExpirationTime = NoWork; // Iterate through the list of updates to compute the result.
13831
13832 var update = queue.firstUpdate;
13833 var resultState = newBaseState;
13834
13835 while (update !== null) {
13836 var updateExpirationTime = update.expirationTime;
13837
13838 if (updateExpirationTime < renderExpirationTime) {
13839 // This update does not have sufficient priority. Skip it.
13840 if (newFirstUpdate === null) {
13841 // This is the first skipped update. It will be the first update in
13842 // the new list.
13843 newFirstUpdate = update; // Since this is the first update that was skipped, the current result
13844 // is the new base state.
13845
13846 newBaseState = resultState;
13847 } // Since this update will remain in the list, update the remaining
13848 // expiration time.
13849
13850
13851 if (newExpirationTime < updateExpirationTime) {
13852 newExpirationTime = updateExpirationTime;
13853 }
13854 } else {
13855 // This update does have sufficient priority.
13856 // Mark the event time of this update as relevant to this render pass.
13857 // TODO: This should ideally use the true event time of this update rather than
13858 // its priority which is a derived and not reverseable value.
13859 // TODO: We should skip this update if it was already committed but currently
13860 // we have no way of detecting the difference between a committed and suspended
13861 // update here.
13862 markRenderEventTimeAndConfig(updateExpirationTime, update.suspenseConfig); // Process it and compute a new result.
13863
13864 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
13865 var callback = update.callback;
13866
13867 if (callback !== null) {
13868 workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render.
13869
13870 update.nextEffect = null;
13871
13872 if (queue.lastEffect === null) {
13873 queue.firstEffect = queue.lastEffect = update;
13874 } else {
13875 queue.lastEffect.nextEffect = update;
13876 queue.lastEffect = update;
13877 }
13878 }
13879 } // Continue to the next update.
13880
13881
13882 update = update.next;
13883 } // Separately, iterate though the list of captured updates.
13884
13885
13886 var newFirstCapturedUpdate = null;
13887 update = queue.firstCapturedUpdate;
13888
13889 while (update !== null) {
13890 var _updateExpirationTime = update.expirationTime;
13891
13892 if (_updateExpirationTime < renderExpirationTime) {
13893 // This update does not have sufficient priority. Skip it.
13894 if (newFirstCapturedUpdate === null) {
13895 // This is the first skipped captured update. It will be the first
13896 // update in the new list.
13897 newFirstCapturedUpdate = update; // If this is the first update that was skipped, the current result is
13898 // the new base state.
13899
13900 if (newFirstUpdate === null) {
13901 newBaseState = resultState;
13902 }
13903 } // Since this update will remain in the list, update the remaining
13904 // expiration time.
13905
13906
13907 if (newExpirationTime < _updateExpirationTime) {
13908 newExpirationTime = _updateExpirationTime;
13909 }
13910 } else {
13911 // This update does have sufficient priority. Process it and compute
13912 // a new result.
13913 resultState = getStateFromUpdate(workInProgress, queue, update, resultState, props, instance);
13914 var _callback = update.callback;
13915
13916 if (_callback !== null) {
13917 workInProgress.effectTag |= Callback; // Set this to null, in case it was mutated during an aborted render.
13918
13919 update.nextEffect = null;
13920
13921 if (queue.lastCapturedEffect === null) {
13922 queue.firstCapturedEffect = queue.lastCapturedEffect = update;
13923 } else {
13924 queue.lastCapturedEffect.nextEffect = update;
13925 queue.lastCapturedEffect = update;
13926 }
13927 }
13928 }
13929
13930 update = update.next;
13931 }
13932
13933 if (newFirstUpdate === null) {
13934 queue.lastUpdate = null;
13935 }
13936
13937 if (newFirstCapturedUpdate === null) {
13938 queue.lastCapturedUpdate = null;
13939 } else {
13940 workInProgress.effectTag |= Callback;
13941 }
13942
13943 if (newFirstUpdate === null && newFirstCapturedUpdate === null) {
13944 // We processed every update, without skipping. That means the new base
13945 // state is the same as the result state.
13946 newBaseState = resultState;
13947 }
13948
13949 queue.baseState = newBaseState;
13950 queue.firstUpdate = newFirstUpdate;
13951 queue.firstCapturedUpdate = newFirstCapturedUpdate; // Set the remaining expiration time to be whatever is remaining in the queue.
13952 // This should be fine because the only two other things that contribute to
13953 // expiration time are props and context. We're already in the middle of the
13954 // begin phase by the time we start processing the queue, so we've already
13955 // dealt with the props. Context in components that specify
13956 // shouldComponentUpdate is tricky; but we'll have to account for
13957 // that regardless.
13958
13959 markUnprocessedUpdateTime(newExpirationTime);
13960 workInProgress.expirationTime = newExpirationTime;
13961 workInProgress.memoizedState = resultState;
13962
13963 {
13964 currentlyProcessingQueue = null;
13965 }
13966}
13967
13968function callCallback(callback, context) {
13969 if (!(typeof callback === 'function')) {
13970 {
13971 throw Error("Invalid argument passed as callback. Expected a function. Instead received: " + callback);
13972 }
13973 }
13974
13975 callback.call(context);
13976}
13977
13978function resetHasForceUpdateBeforeProcessing() {
13979 hasForceUpdate = false;
13980}
13981function checkHasForceUpdateAfterProcessing() {
13982 return hasForceUpdate;
13983}
13984function commitUpdateQueue(finishedWork, finishedQueue, instance, renderExpirationTime) {
13985 // If the finished render included captured updates, and there are still
13986 // lower priority updates left over, we need to keep the captured updates
13987 // in the queue so that they are rebased and not dropped once we process the
13988 // queue again at the lower priority.
13989 if (finishedQueue.firstCapturedUpdate !== null) {
13990 // Join the captured update list to the end of the normal list.
13991 if (finishedQueue.lastUpdate !== null) {
13992 finishedQueue.lastUpdate.next = finishedQueue.firstCapturedUpdate;
13993 finishedQueue.lastUpdate = finishedQueue.lastCapturedUpdate;
13994 } // Clear the list of captured updates.
13995
13996
13997 finishedQueue.firstCapturedUpdate = finishedQueue.lastCapturedUpdate = null;
13998 } // Commit the effects
13999
14000
14001 commitUpdateEffects(finishedQueue.firstEffect, instance);
14002 finishedQueue.firstEffect = finishedQueue.lastEffect = null;
14003 commitUpdateEffects(finishedQueue.firstCapturedEffect, instance);
14004 finishedQueue.firstCapturedEffect = finishedQueue.lastCapturedEffect = null;
14005}
14006
14007function commitUpdateEffects(effect, instance) {
14008 while (effect !== null) {
14009 var callback = effect.callback;
14010
14011 if (callback !== null) {
14012 effect.callback = null;
14013 callCallback(callback, instance);
14014 }
14015
14016 effect = effect.nextEffect;
14017 }
14018}
14019
14020var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig;
14021function requestCurrentSuspenseConfig() {
14022 return ReactCurrentBatchConfig.suspense;
14023}
14024
14025var fakeInternalInstance = {};
14026var isArray$1 = Array.isArray; // React.Component uses a shared frozen object by default.
14027// We'll use it to determine whether we need to initialize legacy refs.
14028
14029var emptyRefsObject = new React.Component().refs;
14030var didWarnAboutStateAssignmentForComponent;
14031var didWarnAboutUninitializedState;
14032var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
14033var didWarnAboutLegacyLifecyclesAndDerivedState;
14034var didWarnAboutUndefinedDerivedState;
14035var warnOnUndefinedDerivedState;
14036var warnOnInvalidCallback$1;
14037var didWarnAboutDirectlyAssigningPropsToState;
14038var didWarnAboutContextTypeAndContextTypes;
14039var didWarnAboutInvalidateContextType;
14040
14041{
14042 didWarnAboutStateAssignmentForComponent = new Set();
14043 didWarnAboutUninitializedState = new Set();
14044 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
14045 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
14046 didWarnAboutDirectlyAssigningPropsToState = new Set();
14047 didWarnAboutUndefinedDerivedState = new Set();
14048 didWarnAboutContextTypeAndContextTypes = new Set();
14049 didWarnAboutInvalidateContextType = new Set();
14050 var didWarnOnInvalidCallback = new Set();
14051
14052 warnOnInvalidCallback$1 = function (callback, callerName) {
14053 if (callback === null || typeof callback === 'function') {
14054 return;
14055 }
14056
14057 var key = callerName + "_" + callback;
14058
14059 if (!didWarnOnInvalidCallback.has(key)) {
14060 didWarnOnInvalidCallback.add(key);
14061 warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
14062 }
14063 };
14064
14065 warnOnUndefinedDerivedState = function (type, partialState) {
14066 if (partialState === undefined) {
14067 var componentName = getComponentName(type) || 'Component';
14068
14069 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
14070 didWarnAboutUndefinedDerivedState.add(componentName);
14071 warningWithoutStack$1(false, '%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
14072 }
14073 }
14074 }; // This is so gross but it's at least non-critical and can be removed if
14075 // it causes problems. This is meant to give a nicer error message for
14076 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
14077 // ...)) which otherwise throws a "_processChildContext is not a function"
14078 // exception.
14079
14080
14081 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
14082 enumerable: false,
14083 value: function () {
14084 {
14085 {
14086 throw Error("_processChildContext is not available in React 16+. This likely means you have multiple copies of React and are attempting to nest a React 15 tree inside a React 16 tree using unstable_renderSubtreeIntoContainer, which isn't supported. Try to make sure you have only one copy of React (and ideally, switch to ReactDOM.createPortal).");
14087 }
14088 }
14089 }
14090 });
14091 Object.freeze(fakeInternalInstance);
14092}
14093
14094function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
14095 var prevState = workInProgress.memoizedState;
14096
14097 {
14098 if (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14099 // Invoke the function an extra time to help detect side-effects.
14100 getDerivedStateFromProps(nextProps, prevState);
14101 }
14102 }
14103
14104 var partialState = getDerivedStateFromProps(nextProps, prevState);
14105
14106 {
14107 warnOnUndefinedDerivedState(ctor, partialState);
14108 } // Merge the partial state and the previous state.
14109
14110
14111 var memoizedState = partialState === null || partialState === undefined ? prevState : _assign({}, prevState, partialState);
14112 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
14113 // base state.
14114
14115 var updateQueue = workInProgress.updateQueue;
14116
14117 if (updateQueue !== null && workInProgress.expirationTime === NoWork) {
14118 updateQueue.baseState = memoizedState;
14119 }
14120}
14121var classComponentUpdater = {
14122 isMounted: isMounted,
14123 enqueueSetState: function (inst, payload, callback) {
14124 var fiber = get(inst);
14125 var currentTime = requestCurrentTimeForUpdate();
14126 var suspenseConfig = requestCurrentSuspenseConfig();
14127 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
14128 var update = createUpdate(expirationTime, suspenseConfig);
14129 update.payload = payload;
14130
14131 if (callback !== undefined && callback !== null) {
14132 {
14133 warnOnInvalidCallback$1(callback, 'setState');
14134 }
14135
14136 update.callback = callback;
14137 }
14138
14139 enqueueUpdate(fiber, update);
14140 scheduleWork(fiber, expirationTime);
14141 },
14142 enqueueReplaceState: function (inst, payload, callback) {
14143 var fiber = get(inst);
14144 var currentTime = requestCurrentTimeForUpdate();
14145 var suspenseConfig = requestCurrentSuspenseConfig();
14146 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
14147 var update = createUpdate(expirationTime, suspenseConfig);
14148 update.tag = ReplaceState;
14149 update.payload = payload;
14150
14151 if (callback !== undefined && callback !== null) {
14152 {
14153 warnOnInvalidCallback$1(callback, 'replaceState');
14154 }
14155
14156 update.callback = callback;
14157 }
14158
14159 enqueueUpdate(fiber, update);
14160 scheduleWork(fiber, expirationTime);
14161 },
14162 enqueueForceUpdate: function (inst, callback) {
14163 var fiber = get(inst);
14164 var currentTime = requestCurrentTimeForUpdate();
14165 var suspenseConfig = requestCurrentSuspenseConfig();
14166 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
14167 var update = createUpdate(expirationTime, suspenseConfig);
14168 update.tag = ForceUpdate;
14169
14170 if (callback !== undefined && callback !== null) {
14171 {
14172 warnOnInvalidCallback$1(callback, 'forceUpdate');
14173 }
14174
14175 update.callback = callback;
14176 }
14177
14178 enqueueUpdate(fiber, update);
14179 scheduleWork(fiber, expirationTime);
14180 }
14181};
14182
14183function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
14184 var instance = workInProgress.stateNode;
14185
14186 if (typeof instance.shouldComponentUpdate === 'function') {
14187 startPhaseTimer(workInProgress, 'shouldComponentUpdate');
14188 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
14189 stopPhaseTimer();
14190
14191 {
14192 !(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;
14193 }
14194
14195 return shouldUpdate;
14196 }
14197
14198 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
14199 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
14200 }
14201
14202 return true;
14203}
14204
14205function checkClassInstance(workInProgress, ctor, newProps) {
14206 var instance = workInProgress.stateNode;
14207
14208 {
14209 var name = getComponentName(ctor) || 'Component';
14210 var renderPresent = instance.render;
14211
14212 if (!renderPresent) {
14213 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
14214 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
14215 } else {
14216 warningWithoutStack$1(false, '%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
14217 }
14218 }
14219
14220 var noGetInitialStateOnES6 = !instance.getInitialState || instance.getInitialState.isReactClassApproved || instance.state;
14221 !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;
14222 var noGetDefaultPropsOnES6 = !instance.getDefaultProps || instance.getDefaultProps.isReactClassApproved;
14223 !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;
14224 var noInstancePropTypes = !instance.propTypes;
14225 !noInstancePropTypes ? warningWithoutStack$1(false, 'propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name) : void 0;
14226 var noInstanceContextType = !instance.contextType;
14227 !noInstanceContextType ? warningWithoutStack$1(false, 'contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name) : void 0;
14228
14229 if (disableLegacyContext) {
14230 if (ctor.childContextTypes) {
14231 warningWithoutStack$1(false, '%s uses the legacy childContextTypes API which is no longer supported. ' + 'Use React.createContext() instead.', name);
14232 }
14233
14234 if (ctor.contextTypes) {
14235 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with static contextType instead.', name);
14236 }
14237 } else {
14238 var noInstanceContextTypes = !instance.contextTypes;
14239 !noInstanceContextTypes ? warningWithoutStack$1(false, 'contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name) : void 0;
14240
14241 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
14242 didWarnAboutContextTypeAndContextTypes.add(ctor);
14243 warningWithoutStack$1(false, '%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
14244 }
14245 }
14246
14247 var noComponentShouldUpdate = typeof instance.componentShouldUpdate !== 'function';
14248 !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;
14249
14250 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
14251 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');
14252 }
14253
14254 var noComponentDidUnmount = typeof instance.componentDidUnmount !== 'function';
14255 !noComponentDidUnmount ? warningWithoutStack$1(false, '%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name) : void 0;
14256 var noComponentDidReceiveProps = typeof instance.componentDidReceiveProps !== 'function';
14257 !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;
14258 var noComponentWillRecieveProps = typeof instance.componentWillRecieveProps !== 'function';
14259 !noComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name) : void 0;
14260 var noUnsafeComponentWillRecieveProps = typeof instance.UNSAFE_componentWillRecieveProps !== 'function';
14261 !noUnsafeComponentWillRecieveProps ? warningWithoutStack$1(false, '%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name) : void 0;
14262 var hasMutatedProps = instance.props !== newProps;
14263 !(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;
14264 var noInstanceDefaultProps = !instance.defaultProps;
14265 !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;
14266
14267 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
14268 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
14269 warningWithoutStack$1(false, '%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentName(ctor));
14270 }
14271
14272 var noInstanceGetDerivedStateFromProps = typeof instance.getDerivedStateFromProps !== 'function';
14273 !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;
14274 var noInstanceGetDerivedStateFromCatch = typeof instance.getDerivedStateFromError !== 'function';
14275 !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;
14276 var noStaticGetSnapshotBeforeUpdate = typeof ctor.getSnapshotBeforeUpdate !== 'function';
14277 !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;
14278 var _state = instance.state;
14279
14280 if (_state && (typeof _state !== 'object' || isArray$1(_state))) {
14281 warningWithoutStack$1(false, '%s.state: must be set to an object or null', name);
14282 }
14283
14284 if (typeof instance.getChildContext === 'function') {
14285 !(typeof ctor.childContextTypes === 'object') ? warningWithoutStack$1(false, '%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name) : void 0;
14286 }
14287 }
14288}
14289
14290function adoptClassInstance(workInProgress, instance) {
14291 instance.updater = classComponentUpdater;
14292 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
14293
14294 set(instance, workInProgress);
14295
14296 {
14297 instance._reactInternalInstance = fakeInternalInstance;
14298 }
14299}
14300
14301function constructClassInstance(workInProgress, ctor, props, renderExpirationTime) {
14302 var isLegacyContextConsumer = false;
14303 var unmaskedContext = emptyContextObject;
14304 var context = emptyContextObject;
14305 var contextType = ctor.contextType;
14306
14307 {
14308 if ('contextType' in ctor) {
14309 var isValid = // Allow null for conditional declaration
14310 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
14311
14312 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
14313 didWarnAboutInvalidateContextType.add(ctor);
14314 var addendum = '';
14315
14316 if (contextType === undefined) {
14317 addendum = ' However, it is set to undefined. ' + 'This can be caused by a typo or by mixing up named and default imports. ' + 'This can also happen due to a circular dependency, so ' + 'try moving the createContext() call to a separate file.';
14318 } else if (typeof contextType !== 'object') {
14319 addendum = ' However, it is set to a ' + typeof contextType + '.';
14320 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
14321 addendum = ' Did you accidentally pass the Context.Provider instead?';
14322 } else if (contextType._context !== undefined) {
14323 // <Context.Consumer>
14324 addendum = ' Did you accidentally pass the Context.Consumer instead?';
14325 } else {
14326 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
14327 }
14328
14329 warningWithoutStack$1(false, '%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentName(ctor) || 'Component', addendum);
14330 }
14331 }
14332 }
14333
14334 if (typeof contextType === 'object' && contextType !== null) {
14335 context = readContext(contextType);
14336 } else if (!disableLegacyContext) {
14337 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
14338 var contextTypes = ctor.contextTypes;
14339 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
14340 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
14341 } // Instantiate twice to help detect side-effects.
14342
14343
14344 {
14345 if (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
14346 new ctor(props, context); // eslint-disable-line no-new
14347 }
14348 }
14349
14350 var instance = new ctor(props, context);
14351 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
14352 adoptClassInstance(workInProgress, instance);
14353
14354 {
14355 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
14356 var componentName = getComponentName(ctor) || 'Component';
14357
14358 if (!didWarnAboutUninitializedState.has(componentName)) {
14359 didWarnAboutUninitializedState.add(componentName);
14360 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);
14361 }
14362 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
14363 // Warn about these lifecycles if they are present.
14364 // Don't warn about react-lifecycles-compat polyfilled methods though.
14365
14366
14367 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
14368 var foundWillMountName = null;
14369 var foundWillReceivePropsName = null;
14370 var foundWillUpdateName = null;
14371
14372 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
14373 foundWillMountName = 'componentWillMount';
14374 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
14375 foundWillMountName = 'UNSAFE_componentWillMount';
14376 }
14377
14378 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
14379 foundWillReceivePropsName = 'componentWillReceiveProps';
14380 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
14381 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
14382 }
14383
14384 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
14385 foundWillUpdateName = 'componentWillUpdate';
14386 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
14387 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
14388 }
14389
14390 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
14391 var _componentName = getComponentName(ctor) || 'Component';
14392
14393 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
14394
14395 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
14396 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
14397 warningWithoutStack$1(false, 'Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://fb.me/react-unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
14398 }
14399 }
14400 }
14401 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
14402 // ReactFiberContext usually updates this cache but can't for newly-created instances.
14403
14404
14405 if (isLegacyContextConsumer) {
14406 cacheContext(workInProgress, unmaskedContext, context);
14407 }
14408
14409 return instance;
14410}
14411
14412function callComponentWillMount(workInProgress, instance) {
14413 startPhaseTimer(workInProgress, 'componentWillMount');
14414 var oldState = instance.state;
14415
14416 if (typeof instance.componentWillMount === 'function') {
14417 instance.componentWillMount();
14418 }
14419
14420 if (typeof instance.UNSAFE_componentWillMount === 'function') {
14421 instance.UNSAFE_componentWillMount();
14422 }
14423
14424 stopPhaseTimer();
14425
14426 if (oldState !== instance.state) {
14427 {
14428 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');
14429 }
14430
14431 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
14432 }
14433}
14434
14435function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
14436 var oldState = instance.state;
14437 startPhaseTimer(workInProgress, 'componentWillReceiveProps');
14438
14439 if (typeof instance.componentWillReceiveProps === 'function') {
14440 instance.componentWillReceiveProps(newProps, nextContext);
14441 }
14442
14443 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
14444 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
14445 }
14446
14447 stopPhaseTimer();
14448
14449 if (instance.state !== oldState) {
14450 {
14451 var componentName = getComponentName(workInProgress.type) || 'Component';
14452
14453 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
14454 didWarnAboutStateAssignmentForComponent.add(componentName);
14455 warningWithoutStack$1(false, '%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
14456 }
14457 }
14458
14459 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
14460 }
14461} // Invokes the mount life-cycles on a previously never rendered instance.
14462
14463
14464function mountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
14465 {
14466 checkClassInstance(workInProgress, ctor, newProps);
14467 }
14468
14469 var instance = workInProgress.stateNode;
14470 instance.props = newProps;
14471 instance.state = workInProgress.memoizedState;
14472 instance.refs = emptyRefsObject;
14473 var contextType = ctor.contextType;
14474
14475 if (typeof contextType === 'object' && contextType !== null) {
14476 instance.context = readContext(contextType);
14477 } else if (disableLegacyContext) {
14478 instance.context = emptyContextObject;
14479 } else {
14480 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
14481 instance.context = getMaskedContext(workInProgress, unmaskedContext);
14482 }
14483
14484 {
14485 if (instance.state === newProps) {
14486 var componentName = getComponentName(ctor) || 'Component';
14487
14488 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
14489 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
14490 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);
14491 }
14492 }
14493
14494 if (workInProgress.mode & StrictMode) {
14495 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
14496 }
14497
14498 if (warnAboutDeprecatedLifecycles) {
14499 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
14500 }
14501 }
14502
14503 var updateQueue = workInProgress.updateQueue;
14504
14505 if (updateQueue !== null) {
14506 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
14507 instance.state = workInProgress.memoizedState;
14508 }
14509
14510 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
14511
14512 if (typeof getDerivedStateFromProps === 'function') {
14513 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
14514 instance.state = workInProgress.memoizedState;
14515 } // In order to support react-lifecycles-compat polyfilled components,
14516 // Unsafe lifecycles should not be invoked for components using the new APIs.
14517
14518
14519 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
14520 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
14521 // process them now.
14522
14523 updateQueue = workInProgress.updateQueue;
14524
14525 if (updateQueue !== null) {
14526 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
14527 instance.state = workInProgress.memoizedState;
14528 }
14529 }
14530
14531 if (typeof instance.componentDidMount === 'function') {
14532 workInProgress.effectTag |= Update;
14533 }
14534}
14535
14536function resumeMountClassInstance(workInProgress, ctor, newProps, renderExpirationTime) {
14537 var instance = workInProgress.stateNode;
14538 var oldProps = workInProgress.memoizedProps;
14539 instance.props = oldProps;
14540 var oldContext = instance.context;
14541 var contextType = ctor.contextType;
14542 var nextContext = emptyContextObject;
14543
14544 if (typeof contextType === 'object' && contextType !== null) {
14545 nextContext = readContext(contextType);
14546 } else if (!disableLegacyContext) {
14547 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
14548 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
14549 }
14550
14551 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
14552 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
14553 // ever the previously attempted to render - not the "current". However,
14554 // during componentDidUpdate we pass the "current" props.
14555 // In order to support react-lifecycles-compat polyfilled components,
14556 // Unsafe lifecycles should not be invoked for components using the new APIs.
14557
14558 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
14559 if (oldProps !== newProps || oldContext !== nextContext) {
14560 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
14561 }
14562 }
14563
14564 resetHasForceUpdateBeforeProcessing();
14565 var oldState = workInProgress.memoizedState;
14566 var newState = instance.state = oldState;
14567 var updateQueue = workInProgress.updateQueue;
14568
14569 if (updateQueue !== null) {
14570 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
14571 newState = workInProgress.memoizedState;
14572 }
14573
14574 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
14575 // If an update was already in progress, we should schedule an Update
14576 // effect even though we're bailing out, so that cWU/cDU are called.
14577 if (typeof instance.componentDidMount === 'function') {
14578 workInProgress.effectTag |= Update;
14579 }
14580
14581 return false;
14582 }
14583
14584 if (typeof getDerivedStateFromProps === 'function') {
14585 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
14586 newState = workInProgress.memoizedState;
14587 }
14588
14589 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
14590
14591 if (shouldUpdate) {
14592 // In order to support react-lifecycles-compat polyfilled components,
14593 // Unsafe lifecycles should not be invoked for components using the new APIs.
14594 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
14595 startPhaseTimer(workInProgress, 'componentWillMount');
14596
14597 if (typeof instance.componentWillMount === 'function') {
14598 instance.componentWillMount();
14599 }
14600
14601 if (typeof instance.UNSAFE_componentWillMount === 'function') {
14602 instance.UNSAFE_componentWillMount();
14603 }
14604
14605 stopPhaseTimer();
14606 }
14607
14608 if (typeof instance.componentDidMount === 'function') {
14609 workInProgress.effectTag |= Update;
14610 }
14611 } else {
14612 // If an update was already in progress, we should schedule an Update
14613 // effect even though we're bailing out, so that cWU/cDU are called.
14614 if (typeof instance.componentDidMount === 'function') {
14615 workInProgress.effectTag |= Update;
14616 } // If shouldComponentUpdate returned false, we should still update the
14617 // memoized state to indicate that this work can be reused.
14618
14619
14620 workInProgress.memoizedProps = newProps;
14621 workInProgress.memoizedState = newState;
14622 } // Update the existing instance's state, props, and context pointers even
14623 // if shouldComponentUpdate returns false.
14624
14625
14626 instance.props = newProps;
14627 instance.state = newState;
14628 instance.context = nextContext;
14629 return shouldUpdate;
14630} // Invokes the update life-cycles and returns false if it shouldn't rerender.
14631
14632
14633function updateClassInstance(current, workInProgress, ctor, newProps, renderExpirationTime) {
14634 var instance = workInProgress.stateNode;
14635 var oldProps = workInProgress.memoizedProps;
14636 instance.props = workInProgress.type === workInProgress.elementType ? oldProps : resolveDefaultProps(workInProgress.type, oldProps);
14637 var oldContext = instance.context;
14638 var contextType = ctor.contextType;
14639 var nextContext = emptyContextObject;
14640
14641 if (typeof contextType === 'object' && contextType !== null) {
14642 nextContext = readContext(contextType);
14643 } else if (!disableLegacyContext) {
14644 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
14645 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
14646 }
14647
14648 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
14649 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
14650 // ever the previously attempted to render - not the "current". However,
14651 // during componentDidUpdate we pass the "current" props.
14652 // In order to support react-lifecycles-compat polyfilled components,
14653 // Unsafe lifecycles should not be invoked for components using the new APIs.
14654
14655 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
14656 if (oldProps !== newProps || oldContext !== nextContext) {
14657 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
14658 }
14659 }
14660
14661 resetHasForceUpdateBeforeProcessing();
14662 var oldState = workInProgress.memoizedState;
14663 var newState = instance.state = oldState;
14664 var updateQueue = workInProgress.updateQueue;
14665
14666 if (updateQueue !== null) {
14667 processUpdateQueue(workInProgress, updateQueue, newProps, instance, renderExpirationTime);
14668 newState = workInProgress.memoizedState;
14669 }
14670
14671 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
14672 // If an update was already in progress, we should schedule an Update
14673 // effect even though we're bailing out, so that cWU/cDU are called.
14674 if (typeof instance.componentDidUpdate === 'function') {
14675 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
14676 workInProgress.effectTag |= Update;
14677 }
14678 }
14679
14680 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
14681 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
14682 workInProgress.effectTag |= Snapshot;
14683 }
14684 }
14685
14686 return false;
14687 }
14688
14689 if (typeof getDerivedStateFromProps === 'function') {
14690 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
14691 newState = workInProgress.memoizedState;
14692 }
14693
14694 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
14695
14696 if (shouldUpdate) {
14697 // In order to support react-lifecycles-compat polyfilled components,
14698 // Unsafe lifecycles should not be invoked for components using the new APIs.
14699 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
14700 startPhaseTimer(workInProgress, 'componentWillUpdate');
14701
14702 if (typeof instance.componentWillUpdate === 'function') {
14703 instance.componentWillUpdate(newProps, newState, nextContext);
14704 }
14705
14706 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
14707 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
14708 }
14709
14710 stopPhaseTimer();
14711 }
14712
14713 if (typeof instance.componentDidUpdate === 'function') {
14714 workInProgress.effectTag |= Update;
14715 }
14716
14717 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
14718 workInProgress.effectTag |= Snapshot;
14719 }
14720 } else {
14721 // If an update was already in progress, we should schedule an Update
14722 // effect even though we're bailing out, so that cWU/cDU are called.
14723 if (typeof instance.componentDidUpdate === 'function') {
14724 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
14725 workInProgress.effectTag |= Update;
14726 }
14727 }
14728
14729 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
14730 if (oldProps !== current.memoizedProps || oldState !== current.memoizedState) {
14731 workInProgress.effectTag |= Snapshot;
14732 }
14733 } // If shouldComponentUpdate returned false, we should still update the
14734 // memoized props/state to indicate that this work can be reused.
14735
14736
14737 workInProgress.memoizedProps = newProps;
14738 workInProgress.memoizedState = newState;
14739 } // Update the existing instance's state, props, and context pointers even
14740 // if shouldComponentUpdate returns false.
14741
14742
14743 instance.props = newProps;
14744 instance.state = newState;
14745 instance.context = nextContext;
14746 return shouldUpdate;
14747}
14748
14749var didWarnAboutMaps;
14750var didWarnAboutGenerators;
14751var didWarnAboutStringRefs;
14752var ownerHasKeyUseWarning;
14753var ownerHasFunctionTypeWarning;
14754
14755var warnForMissingKey = function (child) {};
14756
14757{
14758 didWarnAboutMaps = false;
14759 didWarnAboutGenerators = false;
14760 didWarnAboutStringRefs = {};
14761 /**
14762 * Warn if there's no key explicitly set on dynamic arrays of children or
14763 * object keys are not valid. This allows us to keep track of children between
14764 * updates.
14765 */
14766
14767 ownerHasKeyUseWarning = {};
14768 ownerHasFunctionTypeWarning = {};
14769
14770 warnForMissingKey = function (child) {
14771 if (child === null || typeof child !== 'object') {
14772 return;
14773 }
14774
14775 if (!child._store || child._store.validated || child.key != null) {
14776 return;
14777 }
14778
14779 if (!(typeof child._store === 'object')) {
14780 {
14781 throw Error("React Component in warnForMissingKey should have a _store. This error is likely caused by a bug in React. Please file an issue.");
14782 }
14783 }
14784
14785 child._store.validated = true;
14786 var currentComponentErrorInfo = 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.' + getCurrentFiberStackInDev();
14787
14788 if (ownerHasKeyUseWarning[currentComponentErrorInfo]) {
14789 return;
14790 }
14791
14792 ownerHasKeyUseWarning[currentComponentErrorInfo] = true;
14793 warning$1(false, 'Each child in a list should have a unique ' + '"key" prop. See https://fb.me/react-warning-keys for ' + 'more information.');
14794 };
14795}
14796
14797var isArray = Array.isArray;
14798
14799function coerceRef(returnFiber, current$$1, element) {
14800 var mixedRef = element.ref;
14801
14802 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
14803 {
14804 // TODO: Clean this up once we turn on the string ref warning for
14805 // everyone, because the strict mode case will no longer be relevant
14806 if (returnFiber.mode & StrictMode || warnAboutStringRefs) {
14807 var componentName = getComponentName(returnFiber.type) || 'Component';
14808
14809 if (!didWarnAboutStringRefs[componentName]) {
14810 if (warnAboutStringRefs) {
14811 warningWithoutStack$1(false, 'Component "%s" contains the string ref "%s". Support for string refs ' + 'will be removed in a future major release. We recommend using ' + 'useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', componentName, mixedRef, getStackByFiberInDevAndProd(returnFiber));
14812 } else {
14813 warningWithoutStack$1(false, 'A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-string-ref%s', mixedRef, getStackByFiberInDevAndProd(returnFiber));
14814 }
14815
14816 didWarnAboutStringRefs[componentName] = true;
14817 }
14818 }
14819 }
14820
14821 if (element._owner) {
14822 var owner = element._owner;
14823 var inst;
14824
14825 if (owner) {
14826 var ownerFiber = owner;
14827
14828 if (!(ownerFiber.tag === ClassComponent)) {
14829 {
14830 throw Error("Function components cannot have refs. Did you mean to use React.forwardRef()?");
14831 }
14832 }
14833
14834 inst = ownerFiber.stateNode;
14835 }
14836
14837 if (!inst) {
14838 {
14839 throw Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a bug in React. Please file an issue.");
14840 }
14841 }
14842
14843 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
14844
14845 if (current$$1 !== null && current$$1.ref !== null && typeof current$$1.ref === 'function' && current$$1.ref._stringRef === stringRef) {
14846 return current$$1.ref;
14847 }
14848
14849 var ref = function (value) {
14850 var refs = inst.refs;
14851
14852 if (refs === emptyRefsObject) {
14853 // This is a lazy pooled frozen object, so we need to initialize.
14854 refs = inst.refs = {};
14855 }
14856
14857 if (value === null) {
14858 delete refs[stringRef];
14859 } else {
14860 refs[stringRef] = value;
14861 }
14862 };
14863
14864 ref._stringRef = stringRef;
14865 return ref;
14866 } else {
14867 if (!(typeof mixedRef === 'string')) {
14868 {
14869 throw Error("Expected ref to be a function, a string, an object returned by React.createRef(), or null.");
14870 }
14871 }
14872
14873 if (!element._owner) {
14874 {
14875 throw Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of the following reasons:\n1. You may be adding a ref to a function component\n2. You may be adding a ref to a component that was not created inside a component's render method\n3. You have multiple copies of React loaded\nSee https://fb.me/react-refs-must-have-owner for more information.");
14876 }
14877 }
14878 }
14879 }
14880
14881 return mixedRef;
14882}
14883
14884function throwOnInvalidObjectType(returnFiber, newChild) {
14885 if (returnFiber.type !== 'textarea') {
14886 var addendum = '';
14887
14888 {
14889 addendum = ' If you meant to render a collection of children, use an array ' + 'instead.' + getCurrentFiberStackInDev();
14890 }
14891
14892 {
14893 {
14894 throw Error("Objects are not valid as a React child (found: " + (Object.prototype.toString.call(newChild) === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : newChild) + ")." + addendum);
14895 }
14896 }
14897 }
14898}
14899
14900function warnOnFunctionType() {
14901 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();
14902
14903 if (ownerHasFunctionTypeWarning[currentComponentErrorInfo]) {
14904 return;
14905 }
14906
14907 ownerHasFunctionTypeWarning[currentComponentErrorInfo] = true;
14908 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.');
14909} // This wrapper function exists because I expect to clone the code in each path
14910// to be able to optimize each path individually by branching early. This needs
14911// a compiler or we can do it manually. Helpers that don't need this branching
14912// live outside of this function.
14913
14914
14915function ChildReconciler(shouldTrackSideEffects) {
14916 function deleteChild(returnFiber, childToDelete) {
14917 if (!shouldTrackSideEffects) {
14918 // Noop.
14919 return;
14920 } // Deletions are added in reversed order so we add it to the front.
14921 // At this point, the return fiber's effect list is empty except for
14922 // deletions, so we can just append the deletion to the list. The remaining
14923 // effects aren't added until the complete phase. Once we implement
14924 // resuming, this may not be true.
14925
14926
14927 var last = returnFiber.lastEffect;
14928
14929 if (last !== null) {
14930 last.nextEffect = childToDelete;
14931 returnFiber.lastEffect = childToDelete;
14932 } else {
14933 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
14934 }
14935
14936 childToDelete.nextEffect = null;
14937 childToDelete.effectTag = Deletion;
14938 }
14939
14940 function deleteRemainingChildren(returnFiber, currentFirstChild) {
14941 if (!shouldTrackSideEffects) {
14942 // Noop.
14943 return null;
14944 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
14945 // assuming that after the first child we've already added everything.
14946
14947
14948 var childToDelete = currentFirstChild;
14949
14950 while (childToDelete !== null) {
14951 deleteChild(returnFiber, childToDelete);
14952 childToDelete = childToDelete.sibling;
14953 }
14954
14955 return null;
14956 }
14957
14958 function mapRemainingChildren(returnFiber, currentFirstChild) {
14959 // Add the remaining children to a temporary map so that we can find them by
14960 // keys quickly. Implicit (null) keys get added to this set with their index
14961 // instead.
14962 var existingChildren = new Map();
14963 var existingChild = currentFirstChild;
14964
14965 while (existingChild !== null) {
14966 if (existingChild.key !== null) {
14967 existingChildren.set(existingChild.key, existingChild);
14968 } else {
14969 existingChildren.set(existingChild.index, existingChild);
14970 }
14971
14972 existingChild = existingChild.sibling;
14973 }
14974
14975 return existingChildren;
14976 }
14977
14978 function useFiber(fiber, pendingProps, expirationTime) {
14979 // We currently set sibling to null and index to 0 here because it is easy
14980 // to forget to do before returning it. E.g. for the single child case.
14981 var clone = createWorkInProgress(fiber, pendingProps, expirationTime);
14982 clone.index = 0;
14983 clone.sibling = null;
14984 return clone;
14985 }
14986
14987 function placeChild(newFiber, lastPlacedIndex, newIndex) {
14988 newFiber.index = newIndex;
14989
14990 if (!shouldTrackSideEffects) {
14991 // Noop.
14992 return lastPlacedIndex;
14993 }
14994
14995 var current$$1 = newFiber.alternate;
14996
14997 if (current$$1 !== null) {
14998 var oldIndex = current$$1.index;
14999
15000 if (oldIndex < lastPlacedIndex) {
15001 // This is a move.
15002 newFiber.effectTag = Placement;
15003 return lastPlacedIndex;
15004 } else {
15005 // This item can stay in place.
15006 return oldIndex;
15007 }
15008 } else {
15009 // This is an insertion.
15010 newFiber.effectTag = Placement;
15011 return lastPlacedIndex;
15012 }
15013 }
15014
15015 function placeSingleChild(newFiber) {
15016 // This is simpler for the single child case. We only need to do a
15017 // placement for inserting new children.
15018 if (shouldTrackSideEffects && newFiber.alternate === null) {
15019 newFiber.effectTag = Placement;
15020 }
15021
15022 return newFiber;
15023 }
15024
15025 function updateTextNode(returnFiber, current$$1, textContent, expirationTime) {
15026 if (current$$1 === null || current$$1.tag !== HostText) {
15027 // Insert
15028 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
15029 created.return = returnFiber;
15030 return created;
15031 } else {
15032 // Update
15033 var existing = useFiber(current$$1, textContent, expirationTime);
15034 existing.return = returnFiber;
15035 return existing;
15036 }
15037 }
15038
15039 function updateElement(returnFiber, current$$1, element, expirationTime) {
15040 if (current$$1 !== null && (current$$1.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
15041 isCompatibleFamilyForHotReloading(current$$1, element)))) {
15042 // Move based on index
15043 var existing = useFiber(current$$1, element.props, expirationTime);
15044 existing.ref = coerceRef(returnFiber, current$$1, element);
15045 existing.return = returnFiber;
15046
15047 {
15048 existing._debugSource = element._source;
15049 existing._debugOwner = element._owner;
15050 }
15051
15052 return existing;
15053 } else {
15054 // Insert
15055 var created = createFiberFromElement(element, returnFiber.mode, expirationTime);
15056 created.ref = coerceRef(returnFiber, current$$1, element);
15057 created.return = returnFiber;
15058 return created;
15059 }
15060 }
15061
15062 function updatePortal(returnFiber, current$$1, portal, expirationTime) {
15063 if (current$$1 === null || current$$1.tag !== HostPortal || current$$1.stateNode.containerInfo !== portal.containerInfo || current$$1.stateNode.implementation !== portal.implementation) {
15064 // Insert
15065 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
15066 created.return = returnFiber;
15067 return created;
15068 } else {
15069 // Update
15070 var existing = useFiber(current$$1, portal.children || [], expirationTime);
15071 existing.return = returnFiber;
15072 return existing;
15073 }
15074 }
15075
15076 function updateFragment(returnFiber, current$$1, fragment, expirationTime, key) {
15077 if (current$$1 === null || current$$1.tag !== Fragment) {
15078 // Insert
15079 var created = createFiberFromFragment(fragment, returnFiber.mode, expirationTime, key);
15080 created.return = returnFiber;
15081 return created;
15082 } else {
15083 // Update
15084 var existing = useFiber(current$$1, fragment, expirationTime);
15085 existing.return = returnFiber;
15086 return existing;
15087 }
15088 }
15089
15090 function createChild(returnFiber, newChild, expirationTime) {
15091 if (typeof newChild === 'string' || typeof newChild === 'number') {
15092 // Text nodes don't have keys. If the previous node is implicitly keyed
15093 // we can continue to replace it without aborting even if it is not a text
15094 // node.
15095 var created = createFiberFromText('' + newChild, returnFiber.mode, expirationTime);
15096 created.return = returnFiber;
15097 return created;
15098 }
15099
15100 if (typeof newChild === 'object' && newChild !== null) {
15101 switch (newChild.$$typeof) {
15102 case REACT_ELEMENT_TYPE:
15103 {
15104 var _created = createFiberFromElement(newChild, returnFiber.mode, expirationTime);
15105
15106 _created.ref = coerceRef(returnFiber, null, newChild);
15107 _created.return = returnFiber;
15108 return _created;
15109 }
15110
15111 case REACT_PORTAL_TYPE:
15112 {
15113 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, expirationTime);
15114
15115 _created2.return = returnFiber;
15116 return _created2;
15117 }
15118 }
15119
15120 if (isArray(newChild) || getIteratorFn(newChild)) {
15121 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, expirationTime, null);
15122
15123 _created3.return = returnFiber;
15124 return _created3;
15125 }
15126
15127 throwOnInvalidObjectType(returnFiber, newChild);
15128 }
15129
15130 {
15131 if (typeof newChild === 'function') {
15132 warnOnFunctionType();
15133 }
15134 }
15135
15136 return null;
15137 }
15138
15139 function updateSlot(returnFiber, oldFiber, newChild, expirationTime) {
15140 // Update the fiber if the keys match, otherwise return null.
15141 var key = oldFiber !== null ? oldFiber.key : null;
15142
15143 if (typeof newChild === 'string' || typeof newChild === 'number') {
15144 // Text nodes don't have keys. If the previous node is implicitly keyed
15145 // we can continue to replace it without aborting even if it is not a text
15146 // node.
15147 if (key !== null) {
15148 return null;
15149 }
15150
15151 return updateTextNode(returnFiber, oldFiber, '' + newChild, expirationTime);
15152 }
15153
15154 if (typeof newChild === 'object' && newChild !== null) {
15155 switch (newChild.$$typeof) {
15156 case REACT_ELEMENT_TYPE:
15157 {
15158 if (newChild.key === key) {
15159 if (newChild.type === REACT_FRAGMENT_TYPE) {
15160 return updateFragment(returnFiber, oldFiber, newChild.props.children, expirationTime, key);
15161 }
15162
15163 return updateElement(returnFiber, oldFiber, newChild, expirationTime);
15164 } else {
15165 return null;
15166 }
15167 }
15168
15169 case REACT_PORTAL_TYPE:
15170 {
15171 if (newChild.key === key) {
15172 return updatePortal(returnFiber, oldFiber, newChild, expirationTime);
15173 } else {
15174 return null;
15175 }
15176 }
15177 }
15178
15179 if (isArray(newChild) || getIteratorFn(newChild)) {
15180 if (key !== null) {
15181 return null;
15182 }
15183
15184 return updateFragment(returnFiber, oldFiber, newChild, expirationTime, null);
15185 }
15186
15187 throwOnInvalidObjectType(returnFiber, newChild);
15188 }
15189
15190 {
15191 if (typeof newChild === 'function') {
15192 warnOnFunctionType();
15193 }
15194 }
15195
15196 return null;
15197 }
15198
15199 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, expirationTime) {
15200 if (typeof newChild === 'string' || typeof newChild === 'number') {
15201 // Text nodes don't have keys, so we neither have to check the old nor
15202 // new node for the key. If both are text nodes, they match.
15203 var matchedFiber = existingChildren.get(newIdx) || null;
15204 return updateTextNode(returnFiber, matchedFiber, '' + newChild, expirationTime);
15205 }
15206
15207 if (typeof newChild === 'object' && newChild !== null) {
15208 switch (newChild.$$typeof) {
15209 case REACT_ELEMENT_TYPE:
15210 {
15211 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
15212
15213 if (newChild.type === REACT_FRAGMENT_TYPE) {
15214 return updateFragment(returnFiber, _matchedFiber, newChild.props.children, expirationTime, newChild.key);
15215 }
15216
15217 return updateElement(returnFiber, _matchedFiber, newChild, expirationTime);
15218 }
15219
15220 case REACT_PORTAL_TYPE:
15221 {
15222 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
15223
15224 return updatePortal(returnFiber, _matchedFiber2, newChild, expirationTime);
15225 }
15226 }
15227
15228 if (isArray(newChild) || getIteratorFn(newChild)) {
15229 var _matchedFiber3 = existingChildren.get(newIdx) || null;
15230
15231 return updateFragment(returnFiber, _matchedFiber3, newChild, expirationTime, null);
15232 }
15233
15234 throwOnInvalidObjectType(returnFiber, newChild);
15235 }
15236
15237 {
15238 if (typeof newChild === 'function') {
15239 warnOnFunctionType();
15240 }
15241 }
15242
15243 return null;
15244 }
15245 /**
15246 * Warns if there is a duplicate or missing key
15247 */
15248
15249
15250 function warnOnInvalidKey(child, knownKeys) {
15251 {
15252 if (typeof child !== 'object' || child === null) {
15253 return knownKeys;
15254 }
15255
15256 switch (child.$$typeof) {
15257 case REACT_ELEMENT_TYPE:
15258 case REACT_PORTAL_TYPE:
15259 warnForMissingKey(child);
15260 var key = child.key;
15261
15262 if (typeof key !== 'string') {
15263 break;
15264 }
15265
15266 if (knownKeys === null) {
15267 knownKeys = new Set();
15268 knownKeys.add(key);
15269 break;
15270 }
15271
15272 if (!knownKeys.has(key)) {
15273 knownKeys.add(key);
15274 break;
15275 }
15276
15277 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);
15278 break;
15279
15280 default:
15281 break;
15282 }
15283 }
15284
15285 return knownKeys;
15286 }
15287
15288 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, expirationTime) {
15289 // This algorithm can't optimize by searching from both ends since we
15290 // don't have backpointers on fibers. I'm trying to see how far we can get
15291 // with that model. If it ends up not being worth the tradeoffs, we can
15292 // add it later.
15293 // Even with a two ended optimization, we'd want to optimize for the case
15294 // where there are few changes and brute force the comparison instead of
15295 // going for the Map. It'd like to explore hitting that path first in
15296 // forward-only mode and only go for the Map once we notice that we need
15297 // lots of look ahead. This doesn't handle reversal as well as two ended
15298 // search but that's unusual. Besides, for the two ended optimization to
15299 // work on Iterables, we'd need to copy the whole set.
15300 // In this first iteration, we'll just live with hitting the bad case
15301 // (adding everything to a Map) in for every insert/move.
15302 // If you change this code, also update reconcileChildrenIterator() which
15303 // uses the same algorithm.
15304 {
15305 // First, validate keys.
15306 var knownKeys = null;
15307
15308 for (var i = 0; i < newChildren.length; i++) {
15309 var child = newChildren[i];
15310 knownKeys = warnOnInvalidKey(child, knownKeys);
15311 }
15312 }
15313
15314 var resultingFirstChild = null;
15315 var previousNewFiber = null;
15316 var oldFiber = currentFirstChild;
15317 var lastPlacedIndex = 0;
15318 var newIdx = 0;
15319 var nextOldFiber = null;
15320
15321 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
15322 if (oldFiber.index > newIdx) {
15323 nextOldFiber = oldFiber;
15324 oldFiber = null;
15325 } else {
15326 nextOldFiber = oldFiber.sibling;
15327 }
15328
15329 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], expirationTime);
15330
15331 if (newFiber === null) {
15332 // TODO: This breaks on empty slots like null children. That's
15333 // unfortunate because it triggers the slow path all the time. We need
15334 // a better way to communicate whether this was a miss or null,
15335 // boolean, undefined, etc.
15336 if (oldFiber === null) {
15337 oldFiber = nextOldFiber;
15338 }
15339
15340 break;
15341 }
15342
15343 if (shouldTrackSideEffects) {
15344 if (oldFiber && newFiber.alternate === null) {
15345 // We matched the slot, but we didn't reuse the existing fiber, so we
15346 // need to delete the existing child.
15347 deleteChild(returnFiber, oldFiber);
15348 }
15349 }
15350
15351 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
15352
15353 if (previousNewFiber === null) {
15354 // TODO: Move out of the loop. This only happens for the first run.
15355 resultingFirstChild = newFiber;
15356 } else {
15357 // TODO: Defer siblings if we're not at the right index for this slot.
15358 // I.e. if we had null values before, then we want to defer this
15359 // for each null value. However, we also don't want to call updateSlot
15360 // with the previous one.
15361 previousNewFiber.sibling = newFiber;
15362 }
15363
15364 previousNewFiber = newFiber;
15365 oldFiber = nextOldFiber;
15366 }
15367
15368 if (newIdx === newChildren.length) {
15369 // We've reached the end of the new children. We can delete the rest.
15370 deleteRemainingChildren(returnFiber, oldFiber);
15371 return resultingFirstChild;
15372 }
15373
15374 if (oldFiber === null) {
15375 // If we don't have any more existing children we can choose a fast path
15376 // since the rest will all be insertions.
15377 for (; newIdx < newChildren.length; newIdx++) {
15378 var _newFiber = createChild(returnFiber, newChildren[newIdx], expirationTime);
15379
15380 if (_newFiber === null) {
15381 continue;
15382 }
15383
15384 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
15385
15386 if (previousNewFiber === null) {
15387 // TODO: Move out of the loop. This only happens for the first run.
15388 resultingFirstChild = _newFiber;
15389 } else {
15390 previousNewFiber.sibling = _newFiber;
15391 }
15392
15393 previousNewFiber = _newFiber;
15394 }
15395
15396 return resultingFirstChild;
15397 } // Add all children to a key map for quick lookups.
15398
15399
15400 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
15401
15402 for (; newIdx < newChildren.length; newIdx++) {
15403 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], expirationTime);
15404
15405 if (_newFiber2 !== null) {
15406 if (shouldTrackSideEffects) {
15407 if (_newFiber2.alternate !== null) {
15408 // The new fiber is a work in progress, but if there exists a
15409 // current, that means that we reused the fiber. We need to delete
15410 // it from the child list so that we don't add it to the deletion
15411 // list.
15412 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
15413 }
15414 }
15415
15416 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
15417
15418 if (previousNewFiber === null) {
15419 resultingFirstChild = _newFiber2;
15420 } else {
15421 previousNewFiber.sibling = _newFiber2;
15422 }
15423
15424 previousNewFiber = _newFiber2;
15425 }
15426 }
15427
15428 if (shouldTrackSideEffects) {
15429 // Any existing children that weren't consumed above were deleted. We need
15430 // to add them to the deletion list.
15431 existingChildren.forEach(function (child) {
15432 return deleteChild(returnFiber, child);
15433 });
15434 }
15435
15436 return resultingFirstChild;
15437 }
15438
15439 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, expirationTime) {
15440 // This is the same implementation as reconcileChildrenArray(),
15441 // but using the iterator instead.
15442 var iteratorFn = getIteratorFn(newChildrenIterable);
15443
15444 if (!(typeof iteratorFn === 'function')) {
15445 {
15446 throw Error("An object is not an iterable. This error is likely caused by a bug in React. Please file an issue.");
15447 }
15448 }
15449
15450 {
15451 // We don't support rendering Generators because it's a mutation.
15452 // See https://github.com/facebook/react/issues/12995
15453 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
15454 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
15455 !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;
15456 didWarnAboutGenerators = true;
15457 } // Warn about using Maps as children
15458
15459
15460 if (newChildrenIterable.entries === iteratorFn) {
15461 !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;
15462 didWarnAboutMaps = true;
15463 } // First, validate keys.
15464 // We'll get a different iterator later for the main pass.
15465
15466
15467 var _newChildren = iteratorFn.call(newChildrenIterable);
15468
15469 if (_newChildren) {
15470 var knownKeys = null;
15471
15472 var _step = _newChildren.next();
15473
15474 for (; !_step.done; _step = _newChildren.next()) {
15475 var child = _step.value;
15476 knownKeys = warnOnInvalidKey(child, knownKeys);
15477 }
15478 }
15479 }
15480
15481 var newChildren = iteratorFn.call(newChildrenIterable);
15482
15483 if (!(newChildren != null)) {
15484 {
15485 throw Error("An iterable object provided no iterator.");
15486 }
15487 }
15488
15489 var resultingFirstChild = null;
15490 var previousNewFiber = null;
15491 var oldFiber = currentFirstChild;
15492 var lastPlacedIndex = 0;
15493 var newIdx = 0;
15494 var nextOldFiber = null;
15495 var step = newChildren.next();
15496
15497 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
15498 if (oldFiber.index > newIdx) {
15499 nextOldFiber = oldFiber;
15500 oldFiber = null;
15501 } else {
15502 nextOldFiber = oldFiber.sibling;
15503 }
15504
15505 var newFiber = updateSlot(returnFiber, oldFiber, step.value, expirationTime);
15506
15507 if (newFiber === null) {
15508 // TODO: This breaks on empty slots like null children. That's
15509 // unfortunate because it triggers the slow path all the time. We need
15510 // a better way to communicate whether this was a miss or null,
15511 // boolean, undefined, etc.
15512 if (oldFiber === null) {
15513 oldFiber = nextOldFiber;
15514 }
15515
15516 break;
15517 }
15518
15519 if (shouldTrackSideEffects) {
15520 if (oldFiber && newFiber.alternate === null) {
15521 // We matched the slot, but we didn't reuse the existing fiber, so we
15522 // need to delete the existing child.
15523 deleteChild(returnFiber, oldFiber);
15524 }
15525 }
15526
15527 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
15528
15529 if (previousNewFiber === null) {
15530 // TODO: Move out of the loop. This only happens for the first run.
15531 resultingFirstChild = newFiber;
15532 } else {
15533 // TODO: Defer siblings if we're not at the right index for this slot.
15534 // I.e. if we had null values before, then we want to defer this
15535 // for each null value. However, we also don't want to call updateSlot
15536 // with the previous one.
15537 previousNewFiber.sibling = newFiber;
15538 }
15539
15540 previousNewFiber = newFiber;
15541 oldFiber = nextOldFiber;
15542 }
15543
15544 if (step.done) {
15545 // We've reached the end of the new children. We can delete the rest.
15546 deleteRemainingChildren(returnFiber, oldFiber);
15547 return resultingFirstChild;
15548 }
15549
15550 if (oldFiber === null) {
15551 // If we don't have any more existing children we can choose a fast path
15552 // since the rest will all be insertions.
15553 for (; !step.done; newIdx++, step = newChildren.next()) {
15554 var _newFiber3 = createChild(returnFiber, step.value, expirationTime);
15555
15556 if (_newFiber3 === null) {
15557 continue;
15558 }
15559
15560 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
15561
15562 if (previousNewFiber === null) {
15563 // TODO: Move out of the loop. This only happens for the first run.
15564 resultingFirstChild = _newFiber3;
15565 } else {
15566 previousNewFiber.sibling = _newFiber3;
15567 }
15568
15569 previousNewFiber = _newFiber3;
15570 }
15571
15572 return resultingFirstChild;
15573 } // Add all children to a key map for quick lookups.
15574
15575
15576 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
15577
15578 for (; !step.done; newIdx++, step = newChildren.next()) {
15579 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, expirationTime);
15580
15581 if (_newFiber4 !== null) {
15582 if (shouldTrackSideEffects) {
15583 if (_newFiber4.alternate !== null) {
15584 // The new fiber is a work in progress, but if there exists a
15585 // current, that means that we reused the fiber. We need to delete
15586 // it from the child list so that we don't add it to the deletion
15587 // list.
15588 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
15589 }
15590 }
15591
15592 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
15593
15594 if (previousNewFiber === null) {
15595 resultingFirstChild = _newFiber4;
15596 } else {
15597 previousNewFiber.sibling = _newFiber4;
15598 }
15599
15600 previousNewFiber = _newFiber4;
15601 }
15602 }
15603
15604 if (shouldTrackSideEffects) {
15605 // Any existing children that weren't consumed above were deleted. We need
15606 // to add them to the deletion list.
15607 existingChildren.forEach(function (child) {
15608 return deleteChild(returnFiber, child);
15609 });
15610 }
15611
15612 return resultingFirstChild;
15613 }
15614
15615 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, expirationTime) {
15616 // There's no need to check for keys on text nodes since we don't have a
15617 // way to define them.
15618 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
15619 // We already have an existing node so let's just update it and delete
15620 // the rest.
15621 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
15622 var existing = useFiber(currentFirstChild, textContent, expirationTime);
15623 existing.return = returnFiber;
15624 return existing;
15625 } // The existing first child is not a text node so we need to create one
15626 // and delete the existing ones.
15627
15628
15629 deleteRemainingChildren(returnFiber, currentFirstChild);
15630 var created = createFiberFromText(textContent, returnFiber.mode, expirationTime);
15631 created.return = returnFiber;
15632 return created;
15633 }
15634
15635 function reconcileSingleElement(returnFiber, currentFirstChild, element, expirationTime) {
15636 var key = element.key;
15637 var child = currentFirstChild;
15638
15639 while (child !== null) {
15640 // TODO: If key === null and child.key === null, then this only applies to
15641 // the first item in the list.
15642 if (child.key === key) {
15643 if (child.tag === Fragment ? element.type === REACT_FRAGMENT_TYPE : child.elementType === element.type || ( // Keep this check inline so it only runs on the false path:
15644 isCompatibleFamilyForHotReloading(child, element))) {
15645 deleteRemainingChildren(returnFiber, child.sibling);
15646 var existing = useFiber(child, element.type === REACT_FRAGMENT_TYPE ? element.props.children : element.props, expirationTime);
15647 existing.ref = coerceRef(returnFiber, child, element);
15648 existing.return = returnFiber;
15649
15650 {
15651 existing._debugSource = element._source;
15652 existing._debugOwner = element._owner;
15653 }
15654
15655 return existing;
15656 } else {
15657 deleteRemainingChildren(returnFiber, child);
15658 break;
15659 }
15660 } else {
15661 deleteChild(returnFiber, child);
15662 }
15663
15664 child = child.sibling;
15665 }
15666
15667 if (element.type === REACT_FRAGMENT_TYPE) {
15668 var created = createFiberFromFragment(element.props.children, returnFiber.mode, expirationTime, element.key);
15669 created.return = returnFiber;
15670 return created;
15671 } else {
15672 var _created4 = createFiberFromElement(element, returnFiber.mode, expirationTime);
15673
15674 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
15675 _created4.return = returnFiber;
15676 return _created4;
15677 }
15678 }
15679
15680 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, expirationTime) {
15681 var key = portal.key;
15682 var child = currentFirstChild;
15683
15684 while (child !== null) {
15685 // TODO: If key === null and child.key === null, then this only applies to
15686 // the first item in the list.
15687 if (child.key === key) {
15688 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
15689 deleteRemainingChildren(returnFiber, child.sibling);
15690 var existing = useFiber(child, portal.children || [], expirationTime);
15691 existing.return = returnFiber;
15692 return existing;
15693 } else {
15694 deleteRemainingChildren(returnFiber, child);
15695 break;
15696 }
15697 } else {
15698 deleteChild(returnFiber, child);
15699 }
15700
15701 child = child.sibling;
15702 }
15703
15704 var created = createFiberFromPortal(portal, returnFiber.mode, expirationTime);
15705 created.return = returnFiber;
15706 return created;
15707 } // This API will tag the children with the side-effect of the reconciliation
15708 // itself. They will be added to the side-effect list as we pass through the
15709 // children and the parent.
15710
15711
15712 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, expirationTime) {
15713 // This function is not recursive.
15714 // If the top level item is an array, we treat it as a set of children,
15715 // not as a fragment. Nested arrays on the other hand will be treated as
15716 // fragment nodes. Recursion happens at the normal flow.
15717 // Handle top level unkeyed fragments as if they were arrays.
15718 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
15719 // We treat the ambiguous cases above the same.
15720 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
15721
15722 if (isUnkeyedTopLevelFragment) {
15723 newChild = newChild.props.children;
15724 } // Handle object types
15725
15726
15727 var isObject = typeof newChild === 'object' && newChild !== null;
15728
15729 if (isObject) {
15730 switch (newChild.$$typeof) {
15731 case REACT_ELEMENT_TYPE:
15732 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, expirationTime));
15733
15734 case REACT_PORTAL_TYPE:
15735 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, expirationTime));
15736 }
15737 }
15738
15739 if (typeof newChild === 'string' || typeof newChild === 'number') {
15740 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, expirationTime));
15741 }
15742
15743 if (isArray(newChild)) {
15744 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, expirationTime);
15745 }
15746
15747 if (getIteratorFn(newChild)) {
15748 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, expirationTime);
15749 }
15750
15751 if (isObject) {
15752 throwOnInvalidObjectType(returnFiber, newChild);
15753 }
15754
15755 {
15756 if (typeof newChild === 'function') {
15757 warnOnFunctionType();
15758 }
15759 }
15760
15761 if (typeof newChild === 'undefined' && !isUnkeyedTopLevelFragment) {
15762 // If the new child is undefined, and the return fiber is a composite
15763 // component, throw an error. If Fiber return types are disabled,
15764 // we already threw above.
15765 switch (returnFiber.tag) {
15766 case ClassComponent:
15767 {
15768 {
15769 var instance = returnFiber.stateNode;
15770
15771 if (instance.render._isMockFunction) {
15772 // We allow auto-mocks to proceed as if they're returning null.
15773 break;
15774 }
15775 }
15776 }
15777 // Intentionally fall through to the next case, which handles both
15778 // functions and classes
15779 // eslint-disable-next-lined no-fallthrough
15780
15781 case FunctionComponent:
15782 {
15783 var Component = returnFiber.type;
15784
15785 {
15786 {
15787 throw Error((Component.displayName || Component.name || 'Component') + "(...): Nothing was returned from render. This usually means a return statement is missing. Or, to render nothing, return null.");
15788 }
15789 }
15790 }
15791 }
15792 } // Remaining cases are all treated as empty.
15793
15794
15795 return deleteRemainingChildren(returnFiber, currentFirstChild);
15796 }
15797
15798 return reconcileChildFibers;
15799}
15800
15801var reconcileChildFibers = ChildReconciler(true);
15802var mountChildFibers = ChildReconciler(false);
15803function cloneChildFibers(current$$1, workInProgress) {
15804 if (!(current$$1 === null || workInProgress.child === current$$1.child)) {
15805 {
15806 throw Error("Resuming work not yet implemented.");
15807 }
15808 }
15809
15810 if (workInProgress.child === null) {
15811 return;
15812 }
15813
15814 var currentChild = workInProgress.child;
15815 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
15816 workInProgress.child = newChild;
15817 newChild.return = workInProgress;
15818
15819 while (currentChild.sibling !== null) {
15820 currentChild = currentChild.sibling;
15821 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps, currentChild.expirationTime);
15822 newChild.return = workInProgress;
15823 }
15824
15825 newChild.sibling = null;
15826} // Reset a workInProgress child set to prepare it for a second pass.
15827
15828function resetChildFibers(workInProgress, renderExpirationTime) {
15829 var child = workInProgress.child;
15830
15831 while (child !== null) {
15832 resetWorkInProgress(child, renderExpirationTime);
15833 child = child.sibling;
15834 }
15835}
15836
15837var NO_CONTEXT = {};
15838var contextStackCursor$1 = createCursor(NO_CONTEXT);
15839var contextFiberStackCursor = createCursor(NO_CONTEXT);
15840var rootInstanceStackCursor = createCursor(NO_CONTEXT);
15841
15842function requiredContext(c) {
15843 if (!(c !== NO_CONTEXT)) {
15844 {
15845 throw Error("Expected host context to exist. This error is likely caused by a bug in React. Please file an issue.");
15846 }
15847 }
15848
15849 return c;
15850}
15851
15852function getRootHostContainer() {
15853 var rootInstance = requiredContext(rootInstanceStackCursor.current);
15854 return rootInstance;
15855}
15856
15857function pushHostContainer(fiber, nextRootInstance) {
15858 // Push current root instance onto the stack;
15859 // This allows us to reset root when portals are popped.
15860 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
15861 // This enables us to pop only Fibers that provide unique contexts.
15862
15863 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
15864 // However, we can't just call getRootHostContext() and push it because
15865 // we'd have a different number of entries on the stack depending on
15866 // whether getRootHostContext() throws somewhere in renderer code or not.
15867 // So we push an empty value first. This lets us safely unwind on errors.
15868
15869 push(contextStackCursor$1, NO_CONTEXT, fiber);
15870 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
15871
15872 pop(contextStackCursor$1, fiber);
15873 push(contextStackCursor$1, nextRootContext, fiber);
15874}
15875
15876function popHostContainer(fiber) {
15877 pop(contextStackCursor$1, fiber);
15878 pop(contextFiberStackCursor, fiber);
15879 pop(rootInstanceStackCursor, fiber);
15880}
15881
15882function getHostContext() {
15883 var context = requiredContext(contextStackCursor$1.current);
15884 return context;
15885}
15886
15887function pushHostContext(fiber) {
15888 var rootInstance = requiredContext(rootInstanceStackCursor.current);
15889 var context = requiredContext(contextStackCursor$1.current);
15890 var nextContext = getChildHostContext(context, fiber.type, rootInstance); // Don't push this Fiber's context unless it's unique.
15891
15892 if (context === nextContext) {
15893 return;
15894 } // Track the context and the Fiber that provided it.
15895 // This enables us to pop only Fibers that provide unique contexts.
15896
15897
15898 push(contextFiberStackCursor, fiber, fiber);
15899 push(contextStackCursor$1, nextContext, fiber);
15900}
15901
15902function popHostContext(fiber) {
15903 // Do not pop unless this Fiber provided the current context.
15904 // pushHostContext() only pushes Fibers that provide unique contexts.
15905 if (contextFiberStackCursor.current !== fiber) {
15906 return;
15907 }
15908
15909 pop(contextStackCursor$1, fiber);
15910 pop(contextFiberStackCursor, fiber);
15911}
15912
15913var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
15914// inherited deeply down the subtree. The upper bits only affect
15915// this immediate suspense boundary and gets reset each new
15916// boundary or suspense list.
15917
15918var SubtreeSuspenseContextMask = 1; // Subtree Flags:
15919// InvisibleParentSuspenseContext indicates that one of our parent Suspense
15920// boundaries is not currently showing visible main content.
15921// Either because it is already showing a fallback or is not mounted at all.
15922// We can use this to determine if it is desirable to trigger a fallback at
15923// the parent. If not, then we might need to trigger undesirable boundaries
15924// and/or suspend the commit to avoid hiding the parent content.
15925
15926var InvisibleParentSuspenseContext = 1; // Shallow Flags:
15927// ForceSuspenseFallback can be used by SuspenseList to force newly added
15928// items into their fallback state during one of the render passes.
15929
15930var ForceSuspenseFallback = 2;
15931var suspenseStackCursor = createCursor(DefaultSuspenseContext);
15932function hasSuspenseContext(parentContext, flag) {
15933 return (parentContext & flag) !== 0;
15934}
15935function setDefaultShallowSuspenseContext(parentContext) {
15936 return parentContext & SubtreeSuspenseContextMask;
15937}
15938function setShallowSuspenseContext(parentContext, shallowContext) {
15939 return parentContext & SubtreeSuspenseContextMask | shallowContext;
15940}
15941function addSubtreeSuspenseContext(parentContext, subtreeContext) {
15942 return parentContext | subtreeContext;
15943}
15944function pushSuspenseContext(fiber, newContext) {
15945 push(suspenseStackCursor, newContext, fiber);
15946}
15947function popSuspenseContext(fiber) {
15948 pop(suspenseStackCursor, fiber);
15949}
15950
15951function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
15952 // If it was the primary children that just suspended, capture and render the
15953 // fallback. Otherwise, don't capture and bubble to the next boundary.
15954 var nextState = workInProgress.memoizedState;
15955
15956 if (nextState !== null) {
15957 if (nextState.dehydrated !== null) {
15958 // A dehydrated boundary always captures.
15959 return true;
15960 }
15961
15962 return false;
15963 }
15964
15965 var props = workInProgress.memoizedProps; // In order to capture, the Suspense component must have a fallback prop.
15966
15967 if (props.fallback === undefined) {
15968 return false;
15969 } // Regular boundaries always capture.
15970
15971
15972 if (props.unstable_avoidThisFallback !== true) {
15973 return true;
15974 } // If it's a boundary we should avoid, then we prefer to bubble up to the
15975 // parent boundary if it is currently invisible.
15976
15977
15978 if (hasInvisibleParent) {
15979 return false;
15980 } // If the parent is not able to handle it, we must handle it.
15981
15982
15983 return true;
15984}
15985function findFirstSuspended(row) {
15986 var node = row;
15987
15988 while (node !== null) {
15989 if (node.tag === SuspenseComponent) {
15990 var state = node.memoizedState;
15991
15992 if (state !== null) {
15993 var dehydrated = state.dehydrated;
15994
15995 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
15996 return node;
15997 }
15998 }
15999 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
16000 // keep track of whether it suspended or not.
16001 node.memoizedProps.revealOrder !== undefined) {
16002 var didSuspend = (node.effectTag & DidCapture) !== NoEffect;
16003
16004 if (didSuspend) {
16005 return node;
16006 }
16007 } else if (node.child !== null) {
16008 node.child.return = node;
16009 node = node.child;
16010 continue;
16011 }
16012
16013 if (node === row) {
16014 return null;
16015 }
16016
16017 while (node.sibling === null) {
16018 if (node.return === null || node.return === row) {
16019 return null;
16020 }
16021
16022 node = node.return;
16023 }
16024
16025 node.sibling.return = node.return;
16026 node = node.sibling;
16027 }
16028
16029 return null;
16030}
16031
16032var emptyObject = {};
16033var isArray$2 = Array.isArray;
16034function createResponderInstance(responder, responderProps, responderState, fiber) {
16035 return {
16036 fiber: fiber,
16037 props: responderProps,
16038 responder: responder,
16039 rootEventTypes: null,
16040 state: responderState
16041 };
16042}
16043
16044function mountEventResponder$1(responder, responderProps, fiber, respondersMap, rootContainerInstance) {
16045 var responderState = emptyObject;
16046 var getInitialState = responder.getInitialState;
16047
16048 if (getInitialState !== null) {
16049 responderState = getInitialState(responderProps);
16050 }
16051
16052 var responderInstance = createResponderInstance(responder, responderProps, responderState, fiber);
16053
16054 if (!rootContainerInstance) {
16055 var node = fiber;
16056
16057 while (node !== null) {
16058 var tag = node.tag;
16059
16060 if (tag === HostComponent) {
16061 rootContainerInstance = node.stateNode;
16062 break;
16063 } else if (tag === HostRoot) {
16064 rootContainerInstance = node.stateNode.containerInfo;
16065 break;
16066 }
16067
16068 node = node.return;
16069 }
16070 }
16071
16072 mountResponderInstance(responder, responderInstance, responderProps, responderState, rootContainerInstance);
16073 respondersMap.set(responder, responderInstance);
16074}
16075
16076function updateEventListener(listener, fiber, visistedResponders, respondersMap, rootContainerInstance) {
16077 var responder;
16078 var props;
16079
16080 if (listener) {
16081 responder = listener.responder;
16082 props = listener.props;
16083 }
16084
16085 if (!(responder && responder.$$typeof === REACT_RESPONDER_TYPE)) {
16086 {
16087 throw Error("An invalid value was used as an event listener. Expect one or many event listeners created via React.unstable_useResponder().");
16088 }
16089 }
16090
16091 var listenerProps = props;
16092
16093 if (visistedResponders.has(responder)) {
16094 // show warning
16095 {
16096 warning$1(false, 'Duplicate event responder "%s" found in event listeners. ' + 'Event listeners passed to elements cannot use the same event responder more than once.', responder.displayName);
16097 }
16098
16099 return;
16100 }
16101
16102 visistedResponders.add(responder);
16103 var responderInstance = respondersMap.get(responder);
16104
16105 if (responderInstance === undefined) {
16106 // Mount (happens in either complete or commit phase)
16107 mountEventResponder$1(responder, listenerProps, fiber, respondersMap, rootContainerInstance);
16108 } else {
16109 // Update (happens during commit phase only)
16110 responderInstance.props = listenerProps;
16111 responderInstance.fiber = fiber;
16112 }
16113}
16114
16115function updateEventListeners(listeners, fiber, rootContainerInstance) {
16116 var visistedResponders = new Set();
16117 var dependencies = fiber.dependencies;
16118
16119 if (listeners != null) {
16120 if (dependencies === null) {
16121 dependencies = fiber.dependencies = {
16122 expirationTime: NoWork,
16123 firstContext: null,
16124 responders: new Map()
16125 };
16126 }
16127
16128 var respondersMap = dependencies.responders;
16129
16130 if (respondersMap === null) {
16131 respondersMap = new Map();
16132 }
16133
16134 if (isArray$2(listeners)) {
16135 for (var i = 0, length = listeners.length; i < length; i++) {
16136 var listener = listeners[i];
16137 updateEventListener(listener, fiber, visistedResponders, respondersMap, rootContainerInstance);
16138 }
16139 } else {
16140 updateEventListener(listeners, fiber, visistedResponders, respondersMap, rootContainerInstance);
16141 }
16142 }
16143
16144 if (dependencies !== null) {
16145 var _respondersMap = dependencies.responders;
16146
16147 if (_respondersMap !== null) {
16148 // Unmount
16149 var mountedResponders = Array.from(_respondersMap.keys());
16150
16151 for (var _i = 0, _length = mountedResponders.length; _i < _length; _i++) {
16152 var mountedResponder = mountedResponders[_i];
16153
16154 if (!visistedResponders.has(mountedResponder)) {
16155 var responderInstance = _respondersMap.get(mountedResponder);
16156
16157 unmountResponderInstance(responderInstance);
16158
16159 _respondersMap.delete(mountedResponder);
16160 }
16161 }
16162 }
16163 }
16164}
16165function createResponderListener(responder, props) {
16166 var eventResponderListener = {
16167 responder: responder,
16168 props: props
16169 };
16170
16171 {
16172 Object.freeze(eventResponderListener);
16173 }
16174
16175 return eventResponderListener;
16176}
16177
16178var NoEffect$1 =
16179/* */
161800;
16181var UnmountSnapshot =
16182/* */
161832;
16184var UnmountMutation =
16185/* */
161864;
16187var MountMutation =
16188/* */
161898;
16190var UnmountLayout =
16191/* */
1619216;
16193var MountLayout =
16194/* */
1619532;
16196var MountPassive =
16197/* */
1619864;
16199var UnmountPassive =
16200/* */
16201128;
16202
16203var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher;
16204var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
16205var didWarnAboutMismatchedHooksForComponent;
16206
16207{
16208 didWarnAboutMismatchedHooksForComponent = new Set();
16209}
16210
16211// These are set right before calling the component.
16212var renderExpirationTime$1 = NoWork; // The work-in-progress fiber. I've named it differently to distinguish it from
16213// the work-in-progress hook.
16214
16215var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
16216// current hook list is the list that belongs to the current fiber. The
16217// work-in-progress hook list is a new list that will be added to the
16218// work-in-progress fiber.
16219
16220var currentHook = null;
16221var nextCurrentHook = null;
16222var firstWorkInProgressHook = null;
16223var workInProgressHook = null;
16224var nextWorkInProgressHook = null;
16225var remainingExpirationTime = NoWork;
16226var componentUpdateQueue = null;
16227var sideEffectTag = 0; // Updates scheduled during render will trigger an immediate re-render at the
16228// end of the current pass. We can't store these updates on the normal queue,
16229// because if the work is aborted, they should be discarded. Because this is
16230// a relatively rare case, we also don't want to add an additional field to
16231// either the hook or queue object types. So we store them in a lazily create
16232// map of queue -> render-phase updates, which are discarded once the component
16233// completes without re-rendering.
16234// Whether an update was scheduled during the currently executing render pass.
16235
16236var didScheduleRenderPhaseUpdate = false; // Lazily created map of render-phase updates
16237
16238var renderPhaseUpdates = null; // Counter to prevent infinite loops.
16239
16240var numberOfReRenders = 0;
16241var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
16242
16243var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
16244// The list stores the order of hooks used during the initial render (mount).
16245// Subsequent renders (updates) reference this list.
16246
16247var hookTypesDev = null;
16248var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
16249// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
16250// When true, such Hooks will always be "remounted". Only used during hot reload.
16251
16252var ignorePreviousDependencies = false;
16253
16254function mountHookTypesDev() {
16255 {
16256 var hookName = currentHookNameInDev;
16257
16258 if (hookTypesDev === null) {
16259 hookTypesDev = [hookName];
16260 } else {
16261 hookTypesDev.push(hookName);
16262 }
16263 }
16264}
16265
16266function updateHookTypesDev() {
16267 {
16268 var hookName = currentHookNameInDev;
16269
16270 if (hookTypesDev !== null) {
16271 hookTypesUpdateIndexDev++;
16272
16273 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
16274 warnOnHookMismatchInDev(hookName);
16275 }
16276 }
16277 }
16278}
16279
16280function checkDepsAreArrayDev(deps) {
16281 {
16282 if (deps !== undefined && deps !== null && !Array.isArray(deps)) {
16283 // Verify deps, but only on mount to avoid extra checks.
16284 // It's unlikely their type would change as usually you define them inline.
16285 warning$1(false, '%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
16286 }
16287 }
16288}
16289
16290function warnOnHookMismatchInDev(currentHookName) {
16291 {
16292 var componentName = getComponentName(currentlyRenderingFiber$1.type);
16293
16294 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
16295 didWarnAboutMismatchedHooksForComponent.add(componentName);
16296
16297 if (hookTypesDev !== null) {
16298 var table = '';
16299 var secondColumnStart = 30;
16300
16301 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
16302 var oldHookName = hookTypesDev[i];
16303 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
16304 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
16305 // lol @ IE not supporting String#repeat
16306
16307 while (row.length < secondColumnStart) {
16308 row += ' ';
16309 }
16310
16311 row += newHookName + '\n';
16312 table += row;
16313 }
16314
16315 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);
16316 }
16317 }
16318 }
16319}
16320
16321function throwInvalidHookError() {
16322 {
16323 {
16324 throw Error("Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:\n1. You might have mismatching versions of React and the renderer (such as React DOM)\n2. You might be breaking the Rules of Hooks\n3. You might have more than one copy of React in the same app\nSee https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.");
16325 }
16326 }
16327}
16328
16329function areHookInputsEqual(nextDeps, prevDeps) {
16330 {
16331 if (ignorePreviousDependencies) {
16332 // Only true when this component is being hot reloaded.
16333 return false;
16334 }
16335 }
16336
16337 if (prevDeps === null) {
16338 {
16339 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);
16340 }
16341
16342 return false;
16343 }
16344
16345 {
16346 // Don't bother comparing lengths in prod because these arrays should be
16347 // passed inline.
16348 if (nextDeps.length !== prevDeps.length) {
16349 warning$1(false, 'The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
16350 }
16351 }
16352
16353 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
16354 if (is$1(nextDeps[i], prevDeps[i])) {
16355 continue;
16356 }
16357
16358 return false;
16359 }
16360
16361 return true;
16362}
16363
16364function renderWithHooks(current, workInProgress, Component, props, refOrContext, nextRenderExpirationTime) {
16365 renderExpirationTime$1 = nextRenderExpirationTime;
16366 currentlyRenderingFiber$1 = workInProgress;
16367 nextCurrentHook = current !== null ? current.memoizedState : null;
16368
16369 {
16370 hookTypesDev = current !== null ? current._debugHookTypes : null;
16371 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
16372
16373 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
16374 } // The following should have already been reset
16375 // currentHook = null;
16376 // workInProgressHook = null;
16377 // remainingExpirationTime = NoWork;
16378 // componentUpdateQueue = null;
16379 // didScheduleRenderPhaseUpdate = false;
16380 // renderPhaseUpdates = null;
16381 // numberOfReRenders = 0;
16382 // sideEffectTag = 0;
16383 // TODO Warn if no hooks are used at all during mount, then some are used during update.
16384 // Currently we will identify the update render as a mount because nextCurrentHook === null.
16385 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
16386 // Using nextCurrentHook to differentiate between mount/update only works if at least one stateful hook is used.
16387 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
16388 // so nextCurrentHook would be null during updates and mounts.
16389
16390
16391 {
16392 if (nextCurrentHook !== null) {
16393 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
16394 } else if (hookTypesDev !== null) {
16395 // This dispatcher handles an edge case where a component is updating,
16396 // but no stateful hooks have been used.
16397 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
16398 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
16399 // This dispatcher does that.
16400 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
16401 } else {
16402 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
16403 }
16404 }
16405
16406 var children = Component(props, refOrContext);
16407
16408 if (didScheduleRenderPhaseUpdate) {
16409 do {
16410 didScheduleRenderPhaseUpdate = false;
16411 numberOfReRenders += 1;
16412
16413 {
16414 // Even when hot reloading, allow dependencies to stabilize
16415 // after first render to prevent infinite render phase updates.
16416 ignorePreviousDependencies = false;
16417 } // Start over from the beginning of the list
16418
16419
16420 nextCurrentHook = current !== null ? current.memoizedState : null;
16421 nextWorkInProgressHook = firstWorkInProgressHook;
16422 currentHook = null;
16423 workInProgressHook = null;
16424 componentUpdateQueue = null;
16425
16426 {
16427 // Also validate hook order for cascading updates.
16428 hookTypesUpdateIndexDev = -1;
16429 }
16430
16431 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
16432 children = Component(props, refOrContext);
16433 } while (didScheduleRenderPhaseUpdate);
16434
16435 renderPhaseUpdates = null;
16436 numberOfReRenders = 0;
16437 } // We can assume the previous dispatcher is always this one, since we set it
16438 // at the beginning of the render phase and there's no re-entrancy.
16439
16440
16441 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
16442 var renderedWork = currentlyRenderingFiber$1;
16443 renderedWork.memoizedState = firstWorkInProgressHook;
16444 renderedWork.expirationTime = remainingExpirationTime;
16445 renderedWork.updateQueue = componentUpdateQueue;
16446 renderedWork.effectTag |= sideEffectTag;
16447
16448 {
16449 renderedWork._debugHookTypes = hookTypesDev;
16450 } // This check uses currentHook so that it works the same in DEV and prod bundles.
16451 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
16452
16453
16454 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
16455 renderExpirationTime$1 = NoWork;
16456 currentlyRenderingFiber$1 = null;
16457 currentHook = null;
16458 nextCurrentHook = null;
16459 firstWorkInProgressHook = null;
16460 workInProgressHook = null;
16461 nextWorkInProgressHook = null;
16462
16463 {
16464 currentHookNameInDev = null;
16465 hookTypesDev = null;
16466 hookTypesUpdateIndexDev = -1;
16467 }
16468
16469 remainingExpirationTime = NoWork;
16470 componentUpdateQueue = null;
16471 sideEffectTag = 0; // These were reset above
16472 // didScheduleRenderPhaseUpdate = false;
16473 // renderPhaseUpdates = null;
16474 // numberOfReRenders = 0;
16475
16476 if (!!didRenderTooFewHooks) {
16477 {
16478 throw Error("Rendered fewer hooks than expected. This may be caused by an accidental early return statement.");
16479 }
16480 }
16481
16482 return children;
16483}
16484function bailoutHooks(current, workInProgress, expirationTime) {
16485 workInProgress.updateQueue = current.updateQueue;
16486 workInProgress.effectTag &= ~(Passive | Update);
16487
16488 if (current.expirationTime <= expirationTime) {
16489 current.expirationTime = NoWork;
16490 }
16491}
16492function resetHooks() {
16493 // We can assume the previous dispatcher is always this one, since we set it
16494 // at the beginning of the render phase and there's no re-entrancy.
16495 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher; // This is used to reset the state of this module when a component throws.
16496 // It's also called inside mountIndeterminateComponent if we determine the
16497 // component is a module-style component.
16498
16499 renderExpirationTime$1 = NoWork;
16500 currentlyRenderingFiber$1 = null;
16501 currentHook = null;
16502 nextCurrentHook = null;
16503 firstWorkInProgressHook = null;
16504 workInProgressHook = null;
16505 nextWorkInProgressHook = null;
16506
16507 {
16508 hookTypesDev = null;
16509 hookTypesUpdateIndexDev = -1;
16510 currentHookNameInDev = null;
16511 }
16512
16513 remainingExpirationTime = NoWork;
16514 componentUpdateQueue = null;
16515 sideEffectTag = 0;
16516 didScheduleRenderPhaseUpdate = false;
16517 renderPhaseUpdates = null;
16518 numberOfReRenders = 0;
16519}
16520
16521function mountWorkInProgressHook() {
16522 var hook = {
16523 memoizedState: null,
16524 baseState: null,
16525 queue: null,
16526 baseUpdate: null,
16527 next: null
16528 };
16529
16530 if (workInProgressHook === null) {
16531 // This is the first hook in the list
16532 firstWorkInProgressHook = workInProgressHook = hook;
16533 } else {
16534 // Append to the end of the list
16535 workInProgressHook = workInProgressHook.next = hook;
16536 }
16537
16538 return workInProgressHook;
16539}
16540
16541function updateWorkInProgressHook() {
16542 // This function is used both for updates and for re-renders triggered by a
16543 // render phase update. It assumes there is either a current hook we can
16544 // clone, or a work-in-progress hook from a previous render pass that we can
16545 // use as a base. When we reach the end of the base list, we must switch to
16546 // the dispatcher used for mounts.
16547 if (nextWorkInProgressHook !== null) {
16548 // There's already a work-in-progress. Reuse it.
16549 workInProgressHook = nextWorkInProgressHook;
16550 nextWorkInProgressHook = workInProgressHook.next;
16551 currentHook = nextCurrentHook;
16552 nextCurrentHook = currentHook !== null ? currentHook.next : null;
16553 } else {
16554 // Clone from the current hook.
16555 if (!(nextCurrentHook !== null)) {
16556 {
16557 throw Error("Rendered more hooks than during the previous render.");
16558 }
16559 }
16560
16561 currentHook = nextCurrentHook;
16562 var newHook = {
16563 memoizedState: currentHook.memoizedState,
16564 baseState: currentHook.baseState,
16565 queue: currentHook.queue,
16566 baseUpdate: currentHook.baseUpdate,
16567 next: null
16568 };
16569
16570 if (workInProgressHook === null) {
16571 // This is the first hook in the list.
16572 workInProgressHook = firstWorkInProgressHook = newHook;
16573 } else {
16574 // Append to the end of the list.
16575 workInProgressHook = workInProgressHook.next = newHook;
16576 }
16577
16578 nextCurrentHook = currentHook.next;
16579 }
16580
16581 return workInProgressHook;
16582}
16583
16584function createFunctionComponentUpdateQueue() {
16585 return {
16586 lastEffect: null
16587 };
16588}
16589
16590function basicStateReducer(state, action) {
16591 return typeof action === 'function' ? action(state) : action;
16592}
16593
16594function mountReducer(reducer, initialArg, init) {
16595 var hook = mountWorkInProgressHook();
16596 var initialState;
16597
16598 if (init !== undefined) {
16599 initialState = init(initialArg);
16600 } else {
16601 initialState = initialArg;
16602 }
16603
16604 hook.memoizedState = hook.baseState = initialState;
16605 var queue = hook.queue = {
16606 last: null,
16607 dispatch: null,
16608 lastRenderedReducer: reducer,
16609 lastRenderedState: initialState
16610 };
16611 var dispatch = queue.dispatch = dispatchAction.bind(null, // Flow doesn't know this is non-null, but we do.
16612 currentlyRenderingFiber$1, queue);
16613 return [hook.memoizedState, dispatch];
16614}
16615
16616function updateReducer(reducer, initialArg, init) {
16617 var hook = updateWorkInProgressHook();
16618 var queue = hook.queue;
16619
16620 if (!(queue !== null)) {
16621 {
16622 throw Error("Should have a queue. This is likely a bug in React. Please file an issue.");
16623 }
16624 }
16625
16626 queue.lastRenderedReducer = reducer;
16627
16628 if (numberOfReRenders > 0) {
16629 // This is a re-render. Apply the new render phase updates to the previous
16630 // work-in-progress hook.
16631 var _dispatch = queue.dispatch;
16632
16633 if (renderPhaseUpdates !== null) {
16634 // Render phase updates are stored in a map of queue -> linked list
16635 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
16636
16637 if (firstRenderPhaseUpdate !== undefined) {
16638 renderPhaseUpdates.delete(queue);
16639 var newState = hook.memoizedState;
16640 var update = firstRenderPhaseUpdate;
16641
16642 do {
16643 // Process this render phase update. We don't have to check the
16644 // priority because it will always be the same as the current
16645 // render's.
16646 var action = update.action;
16647 newState = reducer(newState, action);
16648 update = update.next;
16649 } while (update !== null); // Mark that the fiber performed work, but only if the new state is
16650 // different from the current state.
16651
16652
16653 if (!is$1(newState, hook.memoizedState)) {
16654 markWorkInProgressReceivedUpdate();
16655 }
16656
16657 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
16658 // the base state unless the queue is empty.
16659 // TODO: Not sure if this is the desired semantics, but it's what we
16660 // do for gDSFP. I can't remember why.
16661
16662 if (hook.baseUpdate === queue.last) {
16663 hook.baseState = newState;
16664 }
16665
16666 queue.lastRenderedState = newState;
16667 return [newState, _dispatch];
16668 }
16669 }
16670
16671 return [hook.memoizedState, _dispatch];
16672 } // The last update in the entire queue
16673
16674
16675 var last = queue.last; // The last update that is part of the base state.
16676
16677 var baseUpdate = hook.baseUpdate;
16678 var baseState = hook.baseState; // Find the first unprocessed update.
16679
16680 var first;
16681
16682 if (baseUpdate !== null) {
16683 if (last !== null) {
16684 // For the first update, the queue is a circular linked list where
16685 // `queue.last.next = queue.first`. Once the first update commits, and
16686 // the `baseUpdate` is no longer empty, we can unravel the list.
16687 last.next = null;
16688 }
16689
16690 first = baseUpdate.next;
16691 } else {
16692 first = last !== null ? last.next : null;
16693 }
16694
16695 if (first !== null) {
16696 var _newState = baseState;
16697 var newBaseState = null;
16698 var newBaseUpdate = null;
16699 var prevUpdate = baseUpdate;
16700 var _update = first;
16701 var didSkip = false;
16702
16703 do {
16704 var updateExpirationTime = _update.expirationTime;
16705
16706 if (updateExpirationTime < renderExpirationTime$1) {
16707 // Priority is insufficient. Skip this update. If this is the first
16708 // skipped update, the previous update/state is the new base
16709 // update/state.
16710 if (!didSkip) {
16711 didSkip = true;
16712 newBaseUpdate = prevUpdate;
16713 newBaseState = _newState;
16714 } // Update the remaining priority in the queue.
16715
16716
16717 if (updateExpirationTime > remainingExpirationTime) {
16718 remainingExpirationTime = updateExpirationTime;
16719 markUnprocessedUpdateTime(remainingExpirationTime);
16720 }
16721 } else {
16722 // This update does have sufficient priority.
16723 // Mark the event time of this update as relevant to this render pass.
16724 // TODO: This should ideally use the true event time of this update rather than
16725 // its priority which is a derived and not reverseable value.
16726 // TODO: We should skip this update if it was already committed but currently
16727 // we have no way of detecting the difference between a committed and suspended
16728 // update here.
16729 markRenderEventTimeAndConfig(updateExpirationTime, _update.suspenseConfig); // Process this update.
16730
16731 if (_update.eagerReducer === reducer) {
16732 // If this update was processed eagerly, and its reducer matches the
16733 // current reducer, we can use the eagerly computed state.
16734 _newState = _update.eagerState;
16735 } else {
16736 var _action = _update.action;
16737 _newState = reducer(_newState, _action);
16738 }
16739 }
16740
16741 prevUpdate = _update;
16742 _update = _update.next;
16743 } while (_update !== null && _update !== first);
16744
16745 if (!didSkip) {
16746 newBaseUpdate = prevUpdate;
16747 newBaseState = _newState;
16748 } // Mark that the fiber performed work, but only if the new state is
16749 // different from the current state.
16750
16751
16752 if (!is$1(_newState, hook.memoizedState)) {
16753 markWorkInProgressReceivedUpdate();
16754 }
16755
16756 hook.memoizedState = _newState;
16757 hook.baseUpdate = newBaseUpdate;
16758 hook.baseState = newBaseState;
16759 queue.lastRenderedState = _newState;
16760 }
16761
16762 var dispatch = queue.dispatch;
16763 return [hook.memoizedState, dispatch];
16764}
16765
16766function mountState(initialState) {
16767 var hook = mountWorkInProgressHook();
16768
16769 if (typeof initialState === 'function') {
16770 initialState = initialState();
16771 }
16772
16773 hook.memoizedState = hook.baseState = initialState;
16774 var queue = hook.queue = {
16775 last: null,
16776 dispatch: null,
16777 lastRenderedReducer: basicStateReducer,
16778 lastRenderedState: initialState
16779 };
16780 var dispatch = queue.dispatch = dispatchAction.bind(null, // Flow doesn't know this is non-null, but we do.
16781 currentlyRenderingFiber$1, queue);
16782 return [hook.memoizedState, dispatch];
16783}
16784
16785function updateState(initialState) {
16786 return updateReducer(basicStateReducer, initialState);
16787}
16788
16789function pushEffect(tag, create, destroy, deps) {
16790 var effect = {
16791 tag: tag,
16792 create: create,
16793 destroy: destroy,
16794 deps: deps,
16795 // Circular
16796 next: null
16797 };
16798
16799 if (componentUpdateQueue === null) {
16800 componentUpdateQueue = createFunctionComponentUpdateQueue();
16801 componentUpdateQueue.lastEffect = effect.next = effect;
16802 } else {
16803 var lastEffect = componentUpdateQueue.lastEffect;
16804
16805 if (lastEffect === null) {
16806 componentUpdateQueue.lastEffect = effect.next = effect;
16807 } else {
16808 var firstEffect = lastEffect.next;
16809 lastEffect.next = effect;
16810 effect.next = firstEffect;
16811 componentUpdateQueue.lastEffect = effect;
16812 }
16813 }
16814
16815 return effect;
16816}
16817
16818function mountRef(initialValue) {
16819 var hook = mountWorkInProgressHook();
16820 var ref = {
16821 current: initialValue
16822 };
16823
16824 {
16825 Object.seal(ref);
16826 }
16827
16828 hook.memoizedState = ref;
16829 return ref;
16830}
16831
16832function updateRef(initialValue) {
16833 var hook = updateWorkInProgressHook();
16834 return hook.memoizedState;
16835}
16836
16837function mountEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
16838 var hook = mountWorkInProgressHook();
16839 var nextDeps = deps === undefined ? null : deps;
16840 sideEffectTag |= fiberEffectTag;
16841 hook.memoizedState = pushEffect(hookEffectTag, create, undefined, nextDeps);
16842}
16843
16844function updateEffectImpl(fiberEffectTag, hookEffectTag, create, deps) {
16845 var hook = updateWorkInProgressHook();
16846 var nextDeps = deps === undefined ? null : deps;
16847 var destroy = undefined;
16848
16849 if (currentHook !== null) {
16850 var prevEffect = currentHook.memoizedState;
16851 destroy = prevEffect.destroy;
16852
16853 if (nextDeps !== null) {
16854 var prevDeps = prevEffect.deps;
16855
16856 if (areHookInputsEqual(nextDeps, prevDeps)) {
16857 pushEffect(NoEffect$1, create, destroy, nextDeps);
16858 return;
16859 }
16860 }
16861 }
16862
16863 sideEffectTag |= fiberEffectTag;
16864 hook.memoizedState = pushEffect(hookEffectTag, create, destroy, nextDeps);
16865}
16866
16867function mountEffect(create, deps) {
16868 {
16869 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
16870 if ('undefined' !== typeof jest) {
16871 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
16872 }
16873 }
16874
16875 return mountEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
16876}
16877
16878function updateEffect(create, deps) {
16879 {
16880 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
16881 if ('undefined' !== typeof jest) {
16882 warnIfNotCurrentlyActingEffectsInDEV(currentlyRenderingFiber$1);
16883 }
16884 }
16885
16886 return updateEffectImpl(Update | Passive, UnmountPassive | MountPassive, create, deps);
16887}
16888
16889function mountLayoutEffect(create, deps) {
16890 return mountEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
16891}
16892
16893function updateLayoutEffect(create, deps) {
16894 return updateEffectImpl(Update, UnmountMutation | MountLayout, create, deps);
16895}
16896
16897function imperativeHandleEffect(create, ref) {
16898 if (typeof ref === 'function') {
16899 var refCallback = ref;
16900
16901 var _inst = create();
16902
16903 refCallback(_inst);
16904 return function () {
16905 refCallback(null);
16906 };
16907 } else if (ref !== null && ref !== undefined) {
16908 var refObject = ref;
16909
16910 {
16911 !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;
16912 }
16913
16914 var _inst2 = create();
16915
16916 refObject.current = _inst2;
16917 return function () {
16918 refObject.current = null;
16919 };
16920 }
16921}
16922
16923function mountImperativeHandle(ref, create, deps) {
16924 {
16925 !(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;
16926 } // TODO: If deps are provided, should we skip comparing the ref itself?
16927
16928
16929 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
16930 return mountEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
16931}
16932
16933function updateImperativeHandle(ref, create, deps) {
16934 {
16935 !(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;
16936 } // TODO: If deps are provided, should we skip comparing the ref itself?
16937
16938
16939 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
16940 return updateEffectImpl(Update, UnmountMutation | MountLayout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
16941}
16942
16943function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
16944 // The react-debug-hooks package injects its own implementation
16945 // so that e.g. DevTools can display custom hook values.
16946}
16947
16948var updateDebugValue = mountDebugValue;
16949
16950function mountCallback(callback, deps) {
16951 var hook = mountWorkInProgressHook();
16952 var nextDeps = deps === undefined ? null : deps;
16953 hook.memoizedState = [callback, nextDeps];
16954 return callback;
16955}
16956
16957function updateCallback(callback, deps) {
16958 var hook = updateWorkInProgressHook();
16959 var nextDeps = deps === undefined ? null : deps;
16960 var prevState = hook.memoizedState;
16961
16962 if (prevState !== null) {
16963 if (nextDeps !== null) {
16964 var prevDeps = prevState[1];
16965
16966 if (areHookInputsEqual(nextDeps, prevDeps)) {
16967 return prevState[0];
16968 }
16969 }
16970 }
16971
16972 hook.memoizedState = [callback, nextDeps];
16973 return callback;
16974}
16975
16976function mountMemo(nextCreate, deps) {
16977 var hook = mountWorkInProgressHook();
16978 var nextDeps = deps === undefined ? null : deps;
16979 var nextValue = nextCreate();
16980 hook.memoizedState = [nextValue, nextDeps];
16981 return nextValue;
16982}
16983
16984function updateMemo(nextCreate, deps) {
16985 var hook = updateWorkInProgressHook();
16986 var nextDeps = deps === undefined ? null : deps;
16987 var prevState = hook.memoizedState;
16988
16989 if (prevState !== null) {
16990 // Assume these are defined. If they're not, areHookInputsEqual will warn.
16991 if (nextDeps !== null) {
16992 var prevDeps = prevState[1];
16993
16994 if (areHookInputsEqual(nextDeps, prevDeps)) {
16995 return prevState[0];
16996 }
16997 }
16998 }
16999
17000 var nextValue = nextCreate();
17001 hook.memoizedState = [nextValue, nextDeps];
17002 return nextValue;
17003}
17004
17005function mountDeferredValue(value, config) {
17006 var _mountState = mountState(value),
17007 prevValue = _mountState[0],
17008 setValue = _mountState[1];
17009
17010 mountEffect(function () {
17011 unstable_next(function () {
17012 var previousConfig = ReactCurrentBatchConfig$1.suspense;
17013 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
17014
17015 try {
17016 setValue(value);
17017 } finally {
17018 ReactCurrentBatchConfig$1.suspense = previousConfig;
17019 }
17020 });
17021 }, [value, config]);
17022 return prevValue;
17023}
17024
17025function updateDeferredValue(value, config) {
17026 var _updateState = updateState(value),
17027 prevValue = _updateState[0],
17028 setValue = _updateState[1];
17029
17030 updateEffect(function () {
17031 unstable_next(function () {
17032 var previousConfig = ReactCurrentBatchConfig$1.suspense;
17033 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
17034
17035 try {
17036 setValue(value);
17037 } finally {
17038 ReactCurrentBatchConfig$1.suspense = previousConfig;
17039 }
17040 });
17041 }, [value, config]);
17042 return prevValue;
17043}
17044
17045function mountTransition(config) {
17046 var _mountState2 = mountState(false),
17047 isPending = _mountState2[0],
17048 setPending = _mountState2[1];
17049
17050 var startTransition = mountCallback(function (callback) {
17051 setPending(true);
17052 unstable_next(function () {
17053 var previousConfig = ReactCurrentBatchConfig$1.suspense;
17054 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
17055
17056 try {
17057 setPending(false);
17058 callback();
17059 } finally {
17060 ReactCurrentBatchConfig$1.suspense = previousConfig;
17061 }
17062 });
17063 }, [config, isPending]);
17064 return [startTransition, isPending];
17065}
17066
17067function updateTransition(config) {
17068 var _updateState2 = updateState(false),
17069 isPending = _updateState2[0],
17070 setPending = _updateState2[1];
17071
17072 var startTransition = updateCallback(function (callback) {
17073 setPending(true);
17074 unstable_next(function () {
17075 var previousConfig = ReactCurrentBatchConfig$1.suspense;
17076 ReactCurrentBatchConfig$1.suspense = config === undefined ? null : config;
17077
17078 try {
17079 setPending(false);
17080 callback();
17081 } finally {
17082 ReactCurrentBatchConfig$1.suspense = previousConfig;
17083 }
17084 });
17085 }, [config, isPending]);
17086 return [startTransition, isPending];
17087}
17088
17089function dispatchAction(fiber, queue, action) {
17090 if (!(numberOfReRenders < RE_RENDER_LIMIT)) {
17091 {
17092 throw Error("Too many re-renders. React limits the number of renders to prevent an infinite loop.");
17093 }
17094 }
17095
17096 {
17097 !(typeof arguments[3] !== 'function') ? warning$1(false, "State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().') : void 0;
17098 }
17099
17100 var alternate = fiber.alternate;
17101
17102 if (fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1) {
17103 // This is a render phase update. Stash it in a lazily-created map of
17104 // queue -> linked list of updates. After this render pass, we'll restart
17105 // and apply the stashed updates on top of the work-in-progress hook.
17106 didScheduleRenderPhaseUpdate = true;
17107 var update = {
17108 expirationTime: renderExpirationTime$1,
17109 suspenseConfig: null,
17110 action: action,
17111 eagerReducer: null,
17112 eagerState: null,
17113 next: null
17114 };
17115
17116 {
17117 update.priority = getCurrentPriorityLevel();
17118 }
17119
17120 if (renderPhaseUpdates === null) {
17121 renderPhaseUpdates = new Map();
17122 }
17123
17124 var firstRenderPhaseUpdate = renderPhaseUpdates.get(queue);
17125
17126 if (firstRenderPhaseUpdate === undefined) {
17127 renderPhaseUpdates.set(queue, update);
17128 } else {
17129 // Append the update to the end of the list.
17130 var lastRenderPhaseUpdate = firstRenderPhaseUpdate;
17131
17132 while (lastRenderPhaseUpdate.next !== null) {
17133 lastRenderPhaseUpdate = lastRenderPhaseUpdate.next;
17134 }
17135
17136 lastRenderPhaseUpdate.next = update;
17137 }
17138 } else {
17139 var currentTime = requestCurrentTimeForUpdate();
17140 var suspenseConfig = requestCurrentSuspenseConfig();
17141 var expirationTime = computeExpirationForFiber(currentTime, fiber, suspenseConfig);
17142 var _update2 = {
17143 expirationTime: expirationTime,
17144 suspenseConfig: suspenseConfig,
17145 action: action,
17146 eagerReducer: null,
17147 eagerState: null,
17148 next: null
17149 };
17150
17151 {
17152 _update2.priority = getCurrentPriorityLevel();
17153 } // Append the update to the end of the list.
17154
17155
17156 var last = queue.last;
17157
17158 if (last === null) {
17159 // This is the first update. Create a circular list.
17160 _update2.next = _update2;
17161 } else {
17162 var first = last.next;
17163
17164 if (first !== null) {
17165 // Still circular.
17166 _update2.next = first;
17167 }
17168
17169 last.next = _update2;
17170 }
17171
17172 queue.last = _update2;
17173
17174 if (fiber.expirationTime === NoWork && (alternate === null || alternate.expirationTime === NoWork)) {
17175 // The queue is currently empty, which means we can eagerly compute the
17176 // next state before entering the render phase. If the new state is the
17177 // same as the current state, we may be able to bail out entirely.
17178 var lastRenderedReducer = queue.lastRenderedReducer;
17179
17180 if (lastRenderedReducer !== null) {
17181 var prevDispatcher;
17182
17183 {
17184 prevDispatcher = ReactCurrentDispatcher$1.current;
17185 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17186 }
17187
17188 try {
17189 var currentState = queue.lastRenderedState;
17190 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
17191 // it, on the update object. If the reducer hasn't changed by the
17192 // time we enter the render phase, then the eager state can be used
17193 // without calling the reducer again.
17194
17195 _update2.eagerReducer = lastRenderedReducer;
17196 _update2.eagerState = eagerState;
17197
17198 if (is$1(eagerState, currentState)) {
17199 // Fast path. We can bail out without scheduling React to re-render.
17200 // It's still possible that we'll need to rebase this update later,
17201 // if the component re-renders for a different reason and by that
17202 // time the reducer has changed.
17203 return;
17204 }
17205 } catch (error) {// Suppress the error. It will throw again in the render phase.
17206 } finally {
17207 {
17208 ReactCurrentDispatcher$1.current = prevDispatcher;
17209 }
17210 }
17211 }
17212 }
17213
17214 {
17215 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
17216 if ('undefined' !== typeof jest) {
17217 warnIfNotScopedWithMatchingAct(fiber);
17218 warnIfNotCurrentlyActingUpdatesInDev(fiber);
17219 }
17220 }
17221
17222 scheduleWork(fiber, expirationTime);
17223 }
17224}
17225
17226var ContextOnlyDispatcher = {
17227 readContext: readContext,
17228 useCallback: throwInvalidHookError,
17229 useContext: throwInvalidHookError,
17230 useEffect: throwInvalidHookError,
17231 useImperativeHandle: throwInvalidHookError,
17232 useLayoutEffect: throwInvalidHookError,
17233 useMemo: throwInvalidHookError,
17234 useReducer: throwInvalidHookError,
17235 useRef: throwInvalidHookError,
17236 useState: throwInvalidHookError,
17237 useDebugValue: throwInvalidHookError,
17238 useResponder: throwInvalidHookError,
17239 useDeferredValue: throwInvalidHookError,
17240 useTransition: throwInvalidHookError
17241};
17242var HooksDispatcherOnMountInDEV = null;
17243var HooksDispatcherOnMountWithHookTypesInDEV = null;
17244var HooksDispatcherOnUpdateInDEV = null;
17245var InvalidNestedHooksDispatcherOnMountInDEV = null;
17246var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
17247
17248{
17249 var warnInvalidContextAccess = function () {
17250 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().');
17251 };
17252
17253 var warnInvalidHookAccess = function () {
17254 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');
17255 };
17256
17257 HooksDispatcherOnMountInDEV = {
17258 readContext: function (context, observedBits) {
17259 return readContext(context, observedBits);
17260 },
17261 useCallback: function (callback, deps) {
17262 currentHookNameInDev = 'useCallback';
17263 mountHookTypesDev();
17264 checkDepsAreArrayDev(deps);
17265 return mountCallback(callback, deps);
17266 },
17267 useContext: function (context, observedBits) {
17268 currentHookNameInDev = 'useContext';
17269 mountHookTypesDev();
17270 return readContext(context, observedBits);
17271 },
17272 useEffect: function (create, deps) {
17273 currentHookNameInDev = 'useEffect';
17274 mountHookTypesDev();
17275 checkDepsAreArrayDev(deps);
17276 return mountEffect(create, deps);
17277 },
17278 useImperativeHandle: function (ref, create, deps) {
17279 currentHookNameInDev = 'useImperativeHandle';
17280 mountHookTypesDev();
17281 checkDepsAreArrayDev(deps);
17282 return mountImperativeHandle(ref, create, deps);
17283 },
17284 useLayoutEffect: function (create, deps) {
17285 currentHookNameInDev = 'useLayoutEffect';
17286 mountHookTypesDev();
17287 checkDepsAreArrayDev(deps);
17288 return mountLayoutEffect(create, deps);
17289 },
17290 useMemo: function (create, deps) {
17291 currentHookNameInDev = 'useMemo';
17292 mountHookTypesDev();
17293 checkDepsAreArrayDev(deps);
17294 var prevDispatcher = ReactCurrentDispatcher$1.current;
17295 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17296
17297 try {
17298 return mountMemo(create, deps);
17299 } finally {
17300 ReactCurrentDispatcher$1.current = prevDispatcher;
17301 }
17302 },
17303 useReducer: function (reducer, initialArg, init) {
17304 currentHookNameInDev = 'useReducer';
17305 mountHookTypesDev();
17306 var prevDispatcher = ReactCurrentDispatcher$1.current;
17307 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17308
17309 try {
17310 return mountReducer(reducer, initialArg, init);
17311 } finally {
17312 ReactCurrentDispatcher$1.current = prevDispatcher;
17313 }
17314 },
17315 useRef: function (initialValue) {
17316 currentHookNameInDev = 'useRef';
17317 mountHookTypesDev();
17318 return mountRef(initialValue);
17319 },
17320 useState: function (initialState) {
17321 currentHookNameInDev = 'useState';
17322 mountHookTypesDev();
17323 var prevDispatcher = ReactCurrentDispatcher$1.current;
17324 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17325
17326 try {
17327 return mountState(initialState);
17328 } finally {
17329 ReactCurrentDispatcher$1.current = prevDispatcher;
17330 }
17331 },
17332 useDebugValue: function (value, formatterFn) {
17333 currentHookNameInDev = 'useDebugValue';
17334 mountHookTypesDev();
17335 return mountDebugValue(value, formatterFn);
17336 },
17337 useResponder: function (responder, props) {
17338 currentHookNameInDev = 'useResponder';
17339 mountHookTypesDev();
17340 return createResponderListener(responder, props);
17341 },
17342 useDeferredValue: function (value, config) {
17343 currentHookNameInDev = 'useDeferredValue';
17344 mountHookTypesDev();
17345 return mountDeferredValue(value, config);
17346 },
17347 useTransition: function (config) {
17348 currentHookNameInDev = 'useTransition';
17349 mountHookTypesDev();
17350 return mountTransition(config);
17351 }
17352 };
17353 HooksDispatcherOnMountWithHookTypesInDEV = {
17354 readContext: function (context, observedBits) {
17355 return readContext(context, observedBits);
17356 },
17357 useCallback: function (callback, deps) {
17358 currentHookNameInDev = 'useCallback';
17359 updateHookTypesDev();
17360 return mountCallback(callback, deps);
17361 },
17362 useContext: function (context, observedBits) {
17363 currentHookNameInDev = 'useContext';
17364 updateHookTypesDev();
17365 return readContext(context, observedBits);
17366 },
17367 useEffect: function (create, deps) {
17368 currentHookNameInDev = 'useEffect';
17369 updateHookTypesDev();
17370 return mountEffect(create, deps);
17371 },
17372 useImperativeHandle: function (ref, create, deps) {
17373 currentHookNameInDev = 'useImperativeHandle';
17374 updateHookTypesDev();
17375 return mountImperativeHandle(ref, create, deps);
17376 },
17377 useLayoutEffect: function (create, deps) {
17378 currentHookNameInDev = 'useLayoutEffect';
17379 updateHookTypesDev();
17380 return mountLayoutEffect(create, deps);
17381 },
17382 useMemo: function (create, deps) {
17383 currentHookNameInDev = 'useMemo';
17384 updateHookTypesDev();
17385 var prevDispatcher = ReactCurrentDispatcher$1.current;
17386 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17387
17388 try {
17389 return mountMemo(create, deps);
17390 } finally {
17391 ReactCurrentDispatcher$1.current = prevDispatcher;
17392 }
17393 },
17394 useReducer: function (reducer, initialArg, init) {
17395 currentHookNameInDev = 'useReducer';
17396 updateHookTypesDev();
17397 var prevDispatcher = ReactCurrentDispatcher$1.current;
17398 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17399
17400 try {
17401 return mountReducer(reducer, initialArg, init);
17402 } finally {
17403 ReactCurrentDispatcher$1.current = prevDispatcher;
17404 }
17405 },
17406 useRef: function (initialValue) {
17407 currentHookNameInDev = 'useRef';
17408 updateHookTypesDev();
17409 return mountRef(initialValue);
17410 },
17411 useState: function (initialState) {
17412 currentHookNameInDev = 'useState';
17413 updateHookTypesDev();
17414 var prevDispatcher = ReactCurrentDispatcher$1.current;
17415 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17416
17417 try {
17418 return mountState(initialState);
17419 } finally {
17420 ReactCurrentDispatcher$1.current = prevDispatcher;
17421 }
17422 },
17423 useDebugValue: function (value, formatterFn) {
17424 currentHookNameInDev = 'useDebugValue';
17425 updateHookTypesDev();
17426 return mountDebugValue(value, formatterFn);
17427 },
17428 useResponder: function (responder, props) {
17429 currentHookNameInDev = 'useResponder';
17430 updateHookTypesDev();
17431 return createResponderListener(responder, props);
17432 },
17433 useDeferredValue: function (value, config) {
17434 currentHookNameInDev = 'useDeferredValue';
17435 updateHookTypesDev();
17436 return mountDeferredValue(value, config);
17437 },
17438 useTransition: function (config) {
17439 currentHookNameInDev = 'useTransition';
17440 updateHookTypesDev();
17441 return mountTransition(config);
17442 }
17443 };
17444 HooksDispatcherOnUpdateInDEV = {
17445 readContext: function (context, observedBits) {
17446 return readContext(context, observedBits);
17447 },
17448 useCallback: function (callback, deps) {
17449 currentHookNameInDev = 'useCallback';
17450 updateHookTypesDev();
17451 return updateCallback(callback, deps);
17452 },
17453 useContext: function (context, observedBits) {
17454 currentHookNameInDev = 'useContext';
17455 updateHookTypesDev();
17456 return readContext(context, observedBits);
17457 },
17458 useEffect: function (create, deps) {
17459 currentHookNameInDev = 'useEffect';
17460 updateHookTypesDev();
17461 return updateEffect(create, deps);
17462 },
17463 useImperativeHandle: function (ref, create, deps) {
17464 currentHookNameInDev = 'useImperativeHandle';
17465 updateHookTypesDev();
17466 return updateImperativeHandle(ref, create, deps);
17467 },
17468 useLayoutEffect: function (create, deps) {
17469 currentHookNameInDev = 'useLayoutEffect';
17470 updateHookTypesDev();
17471 return updateLayoutEffect(create, deps);
17472 },
17473 useMemo: function (create, deps) {
17474 currentHookNameInDev = 'useMemo';
17475 updateHookTypesDev();
17476 var prevDispatcher = ReactCurrentDispatcher$1.current;
17477 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17478
17479 try {
17480 return updateMemo(create, deps);
17481 } finally {
17482 ReactCurrentDispatcher$1.current = prevDispatcher;
17483 }
17484 },
17485 useReducer: function (reducer, initialArg, init) {
17486 currentHookNameInDev = 'useReducer';
17487 updateHookTypesDev();
17488 var prevDispatcher = ReactCurrentDispatcher$1.current;
17489 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17490
17491 try {
17492 return updateReducer(reducer, initialArg, init);
17493 } finally {
17494 ReactCurrentDispatcher$1.current = prevDispatcher;
17495 }
17496 },
17497 useRef: function (initialValue) {
17498 currentHookNameInDev = 'useRef';
17499 updateHookTypesDev();
17500 return updateRef(initialValue);
17501 },
17502 useState: function (initialState) {
17503 currentHookNameInDev = 'useState';
17504 updateHookTypesDev();
17505 var prevDispatcher = ReactCurrentDispatcher$1.current;
17506 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17507
17508 try {
17509 return updateState(initialState);
17510 } finally {
17511 ReactCurrentDispatcher$1.current = prevDispatcher;
17512 }
17513 },
17514 useDebugValue: function (value, formatterFn) {
17515 currentHookNameInDev = 'useDebugValue';
17516 updateHookTypesDev();
17517 return updateDebugValue(value, formatterFn);
17518 },
17519 useResponder: function (responder, props) {
17520 currentHookNameInDev = 'useResponder';
17521 updateHookTypesDev();
17522 return createResponderListener(responder, props);
17523 },
17524 useDeferredValue: function (value, config) {
17525 currentHookNameInDev = 'useDeferredValue';
17526 updateHookTypesDev();
17527 return updateDeferredValue(value, config);
17528 },
17529 useTransition: function (config) {
17530 currentHookNameInDev = 'useTransition';
17531 updateHookTypesDev();
17532 return updateTransition(config);
17533 }
17534 };
17535 InvalidNestedHooksDispatcherOnMountInDEV = {
17536 readContext: function (context, observedBits) {
17537 warnInvalidContextAccess();
17538 return readContext(context, observedBits);
17539 },
17540 useCallback: function (callback, deps) {
17541 currentHookNameInDev = 'useCallback';
17542 warnInvalidHookAccess();
17543 mountHookTypesDev();
17544 return mountCallback(callback, deps);
17545 },
17546 useContext: function (context, observedBits) {
17547 currentHookNameInDev = 'useContext';
17548 warnInvalidHookAccess();
17549 mountHookTypesDev();
17550 return readContext(context, observedBits);
17551 },
17552 useEffect: function (create, deps) {
17553 currentHookNameInDev = 'useEffect';
17554 warnInvalidHookAccess();
17555 mountHookTypesDev();
17556 return mountEffect(create, deps);
17557 },
17558 useImperativeHandle: function (ref, create, deps) {
17559 currentHookNameInDev = 'useImperativeHandle';
17560 warnInvalidHookAccess();
17561 mountHookTypesDev();
17562 return mountImperativeHandle(ref, create, deps);
17563 },
17564 useLayoutEffect: function (create, deps) {
17565 currentHookNameInDev = 'useLayoutEffect';
17566 warnInvalidHookAccess();
17567 mountHookTypesDev();
17568 return mountLayoutEffect(create, deps);
17569 },
17570 useMemo: function (create, deps) {
17571 currentHookNameInDev = 'useMemo';
17572 warnInvalidHookAccess();
17573 mountHookTypesDev();
17574 var prevDispatcher = ReactCurrentDispatcher$1.current;
17575 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17576
17577 try {
17578 return mountMemo(create, deps);
17579 } finally {
17580 ReactCurrentDispatcher$1.current = prevDispatcher;
17581 }
17582 },
17583 useReducer: function (reducer, initialArg, init) {
17584 currentHookNameInDev = 'useReducer';
17585 warnInvalidHookAccess();
17586 mountHookTypesDev();
17587 var prevDispatcher = ReactCurrentDispatcher$1.current;
17588 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17589
17590 try {
17591 return mountReducer(reducer, initialArg, init);
17592 } finally {
17593 ReactCurrentDispatcher$1.current = prevDispatcher;
17594 }
17595 },
17596 useRef: function (initialValue) {
17597 currentHookNameInDev = 'useRef';
17598 warnInvalidHookAccess();
17599 mountHookTypesDev();
17600 return mountRef(initialValue);
17601 },
17602 useState: function (initialState) {
17603 currentHookNameInDev = 'useState';
17604 warnInvalidHookAccess();
17605 mountHookTypesDev();
17606 var prevDispatcher = ReactCurrentDispatcher$1.current;
17607 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17608
17609 try {
17610 return mountState(initialState);
17611 } finally {
17612 ReactCurrentDispatcher$1.current = prevDispatcher;
17613 }
17614 },
17615 useDebugValue: function (value, formatterFn) {
17616 currentHookNameInDev = 'useDebugValue';
17617 warnInvalidHookAccess();
17618 mountHookTypesDev();
17619 return mountDebugValue(value, formatterFn);
17620 },
17621 useResponder: function (responder, props) {
17622 currentHookNameInDev = 'useResponder';
17623 warnInvalidHookAccess();
17624 mountHookTypesDev();
17625 return createResponderListener(responder, props);
17626 },
17627 useDeferredValue: function (value, config) {
17628 currentHookNameInDev = 'useDeferredValue';
17629 warnInvalidHookAccess();
17630 mountHookTypesDev();
17631 return mountDeferredValue(value, config);
17632 },
17633 useTransition: function (config) {
17634 currentHookNameInDev = 'useTransition';
17635 warnInvalidHookAccess();
17636 mountHookTypesDev();
17637 return mountTransition(config);
17638 }
17639 };
17640 InvalidNestedHooksDispatcherOnUpdateInDEV = {
17641 readContext: function (context, observedBits) {
17642 warnInvalidContextAccess();
17643 return readContext(context, observedBits);
17644 },
17645 useCallback: function (callback, deps) {
17646 currentHookNameInDev = 'useCallback';
17647 warnInvalidHookAccess();
17648 updateHookTypesDev();
17649 return updateCallback(callback, deps);
17650 },
17651 useContext: function (context, observedBits) {
17652 currentHookNameInDev = 'useContext';
17653 warnInvalidHookAccess();
17654 updateHookTypesDev();
17655 return readContext(context, observedBits);
17656 },
17657 useEffect: function (create, deps) {
17658 currentHookNameInDev = 'useEffect';
17659 warnInvalidHookAccess();
17660 updateHookTypesDev();
17661 return updateEffect(create, deps);
17662 },
17663 useImperativeHandle: function (ref, create, deps) {
17664 currentHookNameInDev = 'useImperativeHandle';
17665 warnInvalidHookAccess();
17666 updateHookTypesDev();
17667 return updateImperativeHandle(ref, create, deps);
17668 },
17669 useLayoutEffect: function (create, deps) {
17670 currentHookNameInDev = 'useLayoutEffect';
17671 warnInvalidHookAccess();
17672 updateHookTypesDev();
17673 return updateLayoutEffect(create, deps);
17674 },
17675 useMemo: function (create, deps) {
17676 currentHookNameInDev = 'useMemo';
17677 warnInvalidHookAccess();
17678 updateHookTypesDev();
17679 var prevDispatcher = ReactCurrentDispatcher$1.current;
17680 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17681
17682 try {
17683 return updateMemo(create, deps);
17684 } finally {
17685 ReactCurrentDispatcher$1.current = prevDispatcher;
17686 }
17687 },
17688 useReducer: function (reducer, initialArg, init) {
17689 currentHookNameInDev = 'useReducer';
17690 warnInvalidHookAccess();
17691 updateHookTypesDev();
17692 var prevDispatcher = ReactCurrentDispatcher$1.current;
17693 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17694
17695 try {
17696 return updateReducer(reducer, initialArg, init);
17697 } finally {
17698 ReactCurrentDispatcher$1.current = prevDispatcher;
17699 }
17700 },
17701 useRef: function (initialValue) {
17702 currentHookNameInDev = 'useRef';
17703 warnInvalidHookAccess();
17704 updateHookTypesDev();
17705 return updateRef(initialValue);
17706 },
17707 useState: function (initialState) {
17708 currentHookNameInDev = 'useState';
17709 warnInvalidHookAccess();
17710 updateHookTypesDev();
17711 var prevDispatcher = ReactCurrentDispatcher$1.current;
17712 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17713
17714 try {
17715 return updateState(initialState);
17716 } finally {
17717 ReactCurrentDispatcher$1.current = prevDispatcher;
17718 }
17719 },
17720 useDebugValue: function (value, formatterFn) {
17721 currentHookNameInDev = 'useDebugValue';
17722 warnInvalidHookAccess();
17723 updateHookTypesDev();
17724 return updateDebugValue(value, formatterFn);
17725 },
17726 useResponder: function (responder, props) {
17727 currentHookNameInDev = 'useResponder';
17728 warnInvalidHookAccess();
17729 updateHookTypesDev();
17730 return createResponderListener(responder, props);
17731 },
17732 useDeferredValue: function (value, config) {
17733 currentHookNameInDev = 'useDeferredValue';
17734 warnInvalidHookAccess();
17735 updateHookTypesDev();
17736 return updateDeferredValue(value, config);
17737 },
17738 useTransition: function (config) {
17739 currentHookNameInDev = 'useTransition';
17740 warnInvalidHookAccess();
17741 updateHookTypesDev();
17742 return updateTransition(config);
17743 }
17744 };
17745}
17746
17747// CommonJS interop named imports.
17748
17749var now$1 = unstable_now;
17750var commitTime = 0;
17751var profilerStartTime = -1;
17752
17753function getCommitTime() {
17754 return commitTime;
17755}
17756
17757function recordCommitTime() {
17758 if (!enableProfilerTimer) {
17759 return;
17760 }
17761
17762 commitTime = now$1();
17763}
17764
17765function startProfilerTimer(fiber) {
17766 if (!enableProfilerTimer) {
17767 return;
17768 }
17769
17770 profilerStartTime = now$1();
17771
17772 if (fiber.actualStartTime < 0) {
17773 fiber.actualStartTime = now$1();
17774 }
17775}
17776
17777function stopProfilerTimerIfRunning(fiber) {
17778 if (!enableProfilerTimer) {
17779 return;
17780 }
17781
17782 profilerStartTime = -1;
17783}
17784
17785function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
17786 if (!enableProfilerTimer) {
17787 return;
17788 }
17789
17790 if (profilerStartTime >= 0) {
17791 var elapsedTime = now$1() - profilerStartTime;
17792 fiber.actualDuration += elapsedTime;
17793
17794 if (overrideBaseTime) {
17795 fiber.selfBaseDuration = elapsedTime;
17796 }
17797
17798 profilerStartTime = -1;
17799 }
17800}
17801
17802// This may have been an insertion or a hydration.
17803
17804var hydrationParentFiber = null;
17805var nextHydratableInstance = null;
17806var isHydrating = false;
17807
17808function warnIfHydrating() {
17809 {
17810 !!isHydrating ? warning$1(false, 'We should not be hydrating here. This is a bug in React. Please file a bug.') : void 0;
17811 }
17812}
17813
17814function enterHydrationState(fiber) {
17815 if (!supportsHydration) {
17816 return false;
17817 }
17818
17819 var parentInstance = fiber.stateNode.containerInfo;
17820 nextHydratableInstance = getFirstHydratableChild(parentInstance);
17821 hydrationParentFiber = fiber;
17822 isHydrating = true;
17823 return true;
17824}
17825
17826function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance) {
17827 if (!supportsHydration) {
17828 return false;
17829 }
17830
17831 nextHydratableInstance = getNextHydratableSibling(suspenseInstance);
17832 popToNextHostParent(fiber);
17833 isHydrating = true;
17834 return true;
17835}
17836
17837function deleteHydratableInstance(returnFiber, instance) {
17838 {
17839 switch (returnFiber.tag) {
17840 case HostRoot:
17841 didNotHydrateContainerInstance(returnFiber.stateNode.containerInfo, instance);
17842 break;
17843
17844 case HostComponent:
17845 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
17846 break;
17847 }
17848 }
17849
17850 var childToDelete = createFiberFromHostInstanceForDeletion();
17851 childToDelete.stateNode = instance;
17852 childToDelete.return = returnFiber;
17853 childToDelete.effectTag = Deletion; // This might seem like it belongs on progressedFirstDeletion. However,
17854 // these children are not part of the reconciliation list of children.
17855 // Even if we abort and rereconcile the children, that will try to hydrate
17856 // again and the nodes are still in the host tree so these will be
17857 // recreated.
17858
17859 if (returnFiber.lastEffect !== null) {
17860 returnFiber.lastEffect.nextEffect = childToDelete;
17861 returnFiber.lastEffect = childToDelete;
17862 } else {
17863 returnFiber.firstEffect = returnFiber.lastEffect = childToDelete;
17864 }
17865}
17866
17867function insertNonHydratedInstance(returnFiber, fiber) {
17868 fiber.effectTag = fiber.effectTag & ~Hydrating | Placement;
17869
17870 {
17871 switch (returnFiber.tag) {
17872 case HostRoot:
17873 {
17874 var parentContainer = returnFiber.stateNode.containerInfo;
17875
17876 switch (fiber.tag) {
17877 case HostComponent:
17878 var type = fiber.type;
17879 var props = fiber.pendingProps;
17880 didNotFindHydratableContainerInstance(parentContainer, type, props);
17881 break;
17882
17883 case HostText:
17884 var text = fiber.pendingProps;
17885 didNotFindHydratableContainerTextInstance(parentContainer, text);
17886 break;
17887
17888 case SuspenseComponent:
17889
17890 break;
17891 }
17892
17893 break;
17894 }
17895
17896 case HostComponent:
17897 {
17898 var parentType = returnFiber.type;
17899 var parentProps = returnFiber.memoizedProps;
17900 var parentInstance = returnFiber.stateNode;
17901
17902 switch (fiber.tag) {
17903 case HostComponent:
17904 var _type = fiber.type;
17905 var _props = fiber.pendingProps;
17906 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props);
17907 break;
17908
17909 case HostText:
17910 var _text = fiber.pendingProps;
17911 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
17912 break;
17913
17914 case SuspenseComponent:
17915 didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance);
17916 break;
17917 }
17918
17919 break;
17920 }
17921
17922 default:
17923 return;
17924 }
17925 }
17926}
17927
17928function tryHydrate(fiber, nextInstance) {
17929 switch (fiber.tag) {
17930 case HostComponent:
17931 {
17932 var type = fiber.type;
17933 var props = fiber.pendingProps;
17934 var instance = canHydrateInstance(nextInstance, type, props);
17935
17936 if (instance !== null) {
17937 fiber.stateNode = instance;
17938 return true;
17939 }
17940
17941 return false;
17942 }
17943
17944 case HostText:
17945 {
17946 var text = fiber.pendingProps;
17947 var textInstance = canHydrateTextInstance(nextInstance, text);
17948
17949 if (textInstance !== null) {
17950 fiber.stateNode = textInstance;
17951 return true;
17952 }
17953
17954 return false;
17955 }
17956
17957 case SuspenseComponent:
17958 {
17959 if (enableSuspenseServerRenderer) {
17960 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
17961
17962 if (suspenseInstance !== null) {
17963 var suspenseState = {
17964 dehydrated: suspenseInstance,
17965 retryTime: Never
17966 };
17967 fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber.
17968 // This simplifies the code for getHostSibling and deleting nodes,
17969 // since it doesn't have to consider all Suspense boundaries and
17970 // check if they're dehydrated ones or not.
17971
17972 var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
17973 dehydratedFragment.return = fiber;
17974 fiber.child = dehydratedFragment;
17975 return true;
17976 }
17977 }
17978
17979 return false;
17980 }
17981
17982 default:
17983 return false;
17984 }
17985}
17986
17987function tryToClaimNextHydratableInstance(fiber) {
17988 if (!isHydrating) {
17989 return;
17990 }
17991
17992 var nextInstance = nextHydratableInstance;
17993
17994 if (!nextInstance) {
17995 // Nothing to hydrate. Make it an insertion.
17996 insertNonHydratedInstance(hydrationParentFiber, fiber);
17997 isHydrating = false;
17998 hydrationParentFiber = fiber;
17999 return;
18000 }
18001
18002 var firstAttemptedInstance = nextInstance;
18003
18004 if (!tryHydrate(fiber, nextInstance)) {
18005 // If we can't hydrate this instance let's try the next one.
18006 // We use this as a heuristic. It's based on intuition and not data so it
18007 // might be flawed or unnecessary.
18008 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
18009
18010 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
18011 // Nothing to hydrate. Make it an insertion.
18012 insertNonHydratedInstance(hydrationParentFiber, fiber);
18013 isHydrating = false;
18014 hydrationParentFiber = fiber;
18015 return;
18016 } // We matched the next one, we'll now assume that the first one was
18017 // superfluous and we'll delete it. Since we can't eagerly delete it
18018 // we'll have to schedule a deletion. To do that, this node needs a dummy
18019 // fiber associated with it.
18020
18021
18022 deleteHydratableInstance(hydrationParentFiber, firstAttemptedInstance);
18023 }
18024
18025 hydrationParentFiber = fiber;
18026 nextHydratableInstance = getFirstHydratableChild(nextInstance);
18027}
18028
18029function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
18030 if (!supportsHydration) {
18031 {
18032 {
18033 throw Error("Expected prepareToHydrateHostInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.");
18034 }
18035 }
18036 }
18037
18038 var instance = fiber.stateNode;
18039 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber); // TODO: Type this specific to this type of component.
18040
18041 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
18042 // is a new ref we mark this as an update.
18043
18044 if (updatePayload !== null) {
18045 return true;
18046 }
18047
18048 return false;
18049}
18050
18051function prepareToHydrateHostTextInstance(fiber) {
18052 if (!supportsHydration) {
18053 {
18054 {
18055 throw Error("Expected prepareToHydrateHostTextInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.");
18056 }
18057 }
18058 }
18059
18060 var textInstance = fiber.stateNode;
18061 var textContent = fiber.memoizedProps;
18062 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
18063
18064 {
18065 if (shouldUpdate) {
18066 // We assume that prepareToHydrateHostTextInstance is called in a context where the
18067 // hydration parent is the parent host component of this host text.
18068 var returnFiber = hydrationParentFiber;
18069
18070 if (returnFiber !== null) {
18071 switch (returnFiber.tag) {
18072 case HostRoot:
18073 {
18074 var parentContainer = returnFiber.stateNode.containerInfo;
18075 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent);
18076 break;
18077 }
18078
18079 case HostComponent:
18080 {
18081 var parentType = returnFiber.type;
18082 var parentProps = returnFiber.memoizedProps;
18083 var parentInstance = returnFiber.stateNode;
18084 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent);
18085 break;
18086 }
18087 }
18088 }
18089 }
18090 }
18091
18092 return shouldUpdate;
18093}
18094
18095function prepareToHydrateHostSuspenseInstance(fiber) {
18096 if (!supportsHydration) {
18097 {
18098 {
18099 throw Error("Expected prepareToHydrateHostSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.");
18100 }
18101 }
18102 }
18103
18104 var suspenseState = fiber.memoizedState;
18105 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
18106
18107 if (!suspenseInstance) {
18108 {
18109 throw Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.");
18110 }
18111 }
18112
18113 hydrateSuspenseInstance(suspenseInstance, fiber);
18114}
18115
18116function skipPastDehydratedSuspenseInstance(fiber) {
18117 if (!supportsHydration) {
18118 {
18119 {
18120 throw Error("Expected skipPastDehydratedSuspenseInstance() to never be called. This error is likely caused by a bug in React. Please file an issue.");
18121 }
18122 }
18123 }
18124
18125 var suspenseState = fiber.memoizedState;
18126 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
18127
18128 if (!suspenseInstance) {
18129 {
18130 throw Error("Expected to have a hydrated suspense instance. This error is likely caused by a bug in React. Please file an issue.");
18131 }
18132 }
18133
18134 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
18135}
18136
18137function popToNextHostParent(fiber) {
18138 var parent = fiber.return;
18139
18140 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
18141 parent = parent.return;
18142 }
18143
18144 hydrationParentFiber = parent;
18145}
18146
18147function popHydrationState(fiber) {
18148 if (!supportsHydration) {
18149 return false;
18150 }
18151
18152 if (fiber !== hydrationParentFiber) {
18153 // We're deeper than the current hydration context, inside an inserted
18154 // tree.
18155 return false;
18156 }
18157
18158 if (!isHydrating) {
18159 // If we're not currently hydrating but we're in a hydration context, then
18160 // we were an insertion and now need to pop up reenter hydration of our
18161 // siblings.
18162 popToNextHostParent(fiber);
18163 isHydrating = true;
18164 return false;
18165 }
18166
18167 var type = fiber.type; // If we have any remaining hydratable nodes, we need to delete them now.
18168 // We only do this deeper than head and body since they tend to have random
18169 // other nodes in them. We also ignore components with pure text content in
18170 // side of them.
18171 // TODO: Better heuristic.
18172
18173 if (fiber.tag !== HostComponent || type !== 'head' && type !== 'body' && !shouldSetTextContent(type, fiber.memoizedProps)) {
18174 var nextInstance = nextHydratableInstance;
18175
18176 while (nextInstance) {
18177 deleteHydratableInstance(fiber, nextInstance);
18178 nextInstance = getNextHydratableSibling(nextInstance);
18179 }
18180 }
18181
18182 popToNextHostParent(fiber);
18183
18184 if (fiber.tag === SuspenseComponent) {
18185 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
18186 } else {
18187 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
18188 }
18189
18190 return true;
18191}
18192
18193function resetHydrationState() {
18194 if (!supportsHydration) {
18195 return;
18196 }
18197
18198 hydrationParentFiber = null;
18199 nextHydratableInstance = null;
18200 isHydrating = false;
18201}
18202
18203var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
18204var didReceiveUpdate = false;
18205var didWarnAboutBadClass;
18206var didWarnAboutModulePatternComponent;
18207var didWarnAboutContextTypeOnFunctionComponent;
18208var didWarnAboutGetDerivedStateOnFunctionComponent;
18209var didWarnAboutFunctionRefs;
18210var didWarnAboutReassigningProps;
18211var didWarnAboutMaxDuration;
18212var didWarnAboutRevealOrder;
18213var didWarnAboutTailOptions;
18214var didWarnAboutDefaultPropsOnFunctionComponent;
18215
18216{
18217 didWarnAboutBadClass = {};
18218 didWarnAboutModulePatternComponent = {};
18219 didWarnAboutContextTypeOnFunctionComponent = {};
18220 didWarnAboutGetDerivedStateOnFunctionComponent = {};
18221 didWarnAboutFunctionRefs = {};
18222 didWarnAboutReassigningProps = false;
18223 didWarnAboutMaxDuration = false;
18224 didWarnAboutRevealOrder = {};
18225 didWarnAboutTailOptions = {};
18226 didWarnAboutDefaultPropsOnFunctionComponent = {};
18227}
18228
18229function reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime) {
18230 if (current$$1 === null) {
18231 // If this is a fresh new component that hasn't been rendered yet, we
18232 // won't update its child set by applying minimal side-effects. Instead,
18233 // we will add them all to the child before it gets rendered. That means
18234 // we can optimize this reconciliation pass by not tracking side-effects.
18235 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
18236 } else {
18237 // If the current child is the same as the work in progress, it means that
18238 // we haven't yet started any work on these children. Therefore, we use
18239 // the clone algorithm to create a copy of all the current children.
18240 // If we had any progressed work already, that is invalid at this point so
18241 // let's throw it out.
18242 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, nextChildren, renderExpirationTime);
18243 }
18244}
18245
18246function forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime) {
18247 // This function is fork of reconcileChildren. It's used in cases where we
18248 // want to reconcile without matching against the existing set. This has the
18249 // effect of all current children being unmounted; even if the type and key
18250 // are the same, the old child is unmounted and a new child is created.
18251 //
18252 // To do this, we're going to go through the reconcile algorithm twice. In
18253 // the first pass, we schedule a deletion for all the current children by
18254 // passing null.
18255 workInProgress.child = reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime); // In the second pass, we mount the new children. The trick here is that we
18256 // pass null in place of where we usually pass the current child set. This has
18257 // the effect of remounting all children regardless of whether their their
18258 // identity matches.
18259
18260 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
18261}
18262
18263function updateForwardRef(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
18264 // TODO: current can be non-null here even if the component
18265 // hasn't yet mounted. This happens after the first render suspends.
18266 // We'll need to figure out if this is fine or can cause issues.
18267 {
18268 if (workInProgress.type !== workInProgress.elementType) {
18269 // Lazy component props can't be validated in createElement
18270 // because they're only guaranteed to be resolved here.
18271 var innerPropTypes = Component.propTypes;
18272
18273 if (innerPropTypes) {
18274 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
18275 'prop', getComponentName(Component), getCurrentFiberStackInDev);
18276 }
18277 }
18278 }
18279
18280 var render = Component.render;
18281 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
18282
18283 var nextChildren;
18284 prepareToReadContext(workInProgress, renderExpirationTime);
18285
18286 {
18287 ReactCurrentOwner$3.current = workInProgress;
18288 setCurrentPhase('render');
18289 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
18290
18291 if (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
18292 // Only double-render components with Hooks
18293 if (workInProgress.memoizedState !== null) {
18294 nextChildren = renderWithHooks(current$$1, workInProgress, render, nextProps, ref, renderExpirationTime);
18295 }
18296 }
18297
18298 setCurrentPhase(null);
18299 }
18300
18301 if (current$$1 !== null && !didReceiveUpdate) {
18302 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
18303 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18304 } // React DevTools reads this flag.
18305
18306
18307 workInProgress.effectTag |= PerformedWork;
18308 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18309 return workInProgress.child;
18310}
18311
18312function updateMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
18313 if (current$$1 === null) {
18314 var type = Component.type;
18315
18316 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
18317 Component.defaultProps === undefined) {
18318 var resolvedType = type;
18319
18320 {
18321 resolvedType = resolveFunctionForHotReloading(type);
18322 } // If this is a plain function component without default props,
18323 // and with only the default shallow comparison, we upgrade it
18324 // to a SimpleMemoComponent to allow fast path updates.
18325
18326
18327 workInProgress.tag = SimpleMemoComponent;
18328 workInProgress.type = resolvedType;
18329
18330 {
18331 validateFunctionComponentInDev(workInProgress, type);
18332 }
18333
18334 return updateSimpleMemoComponent(current$$1, workInProgress, resolvedType, nextProps, updateExpirationTime, renderExpirationTime);
18335 }
18336
18337 {
18338 var innerPropTypes = type.propTypes;
18339
18340 if (innerPropTypes) {
18341 // Inner memo component props aren't currently validated in createElement.
18342 // We could move it there, but we'd still need this for lazy code path.
18343 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
18344 'prop', getComponentName(type), getCurrentFiberStackInDev);
18345 }
18346 }
18347
18348 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, null, workInProgress.mode, renderExpirationTime);
18349 child.ref = workInProgress.ref;
18350 child.return = workInProgress;
18351 workInProgress.child = child;
18352 return child;
18353 }
18354
18355 {
18356 var _type = Component.type;
18357 var _innerPropTypes = _type.propTypes;
18358
18359 if (_innerPropTypes) {
18360 // Inner memo component props aren't currently validated in createElement.
18361 // We could move it there, but we'd still need this for lazy code path.
18362 checkPropTypes_1(_innerPropTypes, nextProps, // Resolved props
18363 'prop', getComponentName(_type), getCurrentFiberStackInDev);
18364 }
18365 }
18366
18367 var currentChild = current$$1.child; // This is always exactly one child
18368
18369 if (updateExpirationTime < renderExpirationTime) {
18370 // This will be the props with resolved defaultProps,
18371 // unlike current.memoizedProps which will be the unresolved ones.
18372 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
18373
18374 var compare = Component.compare;
18375 compare = compare !== null ? compare : shallowEqual;
18376
18377 if (compare(prevProps, nextProps) && current$$1.ref === workInProgress.ref) {
18378 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18379 }
18380 } // React DevTools reads this flag.
18381
18382
18383 workInProgress.effectTag |= PerformedWork;
18384 var newChild = createWorkInProgress(currentChild, nextProps, renderExpirationTime);
18385 newChild.ref = workInProgress.ref;
18386 newChild.return = workInProgress;
18387 workInProgress.child = newChild;
18388 return newChild;
18389}
18390
18391function updateSimpleMemoComponent(current$$1, workInProgress, Component, nextProps, updateExpirationTime, renderExpirationTime) {
18392 // TODO: current can be non-null here even if the component
18393 // hasn't yet mounted. This happens when the inner render suspends.
18394 // We'll need to figure out if this is fine or can cause issues.
18395 {
18396 if (workInProgress.type !== workInProgress.elementType) {
18397 // Lazy component props can't be validated in createElement
18398 // because they're only guaranteed to be resolved here.
18399 var outerMemoType = workInProgress.elementType;
18400
18401 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
18402 // We warn when you define propTypes on lazy()
18403 // so let's just skip over it to find memo() outer wrapper.
18404 // Inner props for memo are validated later.
18405 outerMemoType = refineResolvedLazyComponent(outerMemoType);
18406 }
18407
18408 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
18409
18410 if (outerPropTypes) {
18411 checkPropTypes_1(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
18412 'prop', getComponentName(outerMemoType), getCurrentFiberStackInDev);
18413 } // Inner propTypes will be validated in the function component path.
18414
18415 }
18416 }
18417
18418 if (current$$1 !== null) {
18419 var prevProps = current$$1.memoizedProps;
18420
18421 if (shallowEqual(prevProps, nextProps) && current$$1.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload:
18422 workInProgress.type === current$$1.type)) {
18423 didReceiveUpdate = false;
18424
18425 if (updateExpirationTime < renderExpirationTime) {
18426 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18427 }
18428 }
18429 }
18430
18431 return updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
18432}
18433
18434function updateFragment(current$$1, workInProgress, renderExpirationTime) {
18435 var nextChildren = workInProgress.pendingProps;
18436 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18437 return workInProgress.child;
18438}
18439
18440function updateMode(current$$1, workInProgress, renderExpirationTime) {
18441 var nextChildren = workInProgress.pendingProps.children;
18442 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18443 return workInProgress.child;
18444}
18445
18446function updateProfiler(current$$1, workInProgress, renderExpirationTime) {
18447 if (enableProfilerTimer) {
18448 workInProgress.effectTag |= Update;
18449 }
18450
18451 var nextProps = workInProgress.pendingProps;
18452 var nextChildren = nextProps.children;
18453 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18454 return workInProgress.child;
18455}
18456
18457function markRef(current$$1, workInProgress) {
18458 var ref = workInProgress.ref;
18459
18460 if (current$$1 === null && ref !== null || current$$1 !== null && current$$1.ref !== ref) {
18461 // Schedule a Ref effect
18462 workInProgress.effectTag |= Ref;
18463 }
18464}
18465
18466function updateFunctionComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
18467 {
18468 if (workInProgress.type !== workInProgress.elementType) {
18469 // Lazy component props can't be validated in createElement
18470 // because they're only guaranteed to be resolved here.
18471 var innerPropTypes = Component.propTypes;
18472
18473 if (innerPropTypes) {
18474 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
18475 'prop', getComponentName(Component), getCurrentFiberStackInDev);
18476 }
18477 }
18478 }
18479
18480 var context;
18481
18482 if (!disableLegacyContext) {
18483 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
18484 context = getMaskedContext(workInProgress, unmaskedContext);
18485 }
18486
18487 var nextChildren;
18488 prepareToReadContext(workInProgress, renderExpirationTime);
18489
18490 {
18491 ReactCurrentOwner$3.current = workInProgress;
18492 setCurrentPhase('render');
18493 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
18494
18495 if (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
18496 // Only double-render components with Hooks
18497 if (workInProgress.memoizedState !== null) {
18498 nextChildren = renderWithHooks(current$$1, workInProgress, Component, nextProps, context, renderExpirationTime);
18499 }
18500 }
18501
18502 setCurrentPhase(null);
18503 }
18504
18505 if (current$$1 !== null && !didReceiveUpdate) {
18506 bailoutHooks(current$$1, workInProgress, renderExpirationTime);
18507 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18508 } // React DevTools reads this flag.
18509
18510
18511 workInProgress.effectTag |= PerformedWork;
18512 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18513 return workInProgress.child;
18514}
18515
18516function updateClassComponent(current$$1, workInProgress, Component, nextProps, renderExpirationTime) {
18517 {
18518 if (workInProgress.type !== workInProgress.elementType) {
18519 // Lazy component props can't be validated in createElement
18520 // because they're only guaranteed to be resolved here.
18521 var innerPropTypes = Component.propTypes;
18522
18523 if (innerPropTypes) {
18524 checkPropTypes_1(innerPropTypes, nextProps, // Resolved props
18525 'prop', getComponentName(Component), getCurrentFiberStackInDev);
18526 }
18527 }
18528 } // Push context providers early to prevent context stack mismatches.
18529 // During mounting we don't know the child context yet as the instance doesn't exist.
18530 // We will invalidate the child context in finishClassComponent() right after rendering.
18531
18532
18533 var hasContext;
18534
18535 if (isContextProvider(Component)) {
18536 hasContext = true;
18537 pushContextProvider(workInProgress);
18538 } else {
18539 hasContext = false;
18540 }
18541
18542 prepareToReadContext(workInProgress, renderExpirationTime);
18543 var instance = workInProgress.stateNode;
18544 var shouldUpdate;
18545
18546 if (instance === null) {
18547 if (current$$1 !== null) {
18548 // An class component without an instance only mounts if it suspended
18549 // inside a non- concurrent tree, in an inconsistent state. We want to
18550 // tree it like a new mount, even though an empty version of it already
18551 // committed. Disconnect the alternate pointers.
18552 current$$1.alternate = null;
18553 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
18554
18555 workInProgress.effectTag |= Placement;
18556 } // In the initial pass we might need to construct the instance.
18557
18558
18559 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
18560 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
18561 shouldUpdate = true;
18562 } else if (current$$1 === null) {
18563 // In a resume, we'll already have an instance we can reuse.
18564 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
18565 } else {
18566 shouldUpdate = updateClassInstance(current$$1, workInProgress, Component, nextProps, renderExpirationTime);
18567 }
18568
18569 var nextUnitOfWork = finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime);
18570
18571 {
18572 var inst = workInProgress.stateNode;
18573
18574 if (inst.props !== nextProps) {
18575 !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;
18576 didWarnAboutReassigningProps = true;
18577 }
18578 }
18579
18580 return nextUnitOfWork;
18581}
18582
18583function finishClassComponent(current$$1, workInProgress, Component, shouldUpdate, hasContext, renderExpirationTime) {
18584 // Refs should update even if shouldComponentUpdate returns false
18585 markRef(current$$1, workInProgress);
18586 var didCaptureError = (workInProgress.effectTag & DidCapture) !== NoEffect;
18587
18588 if (!shouldUpdate && !didCaptureError) {
18589 // Context providers should defer to sCU for rendering
18590 if (hasContext) {
18591 invalidateContextProvider(workInProgress, Component, false);
18592 }
18593
18594 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18595 }
18596
18597 var instance = workInProgress.stateNode; // Rerender
18598
18599 ReactCurrentOwner$3.current = workInProgress;
18600 var nextChildren;
18601
18602 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
18603 // If we captured an error, but getDerivedStateFrom catch is not defined,
18604 // unmount all the children. componentDidCatch will schedule an update to
18605 // re-render a fallback. This is temporary until we migrate everyone to
18606 // the new API.
18607 // TODO: Warn in a future release.
18608 nextChildren = null;
18609
18610 if (enableProfilerTimer) {
18611 stopProfilerTimerIfRunning(workInProgress);
18612 }
18613 } else {
18614 {
18615 setCurrentPhase('render');
18616 nextChildren = instance.render();
18617
18618 if (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
18619 instance.render();
18620 }
18621
18622 setCurrentPhase(null);
18623 }
18624 } // React DevTools reads this flag.
18625
18626
18627 workInProgress.effectTag |= PerformedWork;
18628
18629 if (current$$1 !== null && didCaptureError) {
18630 // If we're recovering from an error, reconcile without reusing any of
18631 // the existing children. Conceptually, the normal children and the children
18632 // that are shown on error are two different sets, so we shouldn't reuse
18633 // normal children even if their identities match.
18634 forceUnmountCurrentAndReconcile(current$$1, workInProgress, nextChildren, renderExpirationTime);
18635 } else {
18636 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18637 } // Memoize state using the values we just used to render.
18638 // TODO: Restructure so we never read values from the instance.
18639
18640
18641 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
18642
18643 if (hasContext) {
18644 invalidateContextProvider(workInProgress, Component, true);
18645 }
18646
18647 return workInProgress.child;
18648}
18649
18650function pushHostRootContext(workInProgress) {
18651 var root = workInProgress.stateNode;
18652
18653 if (root.pendingContext) {
18654 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
18655 } else if (root.context) {
18656 // Should always be set
18657 pushTopLevelContextObject(workInProgress, root.context, false);
18658 }
18659
18660 pushHostContainer(workInProgress, root.containerInfo);
18661}
18662
18663function updateHostRoot(current$$1, workInProgress, renderExpirationTime) {
18664 pushHostRootContext(workInProgress);
18665 var updateQueue = workInProgress.updateQueue;
18666
18667 if (!(updateQueue !== null)) {
18668 {
18669 throw Error("If the root does not have an updateQueue, we should have already bailed out. This error is likely caused by a bug in React. Please file an issue.");
18670 }
18671 }
18672
18673 var nextProps = workInProgress.pendingProps;
18674 var prevState = workInProgress.memoizedState;
18675 var prevChildren = prevState !== null ? prevState.element : null;
18676 processUpdateQueue(workInProgress, updateQueue, nextProps, null, renderExpirationTime);
18677 var nextState = workInProgress.memoizedState; // Caution: React DevTools currently depends on this property
18678 // being called "element".
18679
18680 var nextChildren = nextState.element;
18681
18682 if (nextChildren === prevChildren) {
18683 // If the state is the same as before, that's a bailout because we had
18684 // no work that expires at this time.
18685 resetHydrationState();
18686 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
18687 }
18688
18689 var root = workInProgress.stateNode;
18690
18691 if (root.hydrate && enterHydrationState(workInProgress)) {
18692 // If we don't have any current children this might be the first pass.
18693 // We always try to hydrate. If this isn't a hydration pass there won't
18694 // be any children to hydrate which is effectively the same thing as
18695 // not hydrating.
18696 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
18697 workInProgress.child = child;
18698 var node = child;
18699
18700 while (node) {
18701 // Mark each child as hydrating. This is a fast path to know whether this
18702 // tree is part of a hydrating tree. This is used to determine if a child
18703 // node has fully mounted yet, and for scheduling event replaying.
18704 // Conceptually this is similar to Placement in that a new subtree is
18705 // inserted into the React tree here. It just happens to not need DOM
18706 // mutations because it already exists.
18707 node.effectTag = node.effectTag & ~Placement | Hydrating;
18708 node = node.sibling;
18709 }
18710 } else {
18711 // Otherwise reset hydration state in case we aborted and resumed another
18712 // root.
18713 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18714 resetHydrationState();
18715 }
18716
18717 return workInProgress.child;
18718}
18719
18720function updateHostComponent(current$$1, workInProgress, renderExpirationTime) {
18721 pushHostContext(workInProgress);
18722
18723 if (current$$1 === null) {
18724 tryToClaimNextHydratableInstance(workInProgress);
18725 }
18726
18727 var type = workInProgress.type;
18728 var nextProps = workInProgress.pendingProps;
18729 var prevProps = current$$1 !== null ? current$$1.memoizedProps : null;
18730 var nextChildren = nextProps.children;
18731 var isDirectTextChild = shouldSetTextContent(type, nextProps);
18732
18733 if (isDirectTextChild) {
18734 // We special case a direct text child of a host node. This is a common
18735 // case. We won't handle it as a reified child. We will instead handle
18736 // this in the host environment that also have access to this prop. That
18737 // avoids allocating another HostText fiber and traversing it.
18738 nextChildren = null;
18739 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
18740 // If we're switching from a direct text child to a normal child, or to
18741 // empty, we need to schedule the text content to be reset.
18742 workInProgress.effectTag |= ContentReset;
18743 }
18744
18745 markRef(current$$1, workInProgress); // Check the host config to see if the children are offscreen/hidden.
18746
18747 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(type, nextProps)) {
18748 if (enableSchedulerTracing) {
18749 markSpawnedWork(Never);
18750 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
18751
18752
18753 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
18754 return null;
18755 }
18756
18757 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
18758 return workInProgress.child;
18759}
18760
18761function updateHostText(current$$1, workInProgress) {
18762 if (current$$1 === null) {
18763 tryToClaimNextHydratableInstance(workInProgress);
18764 } // Nothing to do here. This is terminal. We'll do the completion step
18765 // immediately after.
18766
18767
18768 return null;
18769}
18770
18771function mountLazyComponent(_current, workInProgress, elementType, updateExpirationTime, renderExpirationTime) {
18772 if (_current !== null) {
18773 // An lazy component only mounts if it suspended inside a non-
18774 // concurrent tree, in an inconsistent state. We want to treat it like
18775 // a new mount, even though an empty version of it already committed.
18776 // Disconnect the alternate pointers.
18777 _current.alternate = null;
18778 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
18779
18780 workInProgress.effectTag |= Placement;
18781 }
18782
18783 var props = workInProgress.pendingProps; // We can't start a User Timing measurement with correct label yet.
18784 // Cancel and resume right after we know the tag.
18785
18786 cancelWorkTimer(workInProgress);
18787 var Component = readLazyComponentType(elementType); // Store the unwrapped component in the type.
18788
18789 workInProgress.type = Component;
18790 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
18791 startWorkTimer(workInProgress);
18792 var resolvedProps = resolveDefaultProps(Component, props);
18793 var child;
18794
18795 switch (resolvedTag) {
18796 case FunctionComponent:
18797 {
18798 {
18799 validateFunctionComponentInDev(workInProgress, Component);
18800 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
18801 }
18802
18803 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
18804 break;
18805 }
18806
18807 case ClassComponent:
18808 {
18809 {
18810 workInProgress.type = Component = resolveClassForHotReloading(Component);
18811 }
18812
18813 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderExpirationTime);
18814 break;
18815 }
18816
18817 case ForwardRef:
18818 {
18819 {
18820 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
18821 }
18822
18823 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderExpirationTime);
18824 break;
18825 }
18826
18827 case MemoComponent:
18828 {
18829 {
18830 if (workInProgress.type !== workInProgress.elementType) {
18831 var outerPropTypes = Component.propTypes;
18832
18833 if (outerPropTypes) {
18834 checkPropTypes_1(outerPropTypes, resolvedProps, // Resolved for outer only
18835 'prop', getComponentName(Component), getCurrentFiberStackInDev);
18836 }
18837 }
18838 }
18839
18840 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
18841 updateExpirationTime, renderExpirationTime);
18842 break;
18843 }
18844
18845 default:
18846 {
18847 var hint = '';
18848
18849 {
18850 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
18851 hint = ' Did you wrap a component in React.lazy() more than once?';
18852 }
18853 } // This message intentionally doesn't mention ForwardRef or MemoComponent
18854 // because the fact that it's a separate type of work is an
18855 // implementation detail.
18856
18857
18858 {
18859 {
18860 throw Error("Element type is invalid. Received a promise that resolves to: " + Component + ". Lazy element type must resolve to a class or function." + hint);
18861 }
18862 }
18863 }
18864 }
18865
18866 return child;
18867}
18868
18869function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderExpirationTime) {
18870 if (_current !== null) {
18871 // An incomplete component only mounts if it suspended inside a non-
18872 // concurrent tree, in an inconsistent state. We want to treat it like
18873 // a new mount, even though an empty version of it already committed.
18874 // Disconnect the alternate pointers.
18875 _current.alternate = null;
18876 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
18877
18878 workInProgress.effectTag |= Placement;
18879 } // Promote the fiber to a class and try rendering again.
18880
18881
18882 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
18883 // Push context providers early to prevent context stack mismatches.
18884 // During mounting we don't know the child context yet as the instance doesn't exist.
18885 // We will invalidate the child context in finishClassComponent() right after rendering.
18886
18887 var hasContext;
18888
18889 if (isContextProvider(Component)) {
18890 hasContext = true;
18891 pushContextProvider(workInProgress);
18892 } else {
18893 hasContext = false;
18894 }
18895
18896 prepareToReadContext(workInProgress, renderExpirationTime);
18897 constructClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
18898 mountClassInstance(workInProgress, Component, nextProps, renderExpirationTime);
18899 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
18900}
18901
18902function mountIndeterminateComponent(_current, workInProgress, Component, renderExpirationTime) {
18903 if (_current !== null) {
18904 // An indeterminate component only mounts if it suspended inside a non-
18905 // concurrent tree, in an inconsistent state. We want to treat it like
18906 // a new mount, even though an empty version of it already committed.
18907 // Disconnect the alternate pointers.
18908 _current.alternate = null;
18909 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
18910
18911 workInProgress.effectTag |= Placement;
18912 }
18913
18914 var props = workInProgress.pendingProps;
18915 var context;
18916
18917 if (!disableLegacyContext) {
18918 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
18919 context = getMaskedContext(workInProgress, unmaskedContext);
18920 }
18921
18922 prepareToReadContext(workInProgress, renderExpirationTime);
18923 var value;
18924
18925 {
18926 if (Component.prototype && typeof Component.prototype.render === 'function') {
18927 var componentName = getComponentName(Component) || 'Unknown';
18928
18929 if (!didWarnAboutBadClass[componentName]) {
18930 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);
18931 didWarnAboutBadClass[componentName] = true;
18932 }
18933 }
18934
18935 if (workInProgress.mode & StrictMode) {
18936 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
18937 }
18938
18939 ReactCurrentOwner$3.current = workInProgress;
18940 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
18941 } // React DevTools reads this flag.
18942
18943
18944 workInProgress.effectTag |= PerformedWork;
18945
18946 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
18947 {
18948 var _componentName = getComponentName(Component) || 'Unknown';
18949
18950 if (!didWarnAboutModulePatternComponent[_componentName]) {
18951 warningWithoutStack$1(false, 'The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
18952 didWarnAboutModulePatternComponent[_componentName] = true;
18953 }
18954 } // Proceed under the assumption that this is a class instance
18955
18956
18957 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
18958
18959 resetHooks(); // Push context providers early to prevent context stack mismatches.
18960 // During mounting we don't know the child context yet as the instance doesn't exist.
18961 // We will invalidate the child context in finishClassComponent() right after rendering.
18962
18963 var hasContext = false;
18964
18965 if (isContextProvider(Component)) {
18966 hasContext = true;
18967 pushContextProvider(workInProgress);
18968 } else {
18969 hasContext = false;
18970 }
18971
18972 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
18973 var getDerivedStateFromProps = Component.getDerivedStateFromProps;
18974
18975 if (typeof getDerivedStateFromProps === 'function') {
18976 applyDerivedStateFromProps(workInProgress, Component, getDerivedStateFromProps, props);
18977 }
18978
18979 adoptClassInstance(workInProgress, value);
18980 mountClassInstance(workInProgress, Component, props, renderExpirationTime);
18981 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderExpirationTime);
18982 } else {
18983 // Proceed under the assumption that this is a function component
18984 workInProgress.tag = FunctionComponent;
18985
18986 {
18987 if (disableLegacyContext && Component.contextTypes) {
18988 warningWithoutStack$1(false, '%s uses the legacy contextTypes API which is no longer supported. ' + 'Use React.createContext() with React.useContext() instead.', getComponentName(Component) || 'Unknown');
18989 }
18990
18991 if (debugRenderPhaseSideEffectsForStrictMode && workInProgress.mode & StrictMode) {
18992 // Only double-render components with Hooks
18993 if (workInProgress.memoizedState !== null) {
18994 value = renderWithHooks(null, workInProgress, Component, props, context, renderExpirationTime);
18995 }
18996 }
18997 }
18998
18999 reconcileChildren(null, workInProgress, value, renderExpirationTime);
19000
19001 {
19002 validateFunctionComponentInDev(workInProgress, Component);
19003 }
19004
19005 return workInProgress.child;
19006 }
19007}
19008
19009function validateFunctionComponentInDev(workInProgress, Component) {
19010 if (Component) {
19011 !!Component.childContextTypes ? warningWithoutStack$1(false, '%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component') : void 0;
19012 }
19013
19014 if (workInProgress.ref !== null) {
19015 var info = '';
19016 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
19017
19018 if (ownerName) {
19019 info += '\n\nCheck the render method of `' + ownerName + '`.';
19020 }
19021
19022 var warningKey = ownerName || workInProgress._debugID || '';
19023 var debugSource = workInProgress._debugSource;
19024
19025 if (debugSource) {
19026 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
19027 }
19028
19029 if (!didWarnAboutFunctionRefs[warningKey]) {
19030 didWarnAboutFunctionRefs[warningKey] = true;
19031 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);
19032 }
19033 }
19034
19035 if (warnAboutDefaultPropsOnFunctionComponents && Component.defaultProps !== undefined) {
19036 var componentName = getComponentName(Component) || 'Unknown';
19037
19038 if (!didWarnAboutDefaultPropsOnFunctionComponent[componentName]) {
19039 warningWithoutStack$1(false, '%s: Support for defaultProps will be removed from function components ' + 'in a future major release. Use JavaScript default parameters instead.', componentName);
19040 didWarnAboutDefaultPropsOnFunctionComponent[componentName] = true;
19041 }
19042 }
19043
19044 if (typeof Component.getDerivedStateFromProps === 'function') {
19045 var _componentName2 = getComponentName(Component) || 'Unknown';
19046
19047 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2]) {
19048 warningWithoutStack$1(false, '%s: Function components do not support getDerivedStateFromProps.', _componentName2);
19049 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName2] = true;
19050 }
19051 }
19052
19053 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
19054 var _componentName3 = getComponentName(Component) || 'Unknown';
19055
19056 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName3]) {
19057 warningWithoutStack$1(false, '%s: Function components do not support contextType.', _componentName3);
19058 didWarnAboutContextTypeOnFunctionComponent[_componentName3] = true;
19059 }
19060 }
19061}
19062
19063var SUSPENDED_MARKER = {
19064 dehydrated: null,
19065 retryTime: NoWork
19066};
19067
19068function shouldRemainOnFallback(suspenseContext, current$$1, workInProgress) {
19069 // If the context is telling us that we should show a fallback, and we're not
19070 // already showing content, then we should show the fallback instead.
19071 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback) && (current$$1 === null || current$$1.memoizedState !== null);
19072}
19073
19074function updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime) {
19075 var mode = workInProgress.mode;
19076 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
19077
19078 {
19079 if (shouldSuspend(workInProgress)) {
19080 workInProgress.effectTag |= DidCapture;
19081 }
19082 }
19083
19084 var suspenseContext = suspenseStackCursor.current;
19085 var nextDidTimeout = false;
19086 var didSuspend = (workInProgress.effectTag & DidCapture) !== NoEffect;
19087
19088 if (didSuspend || shouldRemainOnFallback(suspenseContext, current$$1, workInProgress)) {
19089 // Something in this boundary's subtree already suspended. Switch to
19090 // rendering the fallback children.
19091 nextDidTimeout = true;
19092 workInProgress.effectTag &= ~DidCapture;
19093 } else {
19094 // Attempting the main content
19095 if (current$$1 === null || current$$1.memoizedState !== null) {
19096 // This is a new mount or this boundary is already showing a fallback state.
19097 // Mark this subtree context as having at least one invisible parent that could
19098 // handle the fallback state.
19099 // Boundaries without fallbacks or should be avoided are not considered since
19100 // they cannot handle preferred fallback states.
19101 if (nextProps.fallback !== undefined && nextProps.unstable_avoidThisFallback !== true) {
19102 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
19103 }
19104 }
19105 }
19106
19107 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19108 pushSuspenseContext(workInProgress, suspenseContext);
19109
19110 {
19111 if ('maxDuration' in nextProps) {
19112 if (!didWarnAboutMaxDuration) {
19113 didWarnAboutMaxDuration = true;
19114 warning$1(false, 'maxDuration has been removed from React. ' + 'Remove the maxDuration prop.');
19115 }
19116 }
19117 } // This next part is a bit confusing. If the children timeout, we switch to
19118 // showing the fallback children in place of the "primary" children.
19119 // However, we don't want to delete the primary children because then their
19120 // state will be lost (both the React state and the host state, e.g.
19121 // uncontrolled form inputs). Instead we keep them mounted and hide them.
19122 // Both the fallback children AND the primary children are rendered at the
19123 // same time. Once the primary children are un-suspended, we can delete
19124 // the fallback children — don't need to preserve their state.
19125 //
19126 // The two sets of children are siblings in the host environment, but
19127 // semantically, for purposes of reconciliation, they are two separate sets.
19128 // So we store them using two fragment fibers.
19129 //
19130 // However, we want to avoid allocating extra fibers for every placeholder.
19131 // They're only necessary when the children time out, because that's the
19132 // only time when both sets are mounted.
19133 //
19134 // So, the extra fragment fibers are only used if the children time out.
19135 // Otherwise, we render the primary children directly. This requires some
19136 // custom reconciliation logic to preserve the state of the primary
19137 // children. It's essentially a very basic form of re-parenting.
19138
19139
19140 if (current$$1 === null) {
19141 // If we're currently hydrating, try to hydrate this boundary.
19142 // But only if this has a fallback.
19143 if (nextProps.fallback !== undefined) {
19144 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
19145
19146 if (enableSuspenseServerRenderer) {
19147 var suspenseState = workInProgress.memoizedState;
19148
19149 if (suspenseState !== null) {
19150 var dehydrated = suspenseState.dehydrated;
19151
19152 if (dehydrated !== null) {
19153 return mountDehydratedSuspenseComponent(workInProgress, dehydrated, renderExpirationTime);
19154 }
19155 }
19156 }
19157 } // This is the initial mount. This branch is pretty simple because there's
19158 // no previous state that needs to be preserved.
19159
19160
19161 if (nextDidTimeout) {
19162 // Mount separate fragments for primary and fallback children.
19163 var nextFallbackChildren = nextProps.fallback;
19164 var primaryChildFragment = createFiberFromFragment(null, mode, NoWork, null);
19165 primaryChildFragment.return = workInProgress;
19166
19167 if ((workInProgress.mode & BlockingMode) === NoMode) {
19168 // Outside of blocking mode, we commit the effects from the
19169 // partially completed, timed-out tree, too.
19170 var progressedState = workInProgress.memoizedState;
19171 var progressedPrimaryChild = progressedState !== null ? workInProgress.child.child : workInProgress.child;
19172 primaryChildFragment.child = progressedPrimaryChild;
19173 var progressedChild = progressedPrimaryChild;
19174
19175 while (progressedChild !== null) {
19176 progressedChild.return = primaryChildFragment;
19177 progressedChild = progressedChild.sibling;
19178 }
19179 }
19180
19181 var fallbackChildFragment = createFiberFromFragment(nextFallbackChildren, mode, renderExpirationTime, null);
19182 fallbackChildFragment.return = workInProgress;
19183 primaryChildFragment.sibling = fallbackChildFragment; // Skip the primary children, and continue working on the
19184 // fallback children.
19185
19186 workInProgress.memoizedState = SUSPENDED_MARKER;
19187 workInProgress.child = primaryChildFragment;
19188 return fallbackChildFragment;
19189 } else {
19190 // Mount the primary children without an intermediate fragment fiber.
19191 var nextPrimaryChildren = nextProps.children;
19192 workInProgress.memoizedState = null;
19193 return workInProgress.child = mountChildFibers(workInProgress, null, nextPrimaryChildren, renderExpirationTime);
19194 }
19195 } else {
19196 // This is an update. This branch is more complicated because we need to
19197 // ensure the state of the primary children is preserved.
19198 var prevState = current$$1.memoizedState;
19199
19200 if (prevState !== null) {
19201 if (enableSuspenseServerRenderer) {
19202 var _dehydrated = prevState.dehydrated;
19203
19204 if (_dehydrated !== null) {
19205 if (!didSuspend) {
19206 return updateDehydratedSuspenseComponent(current$$1, workInProgress, _dehydrated, prevState, renderExpirationTime);
19207 } else if (workInProgress.memoizedState !== null) {
19208 // Something suspended and we should still be in dehydrated mode.
19209 // Leave the existing child in place.
19210 workInProgress.child = current$$1.child; // The dehydrated completion pass expects this flag to be there
19211 // but the normal suspense pass doesn't.
19212
19213 workInProgress.effectTag |= DidCapture;
19214 return null;
19215 } else {
19216 // Suspended but we should no longer be in dehydrated mode.
19217 // Therefore we now have to render the fallback. Wrap the children
19218 // in a fragment fiber to keep them separate from the fallback
19219 // children.
19220 var _nextFallbackChildren = nextProps.fallback;
19221
19222 var _primaryChildFragment = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
19223 // going to render this fragment.
19224 null, mode, NoWork, null);
19225
19226 _primaryChildFragment.return = workInProgress; // This is always null since we never want the previous child
19227 // that we're not going to hydrate.
19228
19229 _primaryChildFragment.child = null;
19230
19231 if ((workInProgress.mode & BlockingMode) === NoMode) {
19232 // Outside of blocking mode, we commit the effects from the
19233 // partially completed, timed-out tree, too.
19234 var _progressedChild = _primaryChildFragment.child = workInProgress.child;
19235
19236 while (_progressedChild !== null) {
19237 _progressedChild.return = _primaryChildFragment;
19238 _progressedChild = _progressedChild.sibling;
19239 }
19240 } else {
19241 // We will have dropped the effect list which contains the deletion.
19242 // We need to reconcile to delete the current child.
19243 reconcileChildFibers(workInProgress, current$$1.child, null, renderExpirationTime);
19244 } // Because primaryChildFragment is a new fiber that we're inserting as the
19245 // parent of a new tree, we need to set its treeBaseDuration.
19246
19247
19248 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19249 // treeBaseDuration is the sum of all the child tree base durations.
19250 var treeBaseDuration = 0;
19251 var hiddenChild = _primaryChildFragment.child;
19252
19253 while (hiddenChild !== null) {
19254 treeBaseDuration += hiddenChild.treeBaseDuration;
19255 hiddenChild = hiddenChild.sibling;
19256 }
19257
19258 _primaryChildFragment.treeBaseDuration = treeBaseDuration;
19259 } // Create a fragment from the fallback children, too.
19260
19261
19262 var _fallbackChildFragment = createFiberFromFragment(_nextFallbackChildren, mode, renderExpirationTime, null);
19263
19264 _fallbackChildFragment.return = workInProgress;
19265 _primaryChildFragment.sibling = _fallbackChildFragment;
19266 _fallbackChildFragment.effectTag |= Placement;
19267 _primaryChildFragment.childExpirationTime = NoWork;
19268 workInProgress.memoizedState = SUSPENDED_MARKER;
19269 workInProgress.child = _primaryChildFragment; // Skip the primary children, and continue working on the
19270 // fallback children.
19271
19272 return _fallbackChildFragment;
19273 }
19274 }
19275 } // The current tree already timed out. That means each child set is
19276 // wrapped in a fragment fiber.
19277
19278
19279 var currentPrimaryChildFragment = current$$1.child;
19280 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
19281
19282 if (nextDidTimeout) {
19283 // Still timed out. Reuse the current primary children by cloning
19284 // its fragment. We're going to skip over these entirely.
19285 var _nextFallbackChildren2 = nextProps.fallback;
19286
19287 var _primaryChildFragment2 = createWorkInProgress(currentPrimaryChildFragment, currentPrimaryChildFragment.pendingProps, NoWork);
19288
19289 _primaryChildFragment2.return = workInProgress;
19290
19291 if ((workInProgress.mode & BlockingMode) === NoMode) {
19292 // Outside of blocking mode, we commit the effects from the
19293 // partially completed, timed-out tree, too.
19294 var _progressedState = workInProgress.memoizedState;
19295
19296 var _progressedPrimaryChild = _progressedState !== null ? workInProgress.child.child : workInProgress.child;
19297
19298 if (_progressedPrimaryChild !== currentPrimaryChildFragment.child) {
19299 _primaryChildFragment2.child = _progressedPrimaryChild;
19300 var _progressedChild2 = _progressedPrimaryChild;
19301
19302 while (_progressedChild2 !== null) {
19303 _progressedChild2.return = _primaryChildFragment2;
19304 _progressedChild2 = _progressedChild2.sibling;
19305 }
19306 }
19307 } // Because primaryChildFragment is a new fiber that we're inserting as the
19308 // parent of a new tree, we need to set its treeBaseDuration.
19309
19310
19311 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19312 // treeBaseDuration is the sum of all the child tree base durations.
19313 var _treeBaseDuration = 0;
19314 var _hiddenChild = _primaryChildFragment2.child;
19315
19316 while (_hiddenChild !== null) {
19317 _treeBaseDuration += _hiddenChild.treeBaseDuration;
19318 _hiddenChild = _hiddenChild.sibling;
19319 }
19320
19321 _primaryChildFragment2.treeBaseDuration = _treeBaseDuration;
19322 } // Clone the fallback child fragment, too. These we'll continue
19323 // working on.
19324
19325
19326 var _fallbackChildFragment2 = createWorkInProgress(currentFallbackChildFragment, _nextFallbackChildren2, currentFallbackChildFragment.expirationTime);
19327
19328 _fallbackChildFragment2.return = workInProgress;
19329 _primaryChildFragment2.sibling = _fallbackChildFragment2;
19330 _primaryChildFragment2.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
19331 // fallback children.
19332
19333 workInProgress.memoizedState = SUSPENDED_MARKER;
19334 workInProgress.child = _primaryChildFragment2;
19335 return _fallbackChildFragment2;
19336 } else {
19337 // No longer suspended. Switch back to showing the primary children,
19338 // and remove the intermediate fragment fiber.
19339 var _nextPrimaryChildren = nextProps.children;
19340 var currentPrimaryChild = currentPrimaryChildFragment.child;
19341 var primaryChild = reconcileChildFibers(workInProgress, currentPrimaryChild, _nextPrimaryChildren, renderExpirationTime); // If this render doesn't suspend, we need to delete the fallback
19342 // children. Wait until the complete phase, after we've confirmed the
19343 // fallback is no longer needed.
19344 // TODO: Would it be better to store the fallback fragment on
19345 // the stateNode?
19346 // Continue rendering the children, like we normally do.
19347
19348 workInProgress.memoizedState = null;
19349 return workInProgress.child = primaryChild;
19350 }
19351 } else {
19352 // The current tree has not already timed out. That means the primary
19353 // children are not wrapped in a fragment fiber.
19354 var _currentPrimaryChild = current$$1.child;
19355
19356 if (nextDidTimeout) {
19357 // Timed out. Wrap the children in a fragment fiber to keep them
19358 // separate from the fallback children.
19359 var _nextFallbackChildren3 = nextProps.fallback;
19360
19361 var _primaryChildFragment3 = createFiberFromFragment( // It shouldn't matter what the pending props are because we aren't
19362 // going to render this fragment.
19363 null, mode, NoWork, null);
19364
19365 _primaryChildFragment3.return = workInProgress;
19366 _primaryChildFragment3.child = _currentPrimaryChild;
19367
19368 if (_currentPrimaryChild !== null) {
19369 _currentPrimaryChild.return = _primaryChildFragment3;
19370 } // Even though we're creating a new fiber, there are no new children,
19371 // because we're reusing an already mounted tree. So we don't need to
19372 // schedule a placement.
19373 // primaryChildFragment.effectTag |= Placement;
19374
19375
19376 if ((workInProgress.mode & BlockingMode) === NoMode) {
19377 // Outside of blocking mode, we commit the effects from the
19378 // partially completed, timed-out tree, too.
19379 var _progressedState2 = workInProgress.memoizedState;
19380
19381 var _progressedPrimaryChild2 = _progressedState2 !== null ? workInProgress.child.child : workInProgress.child;
19382
19383 _primaryChildFragment3.child = _progressedPrimaryChild2;
19384 var _progressedChild3 = _progressedPrimaryChild2;
19385
19386 while (_progressedChild3 !== null) {
19387 _progressedChild3.return = _primaryChildFragment3;
19388 _progressedChild3 = _progressedChild3.sibling;
19389 }
19390 } // Because primaryChildFragment is a new fiber that we're inserting as the
19391 // parent of a new tree, we need to set its treeBaseDuration.
19392
19393
19394 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
19395 // treeBaseDuration is the sum of all the child tree base durations.
19396 var _treeBaseDuration2 = 0;
19397 var _hiddenChild2 = _primaryChildFragment3.child;
19398
19399 while (_hiddenChild2 !== null) {
19400 _treeBaseDuration2 += _hiddenChild2.treeBaseDuration;
19401 _hiddenChild2 = _hiddenChild2.sibling;
19402 }
19403
19404 _primaryChildFragment3.treeBaseDuration = _treeBaseDuration2;
19405 } // Create a fragment from the fallback children, too.
19406
19407
19408 var _fallbackChildFragment3 = createFiberFromFragment(_nextFallbackChildren3, mode, renderExpirationTime, null);
19409
19410 _fallbackChildFragment3.return = workInProgress;
19411 _primaryChildFragment3.sibling = _fallbackChildFragment3;
19412 _fallbackChildFragment3.effectTag |= Placement;
19413 _primaryChildFragment3.childExpirationTime = NoWork; // Skip the primary children, and continue working on the
19414 // fallback children.
19415
19416 workInProgress.memoizedState = SUSPENDED_MARKER;
19417 workInProgress.child = _primaryChildFragment3;
19418 return _fallbackChildFragment3;
19419 } else {
19420 // Still haven't timed out. Continue rendering the children, like we
19421 // normally do.
19422 workInProgress.memoizedState = null;
19423 var _nextPrimaryChildren2 = nextProps.children;
19424 return workInProgress.child = reconcileChildFibers(workInProgress, _currentPrimaryChild, _nextPrimaryChildren2, renderExpirationTime);
19425 }
19426 }
19427 }
19428}
19429
19430function retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime) {
19431 // We're now not suspended nor dehydrated.
19432 workInProgress.memoizedState = null; // Retry with the full children.
19433
19434 var nextProps = workInProgress.pendingProps;
19435 var nextChildren = nextProps.children; // This will ensure that the children get Placement effects and
19436 // that the old child gets a Deletion effect.
19437 // We could also call forceUnmountCurrentAndReconcile.
19438
19439 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
19440 return workInProgress.child;
19441}
19442
19443function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderExpirationTime) {
19444 // During the first pass, we'll bail out and not drill into the children.
19445 // Instead, we'll leave the content in place and try to hydrate it later.
19446 if ((workInProgress.mode & BlockingMode) === NoMode) {
19447 {
19448 warning$1(false, 'Cannot hydrate Suspense in legacy mode. Switch from ' + 'ReactDOM.hydrate(element, container) to ' + 'ReactDOM.createBlockingRoot(container, { hydrate: true })' + '.render(element) or remove the Suspense components from ' + 'the server rendered components.');
19449 }
19450
19451 workInProgress.expirationTime = Sync;
19452 } else if (isSuspenseInstanceFallback(suspenseInstance)) {
19453 // This is a client-only boundary. Since we won't get any content from the server
19454 // for this, we need to schedule that at a higher priority based on when it would
19455 // have timed out. In theory we could render it in this pass but it would have the
19456 // wrong priority associated with it and will prevent hydration of parent path.
19457 // Instead, we'll leave work left on it to render it in a separate commit.
19458 // TODO This time should be the time at which the server rendered response that is
19459 // a parent to this boundary was displayed. However, since we currently don't have
19460 // a protocol to transfer that time, we'll just estimate it by using the current
19461 // time. This will mean that Suspense timeouts are slightly shifted to later than
19462 // they should be.
19463 var serverDisplayTime = requestCurrentTimeForUpdate(); // Schedule a normal pri update to render this content.
19464
19465 var newExpirationTime = computeAsyncExpiration(serverDisplayTime);
19466
19467 if (enableSchedulerTracing) {
19468 markSpawnedWork(newExpirationTime);
19469 }
19470
19471 workInProgress.expirationTime = newExpirationTime;
19472 } else {
19473 // We'll continue hydrating the rest at offscreen priority since we'll already
19474 // be showing the right content coming from the server, it is no rush.
19475 workInProgress.expirationTime = Never;
19476
19477 if (enableSchedulerTracing) {
19478 markSpawnedWork(Never);
19479 }
19480 }
19481
19482 return null;
19483}
19484
19485function updateDehydratedSuspenseComponent(current$$1, workInProgress, suspenseInstance, suspenseState, renderExpirationTime) {
19486 // We should never be hydrating at this point because it is the first pass,
19487 // but after we've already committed once.
19488 warnIfHydrating();
19489
19490 if ((workInProgress.mode & BlockingMode) === NoMode) {
19491 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
19492 }
19493
19494 if (isSuspenseInstanceFallback(suspenseInstance)) {
19495 // This boundary is in a permanent fallback state. In this case, we'll never
19496 // get an update and we'll never be able to hydrate the final content. Let's just try the
19497 // client side render instead.
19498 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
19499 } // We use childExpirationTime to indicate that a child might depend on context, so if
19500 // any context has changed, we need to treat is as if the input might have changed.
19501
19502
19503 var hasContextChanged$$1 = current$$1.childExpirationTime >= renderExpirationTime;
19504
19505 if (didReceiveUpdate || hasContextChanged$$1) {
19506 // This boundary has changed since the first render. This means that we are now unable to
19507 // hydrate it. We might still be able to hydrate it using an earlier expiration time, if
19508 // we are rendering at lower expiration than sync.
19509 if (renderExpirationTime < Sync) {
19510 if (suspenseState.retryTime <= renderExpirationTime) {
19511 // This render is even higher pri than we've seen before, let's try again
19512 // at even higher pri.
19513 var attemptHydrationAtExpirationTime = renderExpirationTime + 1;
19514 suspenseState.retryTime = attemptHydrationAtExpirationTime;
19515 scheduleWork(current$$1, attemptHydrationAtExpirationTime); // TODO: Early abort this render.
19516 } else {// We have already tried to ping at a higher priority than we're rendering with
19517 // so if we got here, we must have failed to hydrate at those levels. We must
19518 // now give up. Instead, we're going to delete the whole subtree and instead inject
19519 // a new real Suspense boundary to take its place, which may render content
19520 // or fallback. This might suspend for a while and if it does we might still have
19521 // an opportunity to hydrate before this pass commits.
19522 }
19523 } // If we have scheduled higher pri work above, this will probably just abort the render
19524 // since we now have higher priority work, but in case it doesn't, we need to prepare to
19525 // render something, if we time out. Even if that requires us to delete everything and
19526 // skip hydration.
19527 // Delay having to do this as long as the suspense timeout allows us.
19528
19529
19530 renderDidSuspendDelayIfPossible();
19531 return retrySuspenseComponentWithoutHydrating(current$$1, workInProgress, renderExpirationTime);
19532 } else if (isSuspenseInstancePending(suspenseInstance)) {
19533 // This component is still pending more data from the server, so we can't hydrate its
19534 // content. We treat it as if this component suspended itself. It might seem as if
19535 // we could just try to render it client-side instead. However, this will perform a
19536 // lot of unnecessary work and is unlikely to complete since it often will suspend
19537 // on missing data anyway. Additionally, the server might be able to render more
19538 // than we can on the client yet. In that case we'd end up with more fallback states
19539 // on the client than if we just leave it alone. If the server times out or errors
19540 // these should update this boundary to the permanent Fallback state instead.
19541 // Mark it as having captured (i.e. suspended).
19542 workInProgress.effectTag |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
19543
19544 workInProgress.child = current$$1.child; // Register a callback to retry this boundary once the server has sent the result.
19545
19546 registerSuspenseInstanceRetry(suspenseInstance, retryDehydratedSuspenseBoundary.bind(null, current$$1));
19547 return null;
19548 } else {
19549 // This is the first attempt.
19550 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance);
19551 var nextProps = workInProgress.pendingProps;
19552 var nextChildren = nextProps.children;
19553 var child = mountChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
19554 var node = child;
19555
19556 while (node) {
19557 // Mark each child as hydrating. This is a fast path to know whether this
19558 // tree is part of a hydrating tree. This is used to determine if a child
19559 // node has fully mounted yet, and for scheduling event replaying.
19560 // Conceptually this is similar to Placement in that a new subtree is
19561 // inserted into the React tree here. It just happens to not need DOM
19562 // mutations because it already exists.
19563 node.effectTag |= Hydrating;
19564 node = node.sibling;
19565 }
19566
19567 workInProgress.child = child;
19568 return workInProgress.child;
19569 }
19570}
19571
19572function scheduleWorkOnFiber(fiber, renderExpirationTime) {
19573 if (fiber.expirationTime < renderExpirationTime) {
19574 fiber.expirationTime = renderExpirationTime;
19575 }
19576
19577 var alternate = fiber.alternate;
19578
19579 if (alternate !== null && alternate.expirationTime < renderExpirationTime) {
19580 alternate.expirationTime = renderExpirationTime;
19581 }
19582
19583 scheduleWorkOnParentPath(fiber.return, renderExpirationTime);
19584}
19585
19586function propagateSuspenseContextChange(workInProgress, firstChild, renderExpirationTime) {
19587 // Mark any Suspense boundaries with fallbacks as having work to do.
19588 // If they were previously forced into fallbacks, they may now be able
19589 // to unblock.
19590 var node = firstChild;
19591
19592 while (node !== null) {
19593 if (node.tag === SuspenseComponent) {
19594 var state = node.memoizedState;
19595
19596 if (state !== null) {
19597 scheduleWorkOnFiber(node, renderExpirationTime);
19598 }
19599 } else if (node.tag === SuspenseListComponent) {
19600 // If the tail is hidden there might not be an Suspense boundaries
19601 // to schedule work on. In this case we have to schedule it on the
19602 // list itself.
19603 // We don't have to traverse to the children of the list since
19604 // the list will propagate the change when it rerenders.
19605 scheduleWorkOnFiber(node, renderExpirationTime);
19606 } else if (node.child !== null) {
19607 node.child.return = node;
19608 node = node.child;
19609 continue;
19610 }
19611
19612 if (node === workInProgress) {
19613 return;
19614 }
19615
19616 while (node.sibling === null) {
19617 if (node.return === null || node.return === workInProgress) {
19618 return;
19619 }
19620
19621 node = node.return;
19622 }
19623
19624 node.sibling.return = node.return;
19625 node = node.sibling;
19626 }
19627}
19628
19629function findLastContentRow(firstChild) {
19630 // This is going to find the last row among these children that is already
19631 // showing content on the screen, as opposed to being in fallback state or
19632 // new. If a row has multiple Suspense boundaries, any of them being in the
19633 // fallback state, counts as the whole row being in a fallback state.
19634 // Note that the "rows" will be workInProgress, but any nested children
19635 // will still be current since we haven't rendered them yet. The mounted
19636 // order may not be the same as the new order. We use the new order.
19637 var row = firstChild;
19638 var lastContentRow = null;
19639
19640 while (row !== null) {
19641 var currentRow = row.alternate; // New rows can't be content rows.
19642
19643 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
19644 lastContentRow = row;
19645 }
19646
19647 row = row.sibling;
19648 }
19649
19650 return lastContentRow;
19651}
19652
19653function validateRevealOrder(revealOrder) {
19654 {
19655 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
19656 didWarnAboutRevealOrder[revealOrder] = true;
19657
19658 if (typeof revealOrder === 'string') {
19659 switch (revealOrder.toLowerCase()) {
19660 case 'together':
19661 case 'forwards':
19662 case 'backwards':
19663 {
19664 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
19665 break;
19666 }
19667
19668 case 'forward':
19669 case 'backward':
19670 {
19671 warning$1(false, '"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
19672 break;
19673 }
19674
19675 default:
19676 warning$1(false, '"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
19677 break;
19678 }
19679 } else {
19680 warning$1(false, '%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
19681 }
19682 }
19683 }
19684}
19685
19686function validateTailOptions(tailMode, revealOrder) {
19687 {
19688 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
19689 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
19690 didWarnAboutTailOptions[tailMode] = true;
19691 warning$1(false, '"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
19692 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
19693 didWarnAboutTailOptions[tailMode] = true;
19694 warning$1(false, '<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
19695 }
19696 }
19697 }
19698}
19699
19700function validateSuspenseListNestedChild(childSlot, index) {
19701 {
19702 var isArray = Array.isArray(childSlot);
19703 var isIterable = !isArray && typeof getIteratorFn(childSlot) === 'function';
19704
19705 if (isArray || isIterable) {
19706 var type = isArray ? 'array' : 'iterable';
19707 warning$1(false, 'A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
19708 return false;
19709 }
19710 }
19711
19712 return true;
19713}
19714
19715function validateSuspenseListChildren(children, revealOrder) {
19716 {
19717 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
19718 if (Array.isArray(children)) {
19719 for (var i = 0; i < children.length; i++) {
19720 if (!validateSuspenseListNestedChild(children[i], i)) {
19721 return;
19722 }
19723 }
19724 } else {
19725 var iteratorFn = getIteratorFn(children);
19726
19727 if (typeof iteratorFn === 'function') {
19728 var childrenIterator = iteratorFn.call(children);
19729
19730 if (childrenIterator) {
19731 var step = childrenIterator.next();
19732 var _i = 0;
19733
19734 for (; !step.done; step = childrenIterator.next()) {
19735 if (!validateSuspenseListNestedChild(step.value, _i)) {
19736 return;
19737 }
19738
19739 _i++;
19740 }
19741 }
19742 } else {
19743 warning$1(false, 'A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
19744 }
19745 }
19746 }
19747 }
19748}
19749
19750function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode, lastEffectBeforeRendering) {
19751 var renderState = workInProgress.memoizedState;
19752
19753 if (renderState === null) {
19754 workInProgress.memoizedState = {
19755 isBackwards: isBackwards,
19756 rendering: null,
19757 last: lastContentRow,
19758 tail: tail,
19759 tailExpiration: 0,
19760 tailMode: tailMode,
19761 lastEffect: lastEffectBeforeRendering
19762 };
19763 } else {
19764 // We can reuse the existing object from previous renders.
19765 renderState.isBackwards = isBackwards;
19766 renderState.rendering = null;
19767 renderState.last = lastContentRow;
19768 renderState.tail = tail;
19769 renderState.tailExpiration = 0;
19770 renderState.tailMode = tailMode;
19771 renderState.lastEffect = lastEffectBeforeRendering;
19772 }
19773} // This can end up rendering this component multiple passes.
19774// The first pass splits the children fibers into two sets. A head and tail.
19775// We first render the head. If anything is in fallback state, we do another
19776// pass through beginWork to rerender all children (including the tail) with
19777// the force suspend context. If the first render didn't have anything in
19778// in fallback state. Then we render each row in the tail one-by-one.
19779// That happens in the completeWork phase without going back to beginWork.
19780
19781
19782function updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime) {
19783 var nextProps = workInProgress.pendingProps;
19784 var revealOrder = nextProps.revealOrder;
19785 var tailMode = nextProps.tail;
19786 var newChildren = nextProps.children;
19787 validateRevealOrder(revealOrder);
19788 validateTailOptions(tailMode, revealOrder);
19789 validateSuspenseListChildren(newChildren, revealOrder);
19790 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
19791 var suspenseContext = suspenseStackCursor.current;
19792 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
19793
19794 if (shouldForceFallback) {
19795 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19796 workInProgress.effectTag |= DidCapture;
19797 } else {
19798 var didSuspendBefore = current$$1 !== null && (current$$1.effectTag & DidCapture) !== NoEffect;
19799
19800 if (didSuspendBefore) {
19801 // If we previously forced a fallback, we need to schedule work
19802 // on any nested boundaries to let them know to try to render
19803 // again. This is the same as context updating.
19804 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderExpirationTime);
19805 }
19806
19807 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19808 }
19809
19810 pushSuspenseContext(workInProgress, suspenseContext);
19811
19812 if ((workInProgress.mode & BlockingMode) === NoMode) {
19813 // Outside of blocking mode, SuspenseList doesn't work so we just
19814 // use make it a noop by treating it as the default revealOrder.
19815 workInProgress.memoizedState = null;
19816 } else {
19817 switch (revealOrder) {
19818 case 'forwards':
19819 {
19820 var lastContentRow = findLastContentRow(workInProgress.child);
19821 var tail;
19822
19823 if (lastContentRow === null) {
19824 // The whole list is part of the tail.
19825 // TODO: We could fast path by just rendering the tail now.
19826 tail = workInProgress.child;
19827 workInProgress.child = null;
19828 } else {
19829 // Disconnect the tail rows after the content row.
19830 // We're going to render them separately later.
19831 tail = lastContentRow.sibling;
19832 lastContentRow.sibling = null;
19833 }
19834
19835 initSuspenseListRenderState(workInProgress, false, // isBackwards
19836 tail, lastContentRow, tailMode, workInProgress.lastEffect);
19837 break;
19838 }
19839
19840 case 'backwards':
19841 {
19842 // We're going to find the first row that has existing content.
19843 // At the same time we're going to reverse the list of everything
19844 // we pass in the meantime. That's going to be our tail in reverse
19845 // order.
19846 var _tail = null;
19847 var row = workInProgress.child;
19848 workInProgress.child = null;
19849
19850 while (row !== null) {
19851 var currentRow = row.alternate; // New rows can't be content rows.
19852
19853 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
19854 // This is the beginning of the main content.
19855 workInProgress.child = row;
19856 break;
19857 }
19858
19859 var nextRow = row.sibling;
19860 row.sibling = _tail;
19861 _tail = row;
19862 row = nextRow;
19863 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
19864
19865
19866 initSuspenseListRenderState(workInProgress, true, // isBackwards
19867 _tail, null, // last
19868 tailMode, workInProgress.lastEffect);
19869 break;
19870 }
19871
19872 case 'together':
19873 {
19874 initSuspenseListRenderState(workInProgress, false, // isBackwards
19875 null, // tail
19876 null, // last
19877 undefined, workInProgress.lastEffect);
19878 break;
19879 }
19880
19881 default:
19882 {
19883 // The default reveal order is the same as not having
19884 // a boundary.
19885 workInProgress.memoizedState = null;
19886 }
19887 }
19888 }
19889
19890 return workInProgress.child;
19891}
19892
19893function updatePortalComponent(current$$1, workInProgress, renderExpirationTime) {
19894 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
19895 var nextChildren = workInProgress.pendingProps;
19896
19897 if (current$$1 === null) {
19898 // Portals are special because we don't append the children during mount
19899 // but at commit. Therefore we need to track insertions which the normal
19900 // flow doesn't do during mount. This doesn't happen at the root because
19901 // the root always starts with a "current" with a null child.
19902 // TODO: Consider unifying this with how the root works.
19903 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderExpirationTime);
19904 } else {
19905 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
19906 }
19907
19908 return workInProgress.child;
19909}
19910
19911function updateContextProvider(current$$1, workInProgress, renderExpirationTime) {
19912 var providerType = workInProgress.type;
19913 var context = providerType._context;
19914 var newProps = workInProgress.pendingProps;
19915 var oldProps = workInProgress.memoizedProps;
19916 var newValue = newProps.value;
19917
19918 {
19919 var providerPropTypes = workInProgress.type.propTypes;
19920
19921 if (providerPropTypes) {
19922 checkPropTypes_1(providerPropTypes, newProps, 'prop', 'Context.Provider', getCurrentFiberStackInDev);
19923 }
19924 }
19925
19926 pushProvider(workInProgress, newValue);
19927
19928 if (oldProps !== null) {
19929 var oldValue = oldProps.value;
19930 var changedBits = calculateChangedBits(context, newValue, oldValue);
19931
19932 if (changedBits === 0) {
19933 // No change. Bailout early if children are the same.
19934 if (oldProps.children === newProps.children && !hasContextChanged()) {
19935 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
19936 }
19937 } else {
19938 // The context value changed. Search for matching consumers and schedule
19939 // them to update.
19940 propagateContextChange(workInProgress, context, changedBits, renderExpirationTime);
19941 }
19942 }
19943
19944 var newChildren = newProps.children;
19945 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
19946 return workInProgress.child;
19947}
19948
19949var hasWarnedAboutUsingContextAsConsumer = false;
19950
19951function updateContextConsumer(current$$1, workInProgress, renderExpirationTime) {
19952 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
19953 // DEV mode, we create a separate object for Context.Consumer that acts
19954 // like a proxy to Context. This proxy object adds unnecessary code in PROD
19955 // so we use the old behaviour (Context.Consumer references Context) to
19956 // reduce size and overhead. The separate object references context via
19957 // a property called "_context", which also gives us the ability to check
19958 // in DEV mode if this property exists or not and warn if it does not.
19959
19960 {
19961 if (context._context === undefined) {
19962 // This may be because it's a Context (rather than a Consumer).
19963 // Or it may be because it's older React where they're the same thing.
19964 // We only want to warn if we're sure it's a new React.
19965 if (context !== context.Consumer) {
19966 if (!hasWarnedAboutUsingContextAsConsumer) {
19967 hasWarnedAboutUsingContextAsConsumer = true;
19968 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?');
19969 }
19970 }
19971 } else {
19972 context = context._context;
19973 }
19974 }
19975
19976 var newProps = workInProgress.pendingProps;
19977 var render = newProps.children;
19978
19979 {
19980 !(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;
19981 }
19982
19983 prepareToReadContext(workInProgress, renderExpirationTime);
19984 var newValue = readContext(context, newProps.unstable_observedBits);
19985 var newChildren;
19986
19987 {
19988 ReactCurrentOwner$3.current = workInProgress;
19989 setCurrentPhase('render');
19990 newChildren = render(newValue);
19991 setCurrentPhase(null);
19992 } // React DevTools reads this flag.
19993
19994
19995 workInProgress.effectTag |= PerformedWork;
19996 reconcileChildren(current$$1, workInProgress, newChildren, renderExpirationTime);
19997 return workInProgress.child;
19998}
19999
20000function updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime) {
20001 var fundamentalImpl = workInProgress.type.impl;
20002
20003 if (fundamentalImpl.reconcileChildren === false) {
20004 return null;
20005 }
20006
20007 var nextProps = workInProgress.pendingProps;
20008 var nextChildren = nextProps.children;
20009 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
20010 return workInProgress.child;
20011}
20012
20013function updateScopeComponent(current$$1, workInProgress, renderExpirationTime) {
20014 var nextProps = workInProgress.pendingProps;
20015 var nextChildren = nextProps.children;
20016 reconcileChildren(current$$1, workInProgress, nextChildren, renderExpirationTime);
20017 return workInProgress.child;
20018}
20019
20020function markWorkInProgressReceivedUpdate() {
20021 didReceiveUpdate = true;
20022}
20023
20024function bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime) {
20025 cancelWorkTimer(workInProgress);
20026
20027 if (current$$1 !== null) {
20028 // Reuse previous dependencies
20029 workInProgress.dependencies = current$$1.dependencies;
20030 }
20031
20032 if (enableProfilerTimer) {
20033 // Don't update "base" render times for bailouts.
20034 stopProfilerTimerIfRunning(workInProgress);
20035 }
20036
20037 var updateExpirationTime = workInProgress.expirationTime;
20038
20039 if (updateExpirationTime !== NoWork) {
20040 markUnprocessedUpdateTime(updateExpirationTime);
20041 } // Check if the children have any pending work.
20042
20043
20044 var childExpirationTime = workInProgress.childExpirationTime;
20045
20046 if (childExpirationTime < renderExpirationTime) {
20047 // The children don't have any work either. We can skip them.
20048 // TODO: Once we add back resuming, we should check if the children are
20049 // a work-in-progress set. If so, we need to transfer their effects.
20050 return null;
20051 } else {
20052 // This fiber doesn't have work, but its subtree does. Clone the child
20053 // fibers and continue.
20054 cloneChildFibers(current$$1, workInProgress);
20055 return workInProgress.child;
20056 }
20057}
20058
20059function remountFiber(current$$1, oldWorkInProgress, newWorkInProgress) {
20060 {
20061 var returnFiber = oldWorkInProgress.return;
20062
20063 if (returnFiber === null) {
20064 throw new Error('Cannot swap the root fiber.');
20065 } // Disconnect from the old current.
20066 // It will get deleted.
20067
20068
20069 current$$1.alternate = null;
20070 oldWorkInProgress.alternate = null; // Connect to the new tree.
20071
20072 newWorkInProgress.index = oldWorkInProgress.index;
20073 newWorkInProgress.sibling = oldWorkInProgress.sibling;
20074 newWorkInProgress.return = oldWorkInProgress.return;
20075 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
20076
20077 if (oldWorkInProgress === returnFiber.child) {
20078 returnFiber.child = newWorkInProgress;
20079 } else {
20080 var prevSibling = returnFiber.child;
20081
20082 if (prevSibling === null) {
20083 throw new Error('Expected parent to have a child.');
20084 }
20085
20086 while (prevSibling.sibling !== oldWorkInProgress) {
20087 prevSibling = prevSibling.sibling;
20088
20089 if (prevSibling === null) {
20090 throw new Error('Expected to find the previous sibling.');
20091 }
20092 }
20093
20094 prevSibling.sibling = newWorkInProgress;
20095 } // Delete the old fiber and place the new one.
20096 // Since the old fiber is disconnected, we have to schedule it manually.
20097
20098
20099 var last = returnFiber.lastEffect;
20100
20101 if (last !== null) {
20102 last.nextEffect = current$$1;
20103 returnFiber.lastEffect = current$$1;
20104 } else {
20105 returnFiber.firstEffect = returnFiber.lastEffect = current$$1;
20106 }
20107
20108 current$$1.nextEffect = null;
20109 current$$1.effectTag = Deletion;
20110 newWorkInProgress.effectTag |= Placement; // Restart work from the new fiber.
20111
20112 return newWorkInProgress;
20113 }
20114}
20115
20116function beginWork$1(current$$1, workInProgress, renderExpirationTime) {
20117 var updateExpirationTime = workInProgress.expirationTime;
20118
20119 {
20120 if (workInProgress._debugNeedsRemount && current$$1 !== null) {
20121 // This will restart the begin phase with a new fiber.
20122 return remountFiber(current$$1, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.expirationTime));
20123 }
20124 }
20125
20126 if (current$$1 !== null) {
20127 var oldProps = current$$1.memoizedProps;
20128 var newProps = workInProgress.pendingProps;
20129
20130 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
20131 workInProgress.type !== current$$1.type)) {
20132 // If props or context changed, mark the fiber as having performed work.
20133 // This may be unset if the props are determined to be equal later (memo).
20134 didReceiveUpdate = true;
20135 } else if (updateExpirationTime < renderExpirationTime) {
20136 didReceiveUpdate = false; // This fiber does not have any pending work. Bailout without entering
20137 // the begin phase. There's still some bookkeeping we that needs to be done
20138 // in this optimized path, mostly pushing stuff onto the stack.
20139
20140 switch (workInProgress.tag) {
20141 case HostRoot:
20142 pushHostRootContext(workInProgress);
20143 resetHydrationState();
20144 break;
20145
20146 case HostComponent:
20147 pushHostContext(workInProgress);
20148
20149 if (workInProgress.mode & ConcurrentMode && renderExpirationTime !== Never && shouldDeprioritizeSubtree(workInProgress.type, newProps)) {
20150 if (enableSchedulerTracing) {
20151 markSpawnedWork(Never);
20152 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
20153
20154
20155 workInProgress.expirationTime = workInProgress.childExpirationTime = Never;
20156 return null;
20157 }
20158
20159 break;
20160
20161 case ClassComponent:
20162 {
20163 var Component = workInProgress.type;
20164
20165 if (isContextProvider(Component)) {
20166 pushContextProvider(workInProgress);
20167 }
20168
20169 break;
20170 }
20171
20172 case HostPortal:
20173 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
20174 break;
20175
20176 case ContextProvider:
20177 {
20178 var newValue = workInProgress.memoizedProps.value;
20179 pushProvider(workInProgress, newValue);
20180 break;
20181 }
20182
20183 case Profiler:
20184 if (enableProfilerTimer) {
20185 // Profiler should only call onRender when one of its descendants actually rendered.
20186 var hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
20187
20188 if (hasChildWork) {
20189 workInProgress.effectTag |= Update;
20190 }
20191 }
20192
20193 break;
20194
20195 case SuspenseComponent:
20196 {
20197 var state = workInProgress.memoizedState;
20198
20199 if (state !== null) {
20200 if (enableSuspenseServerRenderer) {
20201 if (state.dehydrated !== null) {
20202 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has
20203 // been unsuspended it has committed as a resolved Suspense component.
20204 // If it needs to be retried, it should have work scheduled on it.
20205
20206 workInProgress.effectTag |= DidCapture;
20207 break;
20208 }
20209 } // If this boundary is currently timed out, we need to decide
20210 // whether to retry the primary children, or to skip over it and
20211 // go straight to the fallback. Check the priority of the primary
20212 // child fragment.
20213
20214
20215 var primaryChildFragment = workInProgress.child;
20216 var primaryChildExpirationTime = primaryChildFragment.childExpirationTime;
20217
20218 if (primaryChildExpirationTime !== NoWork && primaryChildExpirationTime >= renderExpirationTime) {
20219 // The primary children have pending work. Use the normal path
20220 // to attempt to render the primary children again.
20221 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
20222 } else {
20223 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
20224 // priority. Bailout.
20225
20226 var child = bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
20227
20228 if (child !== null) {
20229 // The fallback children have pending work. Skip over the
20230 // primary children and work on the fallback.
20231 return child.sibling;
20232 } else {
20233 return null;
20234 }
20235 }
20236 } else {
20237 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
20238 }
20239
20240 break;
20241 }
20242
20243 case SuspenseListComponent:
20244 {
20245 var didSuspendBefore = (current$$1.effectTag & DidCapture) !== NoEffect;
20246
20247 var _hasChildWork = workInProgress.childExpirationTime >= renderExpirationTime;
20248
20249 if (didSuspendBefore) {
20250 if (_hasChildWork) {
20251 // If something was in fallback state last time, and we have all the
20252 // same children then we're still in progressive loading state.
20253 // Something might get unblocked by state updates or retries in the
20254 // tree which will affect the tail. So we need to use the normal
20255 // path to compute the correct tail.
20256 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
20257 } // If none of the children had any work, that means that none of
20258 // them got retried so they'll still be blocked in the same way
20259 // as before. We can fast bail out.
20260
20261
20262 workInProgress.effectTag |= DidCapture;
20263 } // If nothing suspended before and we're rendering the same children,
20264 // then the tail doesn't matter. Anything new that suspends will work
20265 // in the "together" mode, so we can continue from the state we had.
20266
20267
20268 var renderState = workInProgress.memoizedState;
20269
20270 if (renderState !== null) {
20271 // Reset to the "together" mode in case we've started a different
20272 // update in the past but didn't complete it.
20273 renderState.rendering = null;
20274 renderState.tail = null;
20275 }
20276
20277 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
20278
20279 if (_hasChildWork) {
20280 break;
20281 } else {
20282 // If none of the children had any work, that means that none of
20283 // them got retried so they'll still be blocked in the same way
20284 // as before. We can fast bail out.
20285 return null;
20286 }
20287 }
20288 }
20289
20290 return bailoutOnAlreadyFinishedWork(current$$1, workInProgress, renderExpirationTime);
20291 } else {
20292 // An update was scheduled on this fiber, but there are no new props
20293 // nor legacy context. Set this to false. If an update queue or context
20294 // consumer produces a changed value, it will set this to true. Otherwise,
20295 // the component will assume the children have not changed and bail out.
20296 didReceiveUpdate = false;
20297 }
20298 } else {
20299 didReceiveUpdate = false;
20300 } // Before entering the begin phase, clear the expiration time.
20301
20302
20303 workInProgress.expirationTime = NoWork;
20304
20305 switch (workInProgress.tag) {
20306 case IndeterminateComponent:
20307 {
20308 return mountIndeterminateComponent(current$$1, workInProgress, workInProgress.type, renderExpirationTime);
20309 }
20310
20311 case LazyComponent:
20312 {
20313 var elementType = workInProgress.elementType;
20314 return mountLazyComponent(current$$1, workInProgress, elementType, updateExpirationTime, renderExpirationTime);
20315 }
20316
20317 case FunctionComponent:
20318 {
20319 var _Component = workInProgress.type;
20320 var unresolvedProps = workInProgress.pendingProps;
20321 var resolvedProps = workInProgress.elementType === _Component ? unresolvedProps : resolveDefaultProps(_Component, unresolvedProps);
20322 return updateFunctionComponent(current$$1, workInProgress, _Component, resolvedProps, renderExpirationTime);
20323 }
20324
20325 case ClassComponent:
20326 {
20327 var _Component2 = workInProgress.type;
20328 var _unresolvedProps = workInProgress.pendingProps;
20329
20330 var _resolvedProps = workInProgress.elementType === _Component2 ? _unresolvedProps : resolveDefaultProps(_Component2, _unresolvedProps);
20331
20332 return updateClassComponent(current$$1, workInProgress, _Component2, _resolvedProps, renderExpirationTime);
20333 }
20334
20335 case HostRoot:
20336 return updateHostRoot(current$$1, workInProgress, renderExpirationTime);
20337
20338 case HostComponent:
20339 return updateHostComponent(current$$1, workInProgress, renderExpirationTime);
20340
20341 case HostText:
20342 return updateHostText(current$$1, workInProgress);
20343
20344 case SuspenseComponent:
20345 return updateSuspenseComponent(current$$1, workInProgress, renderExpirationTime);
20346
20347 case HostPortal:
20348 return updatePortalComponent(current$$1, workInProgress, renderExpirationTime);
20349
20350 case ForwardRef:
20351 {
20352 var type = workInProgress.type;
20353 var _unresolvedProps2 = workInProgress.pendingProps;
20354
20355 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
20356
20357 return updateForwardRef(current$$1, workInProgress, type, _resolvedProps2, renderExpirationTime);
20358 }
20359
20360 case Fragment:
20361 return updateFragment(current$$1, workInProgress, renderExpirationTime);
20362
20363 case Mode:
20364 return updateMode(current$$1, workInProgress, renderExpirationTime);
20365
20366 case Profiler:
20367 return updateProfiler(current$$1, workInProgress, renderExpirationTime);
20368
20369 case ContextProvider:
20370 return updateContextProvider(current$$1, workInProgress, renderExpirationTime);
20371
20372 case ContextConsumer:
20373 return updateContextConsumer(current$$1, workInProgress, renderExpirationTime);
20374
20375 case MemoComponent:
20376 {
20377 var _type2 = workInProgress.type;
20378 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
20379
20380 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
20381
20382 {
20383 if (workInProgress.type !== workInProgress.elementType) {
20384 var outerPropTypes = _type2.propTypes;
20385
20386 if (outerPropTypes) {
20387 checkPropTypes_1(outerPropTypes, _resolvedProps3, // Resolved for outer only
20388 'prop', getComponentName(_type2), getCurrentFiberStackInDev);
20389 }
20390 }
20391 }
20392
20393 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
20394 return updateMemoComponent(current$$1, workInProgress, _type2, _resolvedProps3, updateExpirationTime, renderExpirationTime);
20395 }
20396
20397 case SimpleMemoComponent:
20398 {
20399 return updateSimpleMemoComponent(current$$1, workInProgress, workInProgress.type, workInProgress.pendingProps, updateExpirationTime, renderExpirationTime);
20400 }
20401
20402 case IncompleteClassComponent:
20403 {
20404 var _Component3 = workInProgress.type;
20405 var _unresolvedProps4 = workInProgress.pendingProps;
20406
20407 var _resolvedProps4 = workInProgress.elementType === _Component3 ? _unresolvedProps4 : resolveDefaultProps(_Component3, _unresolvedProps4);
20408
20409 return mountIncompleteClassComponent(current$$1, workInProgress, _Component3, _resolvedProps4, renderExpirationTime);
20410 }
20411
20412 case SuspenseListComponent:
20413 {
20414 return updateSuspenseListComponent(current$$1, workInProgress, renderExpirationTime);
20415 }
20416
20417 case FundamentalComponent:
20418 {
20419 if (enableFundamentalAPI) {
20420 return updateFundamentalComponent$1(current$$1, workInProgress, renderExpirationTime);
20421 }
20422
20423 break;
20424 }
20425
20426 case ScopeComponent:
20427 {
20428 if (enableScopeAPI) {
20429 return updateScopeComponent(current$$1, workInProgress, renderExpirationTime);
20430 }
20431
20432 break;
20433 }
20434 }
20435
20436 {
20437 {
20438 throw Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue.");
20439 }
20440 }
20441}
20442
20443function createFundamentalStateInstance(currentFiber, props, impl, state) {
20444 return {
20445 currentFiber: currentFiber,
20446 impl: impl,
20447 instance: null,
20448 prevProps: null,
20449 props: props,
20450 state: state
20451 };
20452}
20453
20454function isFiberSuspenseAndTimedOut(fiber) {
20455 return fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
20456}
20457
20458function getSuspenseFallbackChild(fiber) {
20459 return fiber.child.sibling.child;
20460}
20461
20462var emptyObject$1 = {};
20463
20464function collectScopedNodes(node, fn, scopedNodes) {
20465 if (enableScopeAPI) {
20466 if (node.tag === HostComponent) {
20467 var _type = node.type,
20468 memoizedProps = node.memoizedProps,
20469 stateNode = node.stateNode;
20470
20471 var _instance = getPublicInstance(stateNode);
20472
20473 if (_instance !== null && fn(_type, memoizedProps || emptyObject$1, _instance) === true) {
20474 scopedNodes.push(_instance);
20475 }
20476 }
20477
20478 var child = node.child;
20479
20480 if (isFiberSuspenseAndTimedOut(node)) {
20481 child = getSuspenseFallbackChild(node);
20482 }
20483
20484 if (child !== null) {
20485 collectScopedNodesFromChildren(child, fn, scopedNodes);
20486 }
20487 }
20488}
20489
20490function collectFirstScopedNode(node, fn) {
20491 if (enableScopeAPI) {
20492 if (node.tag === HostComponent) {
20493 var _type2 = node.type,
20494 memoizedProps = node.memoizedProps,
20495 stateNode = node.stateNode;
20496
20497 var _instance2 = getPublicInstance(stateNode);
20498
20499 if (_instance2 !== null && fn(_type2, memoizedProps, _instance2) === true) {
20500 return _instance2;
20501 }
20502 }
20503
20504 var child = node.child;
20505
20506 if (isFiberSuspenseAndTimedOut(node)) {
20507 child = getSuspenseFallbackChild(node);
20508 }
20509
20510 if (child !== null) {
20511 return collectFirstScopedNodeFromChildren(child, fn);
20512 }
20513 }
20514
20515 return null;
20516}
20517
20518function collectScopedNodesFromChildren(startingChild, fn, scopedNodes) {
20519 var child = startingChild;
20520
20521 while (child !== null) {
20522 collectScopedNodes(child, fn, scopedNodes);
20523 child = child.sibling;
20524 }
20525}
20526
20527function collectFirstScopedNodeFromChildren(startingChild, fn) {
20528 var child = startingChild;
20529
20530 while (child !== null) {
20531 var scopedNode = collectFirstScopedNode(child, fn);
20532
20533 if (scopedNode !== null) {
20534 return scopedNode;
20535 }
20536
20537 child = child.sibling;
20538 }
20539
20540 return null;
20541}
20542
20543function collectNearestScopeMethods(node, scope, childrenScopes) {
20544 if (isValidScopeNode(node, scope)) {
20545 childrenScopes.push(node.stateNode.methods);
20546 } else {
20547 var child = node.child;
20548
20549 if (isFiberSuspenseAndTimedOut(node)) {
20550 child = getSuspenseFallbackChild(node);
20551 }
20552
20553 if (child !== null) {
20554 collectNearestChildScopeMethods(child, scope, childrenScopes);
20555 }
20556 }
20557}
20558
20559function collectNearestChildScopeMethods(startingChild, scope, childrenScopes) {
20560 var child = startingChild;
20561
20562 while (child !== null) {
20563 collectNearestScopeMethods(child, scope, childrenScopes);
20564 child = child.sibling;
20565 }
20566}
20567
20568function isValidScopeNode(node, scope) {
20569 return node.tag === ScopeComponent && node.type === scope && node.stateNode !== null;
20570}
20571
20572function createScopeMethods(scope, instance) {
20573 return {
20574 getChildren: function () {
20575 var currentFiber = instance.fiber;
20576 var child = currentFiber.child;
20577 var childrenScopes = [];
20578
20579 if (child !== null) {
20580 collectNearestChildScopeMethods(child, scope, childrenScopes);
20581 }
20582
20583 return childrenScopes.length === 0 ? null : childrenScopes;
20584 },
20585 getChildrenFromRoot: function () {
20586 var currentFiber = instance.fiber;
20587 var node = currentFiber;
20588
20589 while (node !== null) {
20590 var parent = node.return;
20591
20592 if (parent === null) {
20593 break;
20594 }
20595
20596 node = parent;
20597
20598 if (node.tag === ScopeComponent && node.type === scope) {
20599 break;
20600 }
20601 }
20602
20603 var childrenScopes = [];
20604 collectNearestChildScopeMethods(node.child, scope, childrenScopes);
20605 return childrenScopes.length === 0 ? null : childrenScopes;
20606 },
20607 getParent: function () {
20608 var node = instance.fiber.return;
20609
20610 while (node !== null) {
20611 if (node.tag === ScopeComponent && node.type === scope) {
20612 return node.stateNode.methods;
20613 }
20614
20615 node = node.return;
20616 }
20617
20618 return null;
20619 },
20620 getProps: function () {
20621 var currentFiber = instance.fiber;
20622 return currentFiber.memoizedProps;
20623 },
20624 queryAllNodes: function (fn) {
20625 var currentFiber = instance.fiber;
20626 var child = currentFiber.child;
20627 var scopedNodes = [];
20628
20629 if (child !== null) {
20630 collectScopedNodesFromChildren(child, fn, scopedNodes);
20631 }
20632
20633 return scopedNodes.length === 0 ? null : scopedNodes;
20634 },
20635 queryFirstNode: function (fn) {
20636 var currentFiber = instance.fiber;
20637 var child = currentFiber.child;
20638
20639 if (child !== null) {
20640 return collectFirstScopedNodeFromChildren(child, fn);
20641 }
20642
20643 return null;
20644 },
20645 containsNode: function (node) {
20646 var fiber = getInstanceFromNode$2(node);
20647
20648 while (fiber !== null) {
20649 if (fiber.tag === ScopeComponent && fiber.type === scope && fiber.stateNode === instance) {
20650 return true;
20651 }
20652
20653 fiber = fiber.return;
20654 }
20655
20656 return false;
20657 }
20658 };
20659}
20660
20661function markUpdate(workInProgress) {
20662 // Tag the fiber with an update effect. This turns a Placement into
20663 // a PlacementAndUpdate.
20664 workInProgress.effectTag |= Update;
20665}
20666
20667function markRef$1(workInProgress) {
20668 workInProgress.effectTag |= Ref;
20669}
20670
20671var appendAllChildren;
20672var updateHostContainer;
20673var updateHostComponent$1;
20674var updateHostText$1;
20675
20676if (supportsMutation) {
20677 // Mutation mode
20678 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
20679 // We only have the top Fiber that was created but we need recurse down its
20680 // children to find all the terminal nodes.
20681 var node = workInProgress.child;
20682
20683 while (node !== null) {
20684 if (node.tag === HostComponent || node.tag === HostText) {
20685 appendInitialChild(parent, node.stateNode);
20686 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
20687 appendInitialChild(parent, node.stateNode.instance);
20688 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
20689 // down its children. Instead, we'll get insertions from each child in
20690 // the portal directly.
20691 } else if (node.child !== null) {
20692 node.child.return = node;
20693 node = node.child;
20694 continue;
20695 }
20696
20697 if (node === workInProgress) {
20698 return;
20699 }
20700
20701 while (node.sibling === null) {
20702 if (node.return === null || node.return === workInProgress) {
20703 return;
20704 }
20705
20706 node = node.return;
20707 }
20708
20709 node.sibling.return = node.return;
20710 node = node.sibling;
20711 }
20712 };
20713
20714 updateHostContainer = function (workInProgress) {// Noop
20715 };
20716
20717 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
20718 // If we have an alternate, that means this is an update and we need to
20719 // schedule a side-effect to do the updates.
20720 var oldProps = current.memoizedProps;
20721
20722 if (oldProps === newProps) {
20723 // In mutation mode, this is sufficient for a bailout because
20724 // we won't touch this node even if children changed.
20725 return;
20726 } // If we get updated because one of our children updated, we don't
20727 // have newProps so we'll have to reuse them.
20728 // TODO: Split the update API as separate for the props vs. children.
20729 // Even better would be if children weren't special cased at all tho.
20730
20731
20732 var instance = workInProgress.stateNode;
20733 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
20734 // component is hitting the resume path. Figure out why. Possibly
20735 // related to `hidden`.
20736
20737 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
20738
20739 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
20740 // is a new ref we mark this as an update. All the work is done in commitWork.
20741
20742 if (updatePayload) {
20743 markUpdate(workInProgress);
20744 }
20745 };
20746
20747 updateHostText$1 = function (current, workInProgress, oldText, newText) {
20748 // If the text differs, mark it as an update. All the work in done in commitWork.
20749 if (oldText !== newText) {
20750 markUpdate(workInProgress);
20751 }
20752 };
20753} else if (supportsPersistence) {
20754 // Persistent host tree mode
20755 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
20756 // We only have the top Fiber that was created but we need recurse down its
20757 // children to find all the terminal nodes.
20758 var node = workInProgress.child;
20759
20760 while (node !== null) {
20761 // eslint-disable-next-line no-labels
20762 branches: if (node.tag === HostComponent) {
20763 var instance = node.stateNode;
20764
20765 if (needsVisibilityToggle && isHidden) {
20766 // This child is inside a timed out tree. Hide it.
20767 var props = node.memoizedProps;
20768 var type = node.type;
20769 instance = cloneHiddenInstance(instance, type, props, node);
20770 }
20771
20772 appendInitialChild(parent, instance);
20773 } else if (node.tag === HostText) {
20774 var _instance = node.stateNode;
20775
20776 if (needsVisibilityToggle && isHidden) {
20777 // This child is inside a timed out tree. Hide it.
20778 var text = node.memoizedProps;
20779 _instance = cloneHiddenTextInstance(_instance, text, node);
20780 }
20781
20782 appendInitialChild(parent, _instance);
20783 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
20784 var _instance2 = node.stateNode.instance;
20785
20786 if (needsVisibilityToggle && isHidden) {
20787 // This child is inside a timed out tree. Hide it.
20788 var _props = node.memoizedProps;
20789 var _type = node.type;
20790 _instance2 = cloneHiddenInstance(_instance2, _type, _props, node);
20791 }
20792
20793 appendInitialChild(parent, _instance2);
20794 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
20795 // down its children. Instead, we'll get insertions from each child in
20796 // the portal directly.
20797 } else if (node.tag === SuspenseComponent) {
20798 if ((node.effectTag & Update) !== NoEffect) {
20799 // Need to toggle the visibility of the primary children.
20800 var newIsHidden = node.memoizedState !== null;
20801
20802 if (newIsHidden) {
20803 var primaryChildParent = node.child;
20804
20805 if (primaryChildParent !== null) {
20806 if (primaryChildParent.child !== null) {
20807 primaryChildParent.child.return = primaryChildParent;
20808 appendAllChildren(parent, primaryChildParent, true, newIsHidden);
20809 }
20810
20811 var fallbackChildParent = primaryChildParent.sibling;
20812
20813 if (fallbackChildParent !== null) {
20814 fallbackChildParent.return = node;
20815 node = fallbackChildParent;
20816 continue;
20817 }
20818 }
20819 }
20820 }
20821
20822 if (node.child !== null) {
20823 // Continue traversing like normal
20824 node.child.return = node;
20825 node = node.child;
20826 continue;
20827 }
20828 } else if (node.child !== null) {
20829 node.child.return = node;
20830 node = node.child;
20831 continue;
20832 } // $FlowFixMe This is correct but Flow is confused by the labeled break.
20833
20834
20835 node = node;
20836
20837 if (node === workInProgress) {
20838 return;
20839 }
20840
20841 while (node.sibling === null) {
20842 if (node.return === null || node.return === workInProgress) {
20843 return;
20844 }
20845
20846 node = node.return;
20847 }
20848
20849 node.sibling.return = node.return;
20850 node = node.sibling;
20851 }
20852 }; // An unfortunate fork of appendAllChildren because we have two different parent types.
20853
20854
20855 var appendAllChildrenToContainer = function (containerChildSet, workInProgress, needsVisibilityToggle, isHidden) {
20856 // We only have the top Fiber that was created but we need recurse down its
20857 // children to find all the terminal nodes.
20858 var node = workInProgress.child;
20859
20860 while (node !== null) {
20861 // eslint-disable-next-line no-labels
20862 branches: if (node.tag === HostComponent) {
20863 var instance = node.stateNode;
20864
20865 if (needsVisibilityToggle && isHidden) {
20866 // This child is inside a timed out tree. Hide it.
20867 var props = node.memoizedProps;
20868 var type = node.type;
20869 instance = cloneHiddenInstance(instance, type, props, node);
20870 }
20871
20872 appendChildToContainerChildSet(containerChildSet, instance);
20873 } else if (node.tag === HostText) {
20874 var _instance3 = node.stateNode;
20875
20876 if (needsVisibilityToggle && isHidden) {
20877 // This child is inside a timed out tree. Hide it.
20878 var text = node.memoizedProps;
20879 _instance3 = cloneHiddenTextInstance(_instance3, text, node);
20880 }
20881
20882 appendChildToContainerChildSet(containerChildSet, _instance3);
20883 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
20884 var _instance4 = node.stateNode.instance;
20885
20886 if (needsVisibilityToggle && isHidden) {
20887 // This child is inside a timed out tree. Hide it.
20888 var _props2 = node.memoizedProps;
20889 var _type2 = node.type;
20890 _instance4 = cloneHiddenInstance(_instance4, _type2, _props2, node);
20891 }
20892
20893 appendChildToContainerChildSet(containerChildSet, _instance4);
20894 } else if (node.tag === HostPortal) {// If we have a portal child, then we don't want to traverse
20895 // down its children. Instead, we'll get insertions from each child in
20896 // the portal directly.
20897 } else if (node.tag === SuspenseComponent) {
20898 if ((node.effectTag & Update) !== NoEffect) {
20899 // Need to toggle the visibility of the primary children.
20900 var newIsHidden = node.memoizedState !== null;
20901
20902 if (newIsHidden) {
20903 var primaryChildParent = node.child;
20904
20905 if (primaryChildParent !== null) {
20906 if (primaryChildParent.child !== null) {
20907 primaryChildParent.child.return = primaryChildParent;
20908 appendAllChildrenToContainer(containerChildSet, primaryChildParent, true, newIsHidden);
20909 }
20910
20911 var fallbackChildParent = primaryChildParent.sibling;
20912
20913 if (fallbackChildParent !== null) {
20914 fallbackChildParent.return = node;
20915 node = fallbackChildParent;
20916 continue;
20917 }
20918 }
20919 }
20920 }
20921
20922 if (node.child !== null) {
20923 // Continue traversing like normal
20924 node.child.return = node;
20925 node = node.child;
20926 continue;
20927 }
20928 } else if (node.child !== null) {
20929 node.child.return = node;
20930 node = node.child;
20931 continue;
20932 } // $FlowFixMe This is correct but Flow is confused by the labeled break.
20933
20934
20935 node = node;
20936
20937 if (node === workInProgress) {
20938 return;
20939 }
20940
20941 while (node.sibling === null) {
20942 if (node.return === null || node.return === workInProgress) {
20943 return;
20944 }
20945
20946 node = node.return;
20947 }
20948
20949 node.sibling.return = node.return;
20950 node = node.sibling;
20951 }
20952 };
20953
20954 updateHostContainer = function (workInProgress) {
20955 var portalOrRoot = workInProgress.stateNode;
20956 var childrenUnchanged = workInProgress.firstEffect === null;
20957
20958 if (childrenUnchanged) {// No changes, just reuse the existing instance.
20959 } else {
20960 var container = portalOrRoot.containerInfo;
20961 var newChildSet = createContainerChildSet(container); // If children might have changed, we have to add them all to the set.
20962
20963 appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
20964 portalOrRoot.pendingChildren = newChildSet; // Schedule an update on the container to swap out the container.
20965
20966 markUpdate(workInProgress);
20967 finalizeContainerChildren(container, newChildSet);
20968 }
20969 };
20970
20971 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
20972 var currentInstance = current.stateNode;
20973 var oldProps = current.memoizedProps; // If there are no effects associated with this node, then none of our children had any updates.
20974 // This guarantees that we can reuse all of them.
20975
20976 var childrenUnchanged = workInProgress.firstEffect === null;
20977
20978 if (childrenUnchanged && oldProps === newProps) {
20979 // No changes, just reuse the existing instance.
20980 // Note that this might release a previous clone.
20981 workInProgress.stateNode = currentInstance;
20982 return;
20983 }
20984
20985 var recyclableInstance = workInProgress.stateNode;
20986 var currentHostContext = getHostContext();
20987 var updatePayload = null;
20988
20989 if (oldProps !== newProps) {
20990 updatePayload = prepareUpdate(recyclableInstance, type, oldProps, newProps, rootContainerInstance, currentHostContext);
20991 }
20992
20993 if (childrenUnchanged && updatePayload === null) {
20994 // No changes, just reuse the existing instance.
20995 // Note that this might release a previous clone.
20996 workInProgress.stateNode = currentInstance;
20997 return;
20998 }
20999
21000 var newInstance = cloneInstance(currentInstance, updatePayload, type, oldProps, newProps, workInProgress, childrenUnchanged, recyclableInstance);
21001
21002 if (finalizeInitialChildren(newInstance, type, newProps, rootContainerInstance, currentHostContext)) {
21003 markUpdate(workInProgress);
21004 }
21005
21006 workInProgress.stateNode = newInstance;
21007
21008 if (childrenUnchanged) {
21009 // If there are no other effects in this tree, we need to flag this node as having one.
21010 // Even though we're not going to use it for anything.
21011 // Otherwise parents won't know that there are new children to propagate upwards.
21012 markUpdate(workInProgress);
21013 } else {
21014 // If children might have changed, we have to add them all to the set.
21015 appendAllChildren(newInstance, workInProgress, false, false);
21016 }
21017 };
21018
21019 updateHostText$1 = function (current, workInProgress, oldText, newText) {
21020 if (oldText !== newText) {
21021 // If the text content differs, we'll create a new text instance for it.
21022 var rootContainerInstance = getRootHostContainer();
21023 var currentHostContext = getHostContext();
21024 workInProgress.stateNode = createTextInstance(newText, rootContainerInstance, currentHostContext, workInProgress); // We'll have to mark it as having an effect, even though we won't use the effect for anything.
21025 // This lets the parents know that at least one of their children has changed.
21026
21027 markUpdate(workInProgress);
21028 }
21029 };
21030} else {
21031 // No host operations
21032 updateHostContainer = function (workInProgress) {// Noop
21033 };
21034
21035 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {// Noop
21036 };
21037
21038 updateHostText$1 = function (current, workInProgress, oldText, newText) {// Noop
21039 };
21040}
21041
21042function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
21043 switch (renderState.tailMode) {
21044 case 'hidden':
21045 {
21046 // Any insertions at the end of the tail list after this point
21047 // should be invisible. If there are already mounted boundaries
21048 // anything before them are not considered for collapsing.
21049 // Therefore we need to go through the whole tail to find if
21050 // there are any.
21051 var tailNode = renderState.tail;
21052 var lastTailNode = null;
21053
21054 while (tailNode !== null) {
21055 if (tailNode.alternate !== null) {
21056 lastTailNode = tailNode;
21057 }
21058
21059 tailNode = tailNode.sibling;
21060 } // Next we're simply going to delete all insertions after the
21061 // last rendered item.
21062
21063
21064 if (lastTailNode === null) {
21065 // All remaining items in the tail are insertions.
21066 renderState.tail = null;
21067 } else {
21068 // Detach the insertion after the last node that was already
21069 // inserted.
21070 lastTailNode.sibling = null;
21071 }
21072
21073 break;
21074 }
21075
21076 case 'collapsed':
21077 {
21078 // Any insertions at the end of the tail list after this point
21079 // should be invisible. If there are already mounted boundaries
21080 // anything before them are not considered for collapsing.
21081 // Therefore we need to go through the whole tail to find if
21082 // there are any.
21083 var _tailNode = renderState.tail;
21084 var _lastTailNode = null;
21085
21086 while (_tailNode !== null) {
21087 if (_tailNode.alternate !== null) {
21088 _lastTailNode = _tailNode;
21089 }
21090
21091 _tailNode = _tailNode.sibling;
21092 } // Next we're simply going to delete all insertions after the
21093 // last rendered item.
21094
21095
21096 if (_lastTailNode === null) {
21097 // All remaining items in the tail are insertions.
21098 if (!hasRenderedATailFallback && renderState.tail !== null) {
21099 // We suspended during the head. We want to show at least one
21100 // row at the tail. So we'll keep on and cut off the rest.
21101 renderState.tail.sibling = null;
21102 } else {
21103 renderState.tail = null;
21104 }
21105 } else {
21106 // Detach the insertion after the last node that was already
21107 // inserted.
21108 _lastTailNode.sibling = null;
21109 }
21110
21111 break;
21112 }
21113 }
21114}
21115
21116function completeWork(current, workInProgress, renderExpirationTime) {
21117 var newProps = workInProgress.pendingProps;
21118
21119 switch (workInProgress.tag) {
21120 case IndeterminateComponent:
21121 break;
21122
21123 case LazyComponent:
21124 break;
21125
21126 case SimpleMemoComponent:
21127 case FunctionComponent:
21128 break;
21129
21130 case ClassComponent:
21131 {
21132 var Component = workInProgress.type;
21133
21134 if (isContextProvider(Component)) {
21135 popContext(workInProgress);
21136 }
21137
21138 break;
21139 }
21140
21141 case HostRoot:
21142 {
21143 popHostContainer(workInProgress);
21144 popTopLevelContextObject(workInProgress);
21145 var fiberRoot = workInProgress.stateNode;
21146
21147 if (fiberRoot.pendingContext) {
21148 fiberRoot.context = fiberRoot.pendingContext;
21149 fiberRoot.pendingContext = null;
21150 }
21151
21152 if (current === null || current.child === null) {
21153 // If we hydrated, pop so that we can delete any remaining children
21154 // that weren't hydrated.
21155 var wasHydrated = popHydrationState(workInProgress);
21156
21157 if (wasHydrated) {
21158 // If we hydrated, then we'll need to schedule an update for
21159 // the commit side-effects on the root.
21160 markUpdate(workInProgress);
21161 }
21162 }
21163
21164 updateHostContainer(workInProgress);
21165 break;
21166 }
21167
21168 case HostComponent:
21169 {
21170 popHostContext(workInProgress);
21171 var rootContainerInstance = getRootHostContainer();
21172 var type = workInProgress.type;
21173
21174 if (current !== null && workInProgress.stateNode != null) {
21175 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
21176
21177 if (enableFlareAPI) {
21178 var prevListeners = current.memoizedProps.listeners;
21179 var nextListeners = newProps.listeners;
21180
21181 if (prevListeners !== nextListeners) {
21182 markUpdate(workInProgress);
21183 }
21184 }
21185
21186 if (current.ref !== workInProgress.ref) {
21187 markRef$1(workInProgress);
21188 }
21189 } else {
21190 if (!newProps) {
21191 if (!(workInProgress.stateNode !== null)) {
21192 {
21193 throw Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.");
21194 }
21195 } // This can happen when we abort work.
21196
21197
21198 break;
21199 }
21200
21201 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
21202 // "stack" as the parent. Then append children as we go in beginWork
21203 // or completeWork depending on we want to add then top->down or
21204 // bottom->up. Top->down is faster in IE11.
21205
21206 var _wasHydrated = popHydrationState(workInProgress);
21207
21208 if (_wasHydrated) {
21209 // TODO: Move this and createInstance step into the beginPhase
21210 // to consolidate.
21211 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
21212 // If changes to the hydrated node needs to be applied at the
21213 // commit-phase we mark this as such.
21214 markUpdate(workInProgress);
21215 }
21216
21217 if (enableFlareAPI) {
21218 var listeners = newProps.listeners;
21219
21220 if (listeners != null) {
21221 updateEventListeners(listeners, workInProgress, rootContainerInstance);
21222 }
21223 }
21224 } else {
21225 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
21226 appendAllChildren(instance, workInProgress, false, false); // This needs to be set before we mount Flare event listeners
21227
21228 workInProgress.stateNode = instance;
21229
21230 if (enableFlareAPI) {
21231 var _listeners = newProps.listeners;
21232
21233 if (_listeners != null) {
21234 updateEventListeners(_listeners, workInProgress, rootContainerInstance);
21235 }
21236 } // Certain renderers require commit-time effects for initial mount.
21237 // (eg DOM renderer supports auto-focus for certain elements).
21238 // Make sure such renderers get scheduled for later work.
21239
21240
21241 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance, currentHostContext)) {
21242 markUpdate(workInProgress);
21243 }
21244 }
21245
21246 if (workInProgress.ref !== null) {
21247 // If there is a ref on a host node we need to schedule a callback
21248 markRef$1(workInProgress);
21249 }
21250 }
21251
21252 break;
21253 }
21254
21255 case HostText:
21256 {
21257 var newText = newProps;
21258
21259 if (current && workInProgress.stateNode != null) {
21260 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
21261 // to schedule a side-effect to do the updates.
21262
21263 updateHostText$1(current, workInProgress, oldText, newText);
21264 } else {
21265 if (typeof newText !== 'string') {
21266 if (!(workInProgress.stateNode !== null)) {
21267 {
21268 throw Error("We must have new props for new mounts. This error is likely caused by a bug in React. Please file an issue.");
21269 }
21270 } // This can happen when we abort work.
21271
21272 }
21273
21274 var _rootContainerInstance = getRootHostContainer();
21275
21276 var _currentHostContext = getHostContext();
21277
21278 var _wasHydrated2 = popHydrationState(workInProgress);
21279
21280 if (_wasHydrated2) {
21281 if (prepareToHydrateHostTextInstance(workInProgress)) {
21282 markUpdate(workInProgress);
21283 }
21284 } else {
21285 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
21286 }
21287 }
21288
21289 break;
21290 }
21291
21292 case ForwardRef:
21293 break;
21294
21295 case SuspenseComponent:
21296 {
21297 popSuspenseContext(workInProgress);
21298 var nextState = workInProgress.memoizedState;
21299
21300 if (enableSuspenseServerRenderer) {
21301 if (nextState !== null && nextState.dehydrated !== null) {
21302 if (current === null) {
21303 var _wasHydrated3 = popHydrationState(workInProgress);
21304
21305 if (!_wasHydrated3) {
21306 {
21307 throw Error("A dehydrated suspense component was completed without a hydrated node. This is probably a bug in React.");
21308 }
21309 }
21310
21311 prepareToHydrateHostSuspenseInstance(workInProgress);
21312
21313 if (enableSchedulerTracing) {
21314 markSpawnedWork(Never);
21315 }
21316
21317 return null;
21318 } else {
21319 // We should never have been in a hydration state if we didn't have a current.
21320 // However, in some of those paths, we might have reentered a hydration state
21321 // and then we might be inside a hydration state. In that case, we'll need to
21322 // exit out of it.
21323 resetHydrationState();
21324
21325 if ((workInProgress.effectTag & DidCapture) === NoEffect) {
21326 // This boundary did not suspend so it's now hydrated and unsuspended.
21327 workInProgress.memoizedState = null;
21328 } // If nothing suspended, we need to schedule an effect to mark this boundary
21329 // as having hydrated so events know that they're free be invoked.
21330 // It's also a signal to replay events and the suspense callback.
21331 // If something suspended, schedule an effect to attach retry listeners.
21332 // So we might as well always mark this.
21333
21334
21335 workInProgress.effectTag |= Update;
21336 return null;
21337 }
21338 }
21339 }
21340
21341 if ((workInProgress.effectTag & DidCapture) !== NoEffect) {
21342 // Something suspended. Re-render with the fallback children.
21343 workInProgress.expirationTime = renderExpirationTime; // Do not reset the effect list.
21344
21345 return workInProgress;
21346 }
21347
21348 var nextDidTimeout = nextState !== null;
21349 var prevDidTimeout = false;
21350
21351 if (current === null) {
21352 if (workInProgress.memoizedProps.fallback !== undefined) {
21353 popHydrationState(workInProgress);
21354 }
21355 } else {
21356 var prevState = current.memoizedState;
21357 prevDidTimeout = prevState !== null;
21358
21359 if (!nextDidTimeout && prevState !== null) {
21360 // We just switched from the fallback to the normal children.
21361 // Delete the fallback.
21362 // TODO: Would it be better to store the fallback fragment on
21363 // the stateNode during the begin phase?
21364 var currentFallbackChild = current.child.sibling;
21365
21366 if (currentFallbackChild !== null) {
21367 // Deletions go at the beginning of the return fiber's effect list
21368 var first = workInProgress.firstEffect;
21369
21370 if (first !== null) {
21371 workInProgress.firstEffect = currentFallbackChild;
21372 currentFallbackChild.nextEffect = first;
21373 } else {
21374 workInProgress.firstEffect = workInProgress.lastEffect = currentFallbackChild;
21375 currentFallbackChild.nextEffect = null;
21376 }
21377
21378 currentFallbackChild.effectTag = Deletion;
21379 }
21380 }
21381 }
21382
21383 if (nextDidTimeout && !prevDidTimeout) {
21384 // If this subtreee is running in blocking mode we can suspend,
21385 // otherwise we won't suspend.
21386 // TODO: This will still suspend a synchronous tree if anything
21387 // in the concurrent tree already suspended during this render.
21388 // This is a known bug.
21389 if ((workInProgress.mode & BlockingMode) !== NoMode) {
21390 // TODO: Move this back to throwException because this is too late
21391 // if this is a large tree which is common for initial loads. We
21392 // don't know if we should restart a render or not until we get
21393 // this marker, and this is too late.
21394 // If this render already had a ping or lower pri updates,
21395 // and this is the first time we know we're going to suspend we
21396 // should be able to immediately restart from within throwException.
21397 var hasInvisibleChildContext = current === null && workInProgress.memoizedProps.unstable_avoidThisFallback !== true;
21398
21399 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
21400 // If this was in an invisible tree or a new render, then showing
21401 // this boundary is ok.
21402 renderDidSuspend();
21403 } else {
21404 // Otherwise, we're going to have to hide content so we should
21405 // suspend for longer if possible.
21406 renderDidSuspendDelayIfPossible();
21407 }
21408 }
21409 }
21410
21411 if (supportsPersistence) {
21412 // TODO: Only schedule updates if not prevDidTimeout.
21413 if (nextDidTimeout) {
21414 // If this boundary just timed out, schedule an effect to attach a
21415 // retry listener to the proimse. This flag is also used to hide the
21416 // primary children.
21417 workInProgress.effectTag |= Update;
21418 }
21419 }
21420
21421 if (supportsMutation) {
21422 // TODO: Only schedule updates if these values are non equal, i.e. it changed.
21423 if (nextDidTimeout || prevDidTimeout) {
21424 // If this boundary just timed out, schedule an effect to attach a
21425 // retry listener to the proimse. This flag is also used to hide the
21426 // primary children. In mutation mode, we also need the flag to
21427 // *unhide* children that were previously hidden, so check if the
21428 // is currently timed out, too.
21429 workInProgress.effectTag |= Update;
21430 }
21431 }
21432
21433 if (enableSuspenseCallback && workInProgress.updateQueue !== null && workInProgress.memoizedProps.suspenseCallback != null) {
21434 // Always notify the callback
21435 workInProgress.effectTag |= Update;
21436 }
21437
21438 break;
21439 }
21440
21441 case Fragment:
21442 break;
21443
21444 case Mode:
21445 break;
21446
21447 case Profiler:
21448 break;
21449
21450 case HostPortal:
21451 popHostContainer(workInProgress);
21452 updateHostContainer(workInProgress);
21453 break;
21454
21455 case ContextProvider:
21456 // Pop provider fiber
21457 popProvider(workInProgress);
21458 break;
21459
21460 case ContextConsumer:
21461 break;
21462
21463 case MemoComponent:
21464 break;
21465
21466 case IncompleteClassComponent:
21467 {
21468 // Same as class component case. I put it down here so that the tags are
21469 // sequential to ensure this switch is compiled to a jump table.
21470 var _Component = workInProgress.type;
21471
21472 if (isContextProvider(_Component)) {
21473 popContext(workInProgress);
21474 }
21475
21476 break;
21477 }
21478
21479 case SuspenseListComponent:
21480 {
21481 popSuspenseContext(workInProgress);
21482 var renderState = workInProgress.memoizedState;
21483
21484 if (renderState === null) {
21485 // We're running in the default, "independent" mode. We don't do anything
21486 // in this mode.
21487 break;
21488 }
21489
21490 var didSuspendAlready = (workInProgress.effectTag & DidCapture) !== NoEffect;
21491 var renderedTail = renderState.rendering;
21492
21493 if (renderedTail === null) {
21494 // We just rendered the head.
21495 if (!didSuspendAlready) {
21496 // This is the first pass. We need to figure out if anything is still
21497 // suspended in the rendered set.
21498 // If new content unsuspended, but there's still some content that
21499 // didn't. Then we need to do a second pass that forces everything
21500 // to keep showing their fallbacks.
21501 // We might be suspended if something in this render pass suspended, or
21502 // something in the previous committed pass suspended. Otherwise,
21503 // there's no chance so we can skip the expensive call to
21504 // findFirstSuspended.
21505 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.effectTag & DidCapture) === NoEffect);
21506
21507 if (!cannotBeSuspended) {
21508 var row = workInProgress.child;
21509
21510 while (row !== null) {
21511 var suspended = findFirstSuspended(row);
21512
21513 if (suspended !== null) {
21514 didSuspendAlready = true;
21515 workInProgress.effectTag |= DidCapture;
21516 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
21517 // part of the second pass. In that case nothing will subscribe to
21518 // its thennables. Instead, we'll transfer its thennables to the
21519 // SuspenseList so that it can retry if they resolve.
21520 // There might be multiple of these in the list but since we're
21521 // going to wait for all of them anyway, it doesn't really matter
21522 // which ones gets to ping. In theory we could get clever and keep
21523 // track of how many dependencies remain but it gets tricky because
21524 // in the meantime, we can add/remove/change items and dependencies.
21525 // We might bail out of the loop before finding any but that
21526 // doesn't matter since that means that the other boundaries that
21527 // we did find already has their listeners attached.
21528
21529 var newThennables = suspended.updateQueue;
21530
21531 if (newThennables !== null) {
21532 workInProgress.updateQueue = newThennables;
21533 workInProgress.effectTag |= Update;
21534 } // Rerender the whole list, but this time, we'll force fallbacks
21535 // to stay in place.
21536 // Reset the effect list before doing the second pass since that's now invalid.
21537
21538
21539 if (renderState.lastEffect === null) {
21540 workInProgress.firstEffect = null;
21541 }
21542
21543 workInProgress.lastEffect = renderState.lastEffect; // Reset the child fibers to their original state.
21544
21545 resetChildFibers(workInProgress, renderExpirationTime); // Set up the Suspense Context to force suspense and immediately
21546 // rerender the children.
21547
21548 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback));
21549 return workInProgress.child;
21550 }
21551
21552 row = row.sibling;
21553 }
21554 }
21555 } else {
21556 cutOffTailIfNeeded(renderState, false);
21557 } // Next we're going to render the tail.
21558
21559 } else {
21560 // Append the rendered row to the child list.
21561 if (!didSuspendAlready) {
21562 var _suspended = findFirstSuspended(renderedTail);
21563
21564 if (_suspended !== null) {
21565 workInProgress.effectTag |= DidCapture;
21566 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
21567 // get lost if this row ends up dropped during a second pass.
21568
21569 var _newThennables = _suspended.updateQueue;
21570
21571 if (_newThennables !== null) {
21572 workInProgress.updateQueue = _newThennables;
21573 workInProgress.effectTag |= Update;
21574 }
21575
21576 cutOffTailIfNeeded(renderState, true); // This might have been modified.
21577
21578 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate) {
21579 // We need to delete the row we just rendered.
21580 // Reset the effect list to what it was before we rendered this
21581 // child. The nested children have already appended themselves.
21582 var lastEffect = workInProgress.lastEffect = renderState.lastEffect; // Remove any effects that were appended after this point.
21583
21584 if (lastEffect !== null) {
21585 lastEffect.nextEffect = null;
21586 } // We're done.
21587
21588
21589 return null;
21590 }
21591 } else if (now() > renderState.tailExpiration && renderExpirationTime > Never) {
21592 // We have now passed our CPU deadline and we'll just give up further
21593 // attempts to render the main content and only render fallbacks.
21594 // The assumption is that this is usually faster.
21595 workInProgress.effectTag |= DidCapture;
21596 didSuspendAlready = true;
21597 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
21598 // to get it started back up to attempt the next item. If we can show
21599 // them, then they really have the same priority as this render.
21600 // So we'll pick it back up the very next render pass once we've had
21601 // an opportunity to yield for paint.
21602
21603 var nextPriority = renderExpirationTime - 1;
21604 workInProgress.expirationTime = workInProgress.childExpirationTime = nextPriority;
21605
21606 if (enableSchedulerTracing) {
21607 markSpawnedWork(nextPriority);
21608 }
21609 }
21610 }
21611
21612 if (renderState.isBackwards) {
21613 // The effect list of the backwards tail will have been added
21614 // to the end. This breaks the guarantee that life-cycles fire in
21615 // sibling order but that isn't a strong guarantee promised by React.
21616 // Especially since these might also just pop in during future commits.
21617 // Append to the beginning of the list.
21618 renderedTail.sibling = workInProgress.child;
21619 workInProgress.child = renderedTail;
21620 } else {
21621 var previousSibling = renderState.last;
21622
21623 if (previousSibling !== null) {
21624 previousSibling.sibling = renderedTail;
21625 } else {
21626 workInProgress.child = renderedTail;
21627 }
21628
21629 renderState.last = renderedTail;
21630 }
21631 }
21632
21633 if (renderState.tail !== null) {
21634 // We still have tail rows to render.
21635 if (renderState.tailExpiration === 0) {
21636 // Heuristic for how long we're willing to spend rendering rows
21637 // until we just give up and show what we have so far.
21638 var TAIL_EXPIRATION_TIMEOUT_MS = 500;
21639 renderState.tailExpiration = now() + TAIL_EXPIRATION_TIMEOUT_MS;
21640 } // Pop a row.
21641
21642
21643 var next = renderState.tail;
21644 renderState.rendering = next;
21645 renderState.tail = next.sibling;
21646 renderState.lastEffect = workInProgress.lastEffect;
21647 next.sibling = null; // Restore the context.
21648 // TODO: We can probably just avoid popping it instead and only
21649 // setting it the first time we go from not suspended to suspended.
21650
21651 var suspenseContext = suspenseStackCursor.current;
21652
21653 if (didSuspendAlready) {
21654 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
21655 } else {
21656 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
21657 }
21658
21659 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
21660
21661 return next;
21662 }
21663
21664 break;
21665 }
21666
21667 case FundamentalComponent:
21668 {
21669 if (enableFundamentalAPI) {
21670 var fundamentalImpl = workInProgress.type.impl;
21671 var fundamentalInstance = workInProgress.stateNode;
21672
21673 if (fundamentalInstance === null) {
21674 var getInitialState = fundamentalImpl.getInitialState;
21675 var fundamentalState;
21676
21677 if (getInitialState !== undefined) {
21678 fundamentalState = getInitialState(newProps);
21679 }
21680
21681 fundamentalInstance = workInProgress.stateNode = createFundamentalStateInstance(workInProgress, newProps, fundamentalImpl, fundamentalState || {});
21682
21683 var _instance5 = getFundamentalComponentInstance(fundamentalInstance);
21684
21685 fundamentalInstance.instance = _instance5;
21686
21687 if (fundamentalImpl.reconcileChildren === false) {
21688 return null;
21689 }
21690
21691 appendAllChildren(_instance5, workInProgress, false, false);
21692 mountFundamentalComponent(fundamentalInstance);
21693 } else {
21694 // We fire update in commit phase
21695 var prevProps = fundamentalInstance.props;
21696 fundamentalInstance.prevProps = prevProps;
21697 fundamentalInstance.props = newProps;
21698 fundamentalInstance.currentFiber = workInProgress;
21699
21700 if (supportsPersistence) {
21701 var _instance6 = cloneFundamentalInstance(fundamentalInstance);
21702
21703 fundamentalInstance.instance = _instance6;
21704 appendAllChildren(_instance6, workInProgress, false, false);
21705 }
21706
21707 var shouldUpdate = shouldUpdateFundamentalComponent(fundamentalInstance);
21708
21709 if (shouldUpdate) {
21710 markUpdate(workInProgress);
21711 }
21712 }
21713 }
21714
21715 break;
21716 }
21717
21718 case ScopeComponent:
21719 {
21720 if (enableScopeAPI) {
21721 if (current === null) {
21722 var _type3 = workInProgress.type;
21723 var scopeInstance = {
21724 fiber: workInProgress,
21725 methods: null
21726 };
21727 workInProgress.stateNode = scopeInstance;
21728 scopeInstance.methods = createScopeMethods(_type3, scopeInstance);
21729
21730 if (enableFlareAPI) {
21731 var _listeners2 = newProps.listeners;
21732
21733 if (_listeners2 != null) {
21734 var _rootContainerInstance2 = getRootHostContainer();
21735
21736 updateEventListeners(_listeners2, workInProgress, _rootContainerInstance2);
21737 }
21738 }
21739
21740 if (workInProgress.ref !== null) {
21741 markRef$1(workInProgress);
21742 markUpdate(workInProgress);
21743 }
21744 } else {
21745 if (enableFlareAPI) {
21746 var _prevListeners = current.memoizedProps.listeners;
21747 var _nextListeners = newProps.listeners;
21748
21749 if (_prevListeners !== _nextListeners || workInProgress.ref !== null) {
21750 markUpdate(workInProgress);
21751 }
21752 } else {
21753 if (workInProgress.ref !== null) {
21754 markUpdate(workInProgress);
21755 }
21756 }
21757
21758 if (current.ref !== workInProgress.ref) {
21759 markRef$1(workInProgress);
21760 }
21761 }
21762 }
21763
21764 break;
21765 }
21766
21767 default:
21768 {
21769 {
21770 throw Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in React. Please file an issue.");
21771 }
21772 }
21773
21774 }
21775
21776 return null;
21777}
21778
21779function unwindWork(workInProgress, renderExpirationTime) {
21780 switch (workInProgress.tag) {
21781 case ClassComponent:
21782 {
21783 var Component = workInProgress.type;
21784
21785 if (isContextProvider(Component)) {
21786 popContext(workInProgress);
21787 }
21788
21789 var effectTag = workInProgress.effectTag;
21790
21791 if (effectTag & ShouldCapture) {
21792 workInProgress.effectTag = effectTag & ~ShouldCapture | DidCapture;
21793 return workInProgress;
21794 }
21795
21796 return null;
21797 }
21798
21799 case HostRoot:
21800 {
21801 popHostContainer(workInProgress);
21802 popTopLevelContextObject(workInProgress);
21803 var _effectTag = workInProgress.effectTag;
21804
21805 if (!((_effectTag & DidCapture) === NoEffect)) {
21806 {
21807 throw Error("The root failed to unmount after an error. This is likely a bug in React. Please file an issue.");
21808 }
21809 }
21810
21811 workInProgress.effectTag = _effectTag & ~ShouldCapture | DidCapture;
21812 return workInProgress;
21813 }
21814
21815 case HostComponent:
21816 {
21817 // TODO: popHydrationState
21818 popHostContext(workInProgress);
21819 return null;
21820 }
21821
21822 case SuspenseComponent:
21823 {
21824 popSuspenseContext(workInProgress);
21825
21826 if (enableSuspenseServerRenderer) {
21827 var suspenseState = workInProgress.memoizedState;
21828
21829 if (suspenseState !== null && suspenseState.dehydrated !== null) {
21830 if (!(workInProgress.alternate !== null)) {
21831 {
21832 throw Error("Threw in newly mounted dehydrated component. This is likely a bug in React. Please file an issue.");
21833 }
21834 }
21835
21836 resetHydrationState();
21837 }
21838 }
21839
21840 var _effectTag2 = workInProgress.effectTag;
21841
21842 if (_effectTag2 & ShouldCapture) {
21843 workInProgress.effectTag = _effectTag2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
21844
21845 return workInProgress;
21846 }
21847
21848 return null;
21849 }
21850
21851 case SuspenseListComponent:
21852 {
21853 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
21854 // caught by a nested boundary. If not, it should bubble through.
21855
21856 return null;
21857 }
21858
21859 case HostPortal:
21860 popHostContainer(workInProgress);
21861 return null;
21862
21863 case ContextProvider:
21864 popProvider(workInProgress);
21865 return null;
21866
21867 default:
21868 return null;
21869 }
21870}
21871
21872function unwindInterruptedWork(interruptedWork) {
21873 switch (interruptedWork.tag) {
21874 case ClassComponent:
21875 {
21876 var childContextTypes = interruptedWork.type.childContextTypes;
21877
21878 if (childContextTypes !== null && childContextTypes !== undefined) {
21879 popContext(interruptedWork);
21880 }
21881
21882 break;
21883 }
21884
21885 case HostRoot:
21886 {
21887 popHostContainer(interruptedWork);
21888 popTopLevelContextObject(interruptedWork);
21889 break;
21890 }
21891
21892 case HostComponent:
21893 {
21894 popHostContext(interruptedWork);
21895 break;
21896 }
21897
21898 case HostPortal:
21899 popHostContainer(interruptedWork);
21900 break;
21901
21902 case SuspenseComponent:
21903 popSuspenseContext(interruptedWork);
21904 break;
21905
21906 case SuspenseListComponent:
21907 popSuspenseContext(interruptedWork);
21908 break;
21909
21910 case ContextProvider:
21911 popProvider(interruptedWork);
21912 break;
21913
21914 default:
21915 break;
21916 }
21917}
21918
21919function createCapturedValue(value, source) {
21920 // If the value is an error, call this function immediately after it is thrown
21921 // so the stack is accurate.
21922 return {
21923 value: value,
21924 source: source,
21925 stack: getStackByFiberInDevAndProd(source)
21926 };
21927}
21928
21929// This module is forked in different environments.
21930// By default, return `true` to log errors to the console.
21931// Forks can return `false` if this isn't desirable.
21932function showErrorDialog(capturedError) {
21933 return true;
21934}
21935
21936function logCapturedError(capturedError) {
21937 var logError = showErrorDialog(capturedError); // Allow injected showErrorDialog() to prevent default console.error logging.
21938 // This enables renderers like ReactNative to better manage redbox behavior.
21939
21940 if (logError === false) {
21941 return;
21942 }
21943
21944 var error = capturedError.error;
21945
21946 {
21947 var componentName = capturedError.componentName,
21948 componentStack = capturedError.componentStack,
21949 errorBoundaryName = capturedError.errorBoundaryName,
21950 errorBoundaryFound = capturedError.errorBoundaryFound,
21951 willRetry = capturedError.willRetry; // Browsers support silencing uncaught errors by calling
21952 // `preventDefault()` in window `error` handler.
21953 // We record this information as an expando on the error.
21954
21955 if (error != null && error._suppressLogging) {
21956 if (errorBoundaryFound && willRetry) {
21957 // The error is recoverable and was silenced.
21958 // Ignore it and don't print the stack addendum.
21959 // This is handy for testing error boundaries without noise.
21960 return;
21961 } // The error is fatal. Since the silencing might have
21962 // been accidental, we'll surface it anyway.
21963 // However, the browser would have silenced the original error
21964 // so we'll print it first, and then print the stack addendum.
21965
21966
21967 console.error(error); // For a more detailed description of this block, see:
21968 // https://github.com/facebook/react/pull/13384
21969 }
21970
21971 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
21972 var errorBoundaryMessage; // errorBoundaryFound check is sufficient; errorBoundaryName check is to satisfy Flow.
21973
21974 if (errorBoundaryFound && errorBoundaryName) {
21975 if (willRetry) {
21976 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
21977 } else {
21978 errorBoundaryMessage = "This error was initially handled by the error boundary " + errorBoundaryName + ".\n" + "Recreating the tree from scratch failed so React will unmount the tree.";
21979 }
21980 } else {
21981 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.';
21982 }
21983
21984 var combinedMessage = "" + componentNameMessage + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
21985 // We don't include the original error message and JS stack because the browser
21986 // has already printed it. Even if the application swallows the error, it is still
21987 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
21988
21989 console.error(combinedMessage);
21990 }
21991}
21992
21993var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
21994
21995{
21996 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
21997}
21998
21999var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
22000function logError(boundary, errorInfo) {
22001 var source = errorInfo.source;
22002 var stack = errorInfo.stack;
22003
22004 if (stack === null && source !== null) {
22005 stack = getStackByFiberInDevAndProd(source);
22006 }
22007
22008 var capturedError = {
22009 componentName: source !== null ? getComponentName(source.type) : null,
22010 componentStack: stack !== null ? stack : '',
22011 error: errorInfo.value,
22012 errorBoundary: null,
22013 errorBoundaryName: null,
22014 errorBoundaryFound: false,
22015 willRetry: false
22016 };
22017
22018 if (boundary !== null && boundary.tag === ClassComponent) {
22019 capturedError.errorBoundary = boundary.stateNode;
22020 capturedError.errorBoundaryName = getComponentName(boundary.type);
22021 capturedError.errorBoundaryFound = true;
22022 capturedError.willRetry = true;
22023 }
22024
22025 try {
22026 logCapturedError(capturedError);
22027 } catch (e) {
22028 // This method must not throw, or React internal state will get messed up.
22029 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
22030 // we want to report this error outside of the normal stack as a last resort.
22031 // https://github.com/facebook/react/issues/13188
22032 setTimeout(function () {
22033 throw e;
22034 });
22035 }
22036}
22037
22038var callComponentWillUnmountWithTimer = function (current$$1, instance) {
22039 startPhaseTimer(current$$1, 'componentWillUnmount');
22040 instance.props = current$$1.memoizedProps;
22041 instance.state = current$$1.memoizedState;
22042 instance.componentWillUnmount();
22043 stopPhaseTimer();
22044}; // Capture errors so they don't interrupt unmounting.
22045
22046
22047function safelyCallComponentWillUnmount(current$$1, instance) {
22048 {
22049 invokeGuardedCallback(null, callComponentWillUnmountWithTimer, null, current$$1, instance);
22050
22051 if (hasCaughtError()) {
22052 var unmountError = clearCaughtError();
22053 captureCommitPhaseError(current$$1, unmountError);
22054 }
22055 }
22056}
22057
22058function safelyDetachRef(current$$1) {
22059 var ref = current$$1.ref;
22060
22061 if (ref !== null) {
22062 if (typeof ref === 'function') {
22063 {
22064 invokeGuardedCallback(null, ref, null, null);
22065
22066 if (hasCaughtError()) {
22067 var refError = clearCaughtError();
22068 captureCommitPhaseError(current$$1, refError);
22069 }
22070 }
22071 } else {
22072 ref.current = null;
22073 }
22074 }
22075}
22076
22077function safelyCallDestroy(current$$1, destroy) {
22078 {
22079 invokeGuardedCallback(null, destroy, null);
22080
22081 if (hasCaughtError()) {
22082 var error = clearCaughtError();
22083 captureCommitPhaseError(current$$1, error);
22084 }
22085 }
22086}
22087
22088function commitBeforeMutationLifeCycles(current$$1, finishedWork) {
22089 switch (finishedWork.tag) {
22090 case FunctionComponent:
22091 case ForwardRef:
22092 case SimpleMemoComponent:
22093 {
22094 commitHookEffectList(UnmountSnapshot, NoEffect$1, finishedWork);
22095 return;
22096 }
22097
22098 case ClassComponent:
22099 {
22100 if (finishedWork.effectTag & Snapshot) {
22101 if (current$$1 !== null) {
22102 var prevProps = current$$1.memoizedProps;
22103 var prevState = current$$1.memoizedState;
22104 startPhaseTimer(finishedWork, 'getSnapshotBeforeUpdate');
22105 var instance = finishedWork.stateNode; // We could update instance props and state here,
22106 // but instead we rely on them being set during last render.
22107 // TODO: revisit this when we implement resuming.
22108
22109 {
22110 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
22111 !(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;
22112 !(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;
22113 }
22114 }
22115
22116 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
22117
22118 {
22119 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
22120
22121 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
22122 didWarnSet.add(finishedWork.type);
22123 warningWithoutStack$1(false, '%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentName(finishedWork.type));
22124 }
22125 }
22126
22127 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
22128 stopPhaseTimer();
22129 }
22130 }
22131
22132 return;
22133 }
22134
22135 case HostRoot:
22136 case HostComponent:
22137 case HostText:
22138 case HostPortal:
22139 case IncompleteClassComponent:
22140 // Nothing to do for these component types
22141 return;
22142
22143 default:
22144 {
22145 {
22146 {
22147 throw Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.");
22148 }
22149 }
22150 }
22151 }
22152}
22153
22154function commitHookEffectList(unmountTag, mountTag, finishedWork) {
22155 var updateQueue = finishedWork.updateQueue;
22156 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
22157
22158 if (lastEffect !== null) {
22159 var firstEffect = lastEffect.next;
22160 var effect = firstEffect;
22161
22162 do {
22163 if ((effect.tag & unmountTag) !== NoEffect$1) {
22164 // Unmount
22165 var destroy = effect.destroy;
22166 effect.destroy = undefined;
22167
22168 if (destroy !== undefined) {
22169 destroy();
22170 }
22171 }
22172
22173 if ((effect.tag & mountTag) !== NoEffect$1) {
22174 // Mount
22175 var create = effect.create;
22176 effect.destroy = create();
22177
22178 {
22179 var _destroy = effect.destroy;
22180
22181 if (_destroy !== undefined && typeof _destroy !== 'function') {
22182 var addendum = void 0;
22183
22184 if (_destroy === null) {
22185 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
22186 } else if (typeof _destroy.then === 'function') {
22187 addendum = '\n\nIt looks like you wrote useEffect(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + 'useEffect(() => {\n' + ' async function fetchData() {\n' + ' // You can await here\n' + ' const response = await MyAPI.getData(someId);\n' + ' // ...\n' + ' }\n' + ' fetchData();\n' + "}, [someId]); // Or [] if effect doesn't need props or state\n\n" + 'Learn more about data fetching with Hooks: https://fb.me/react-hooks-data-fetching';
22188 } else {
22189 addendum = ' You returned: ' + _destroy;
22190 }
22191
22192 warningWithoutStack$1(false, 'An effect function must not return anything besides a function, ' + 'which is used for clean-up.%s%s', addendum, getStackByFiberInDevAndProd(finishedWork));
22193 }
22194 }
22195 }
22196
22197 effect = effect.next;
22198 } while (effect !== firstEffect);
22199 }
22200}
22201
22202function commitPassiveHookEffects(finishedWork) {
22203 if ((finishedWork.effectTag & Passive) !== NoEffect) {
22204 switch (finishedWork.tag) {
22205 case FunctionComponent:
22206 case ForwardRef:
22207 case SimpleMemoComponent:
22208 {
22209 commitHookEffectList(UnmountPassive, NoEffect$1, finishedWork);
22210 commitHookEffectList(NoEffect$1, MountPassive, finishedWork);
22211 break;
22212 }
22213
22214 default:
22215 break;
22216 }
22217 }
22218}
22219
22220function commitLifeCycles(finishedRoot, current$$1, finishedWork, committedExpirationTime) {
22221 switch (finishedWork.tag) {
22222 case FunctionComponent:
22223 case ForwardRef:
22224 case SimpleMemoComponent:
22225 {
22226 commitHookEffectList(UnmountLayout, MountLayout, finishedWork);
22227 break;
22228 }
22229
22230 case ClassComponent:
22231 {
22232 var instance = finishedWork.stateNode;
22233
22234 if (finishedWork.effectTag & Update) {
22235 if (current$$1 === null) {
22236 startPhaseTimer(finishedWork, 'componentDidMount'); // We could update instance props and state here,
22237 // but instead we rely on them being set during last render.
22238 // TODO: revisit this when we implement resuming.
22239
22240 {
22241 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
22242 !(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;
22243 !(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;
22244 }
22245 }
22246
22247 instance.componentDidMount();
22248 stopPhaseTimer();
22249 } else {
22250 var prevProps = finishedWork.elementType === finishedWork.type ? current$$1.memoizedProps : resolveDefaultProps(finishedWork.type, current$$1.memoizedProps);
22251 var prevState = current$$1.memoizedState;
22252 startPhaseTimer(finishedWork, 'componentDidUpdate'); // We could update instance props and state here,
22253 // but instead we rely on them being set during last render.
22254 // TODO: revisit this when we implement resuming.
22255
22256 {
22257 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
22258 !(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;
22259 !(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;
22260 }
22261 }
22262
22263 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
22264 stopPhaseTimer();
22265 }
22266 }
22267
22268 var updateQueue = finishedWork.updateQueue;
22269
22270 if (updateQueue !== null) {
22271 {
22272 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
22273 !(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;
22274 !(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;
22275 }
22276 } // We could update instance props and state here,
22277 // but instead we rely on them being set during last render.
22278 // TODO: revisit this when we implement resuming.
22279
22280
22281 commitUpdateQueue(finishedWork, updateQueue, instance, committedExpirationTime);
22282 }
22283
22284 return;
22285 }
22286
22287 case HostRoot:
22288 {
22289 var _updateQueue = finishedWork.updateQueue;
22290
22291 if (_updateQueue !== null) {
22292 var _instance = null;
22293
22294 if (finishedWork.child !== null) {
22295 switch (finishedWork.child.tag) {
22296 case HostComponent:
22297 _instance = getPublicInstance(finishedWork.child.stateNode);
22298 break;
22299
22300 case ClassComponent:
22301 _instance = finishedWork.child.stateNode;
22302 break;
22303 }
22304 }
22305
22306 commitUpdateQueue(finishedWork, _updateQueue, _instance, committedExpirationTime);
22307 }
22308
22309 return;
22310 }
22311
22312 case HostComponent:
22313 {
22314 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
22315 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
22316 // These effects should only be committed when components are first mounted,
22317 // aka when there is no current/alternate.
22318
22319 if (current$$1 === null && finishedWork.effectTag & Update) {
22320 var type = finishedWork.type;
22321 var props = finishedWork.memoizedProps;
22322 commitMount(_instance2, type, props, finishedWork);
22323 }
22324
22325 return;
22326 }
22327
22328 case HostText:
22329 {
22330 // We have no life-cycles associated with text.
22331 return;
22332 }
22333
22334 case HostPortal:
22335 {
22336 // We have no life-cycles associated with portals.
22337 return;
22338 }
22339
22340 case Profiler:
22341 {
22342 if (enableProfilerTimer) {
22343 var onRender = finishedWork.memoizedProps.onRender;
22344
22345 if (typeof onRender === 'function') {
22346 if (enableSchedulerTracing) {
22347 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime(), finishedRoot.memoizedInteractions);
22348 } else {
22349 onRender(finishedWork.memoizedProps.id, current$$1 === null ? 'mount' : 'update', finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, getCommitTime());
22350 }
22351 }
22352 }
22353
22354 return;
22355 }
22356
22357 case SuspenseComponent:
22358 {
22359 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
22360 return;
22361 }
22362
22363 case SuspenseListComponent:
22364 case IncompleteClassComponent:
22365 case FundamentalComponent:
22366 case ScopeComponent:
22367 return;
22368
22369 default:
22370 {
22371 {
22372 {
22373 throw Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.");
22374 }
22375 }
22376 }
22377 }
22378}
22379
22380function hideOrUnhideAllChildren(finishedWork, isHidden) {
22381 if (supportsMutation) {
22382 // We only have the top Fiber that was inserted but we need to recurse down its
22383 // children to find all the terminal nodes.
22384 var node = finishedWork;
22385
22386 while (true) {
22387 if (node.tag === HostComponent) {
22388 var instance = node.stateNode;
22389
22390 if (isHidden) {
22391 hideInstance(instance);
22392 } else {
22393 unhideInstance(node.stateNode, node.memoizedProps);
22394 }
22395 } else if (node.tag === HostText) {
22396 var _instance3 = node.stateNode;
22397
22398 if (isHidden) {
22399 hideTextInstance(_instance3);
22400 } else {
22401 unhideTextInstance(_instance3, node.memoizedProps);
22402 }
22403 } else if (node.tag === SuspenseComponent && node.memoizedState !== null && node.memoizedState.dehydrated === null) {
22404 // Found a nested Suspense component that timed out. Skip over the
22405 // primary child fragment, which should remain hidden.
22406 var fallbackChildFragment = node.child.sibling;
22407 fallbackChildFragment.return = node;
22408 node = fallbackChildFragment;
22409 continue;
22410 } else if (node.child !== null) {
22411 node.child.return = node;
22412 node = node.child;
22413 continue;
22414 }
22415
22416 if (node === finishedWork) {
22417 return;
22418 }
22419
22420 while (node.sibling === null) {
22421 if (node.return === null || node.return === finishedWork) {
22422 return;
22423 }
22424
22425 node = node.return;
22426 }
22427
22428 node.sibling.return = node.return;
22429 node = node.sibling;
22430 }
22431 }
22432}
22433
22434function commitAttachRef(finishedWork) {
22435 var ref = finishedWork.ref;
22436
22437 if (ref !== null) {
22438 var instance = finishedWork.stateNode;
22439 var instanceToUse;
22440
22441 switch (finishedWork.tag) {
22442 case HostComponent:
22443 instanceToUse = getPublicInstance(instance);
22444 break;
22445
22446 default:
22447 instanceToUse = instance;
22448 } // Moved outside to ensure DCE works with this flag
22449
22450
22451 if (enableScopeAPI && finishedWork.tag === ScopeComponent) {
22452 instanceToUse = instance.methods;
22453 }
22454
22455 if (typeof ref === 'function') {
22456 ref(instanceToUse);
22457 } else {
22458 {
22459 if (!ref.hasOwnProperty('current')) {
22460 warningWithoutStack$1(false, 'Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().%s', getComponentName(finishedWork.type), getStackByFiberInDevAndProd(finishedWork));
22461 }
22462 }
22463
22464 ref.current = instanceToUse;
22465 }
22466 }
22467}
22468
22469function commitDetachRef(current$$1) {
22470 var currentRef = current$$1.ref;
22471
22472 if (currentRef !== null) {
22473 if (typeof currentRef === 'function') {
22474 currentRef(null);
22475 } else {
22476 currentRef.current = null;
22477 }
22478 }
22479} // User-originating errors (lifecycles and refs) should not interrupt
22480// deletion, so don't let them throw. Host-originating errors should
22481// interrupt deletion, so it's okay
22482
22483
22484function commitUnmount(finishedRoot, current$$1, renderPriorityLevel) {
22485 onCommitUnmount(current$$1);
22486
22487 switch (current$$1.tag) {
22488 case FunctionComponent:
22489 case ForwardRef:
22490 case MemoComponent:
22491 case SimpleMemoComponent:
22492 {
22493 var updateQueue = current$$1.updateQueue;
22494
22495 if (updateQueue !== null) {
22496 var lastEffect = updateQueue.lastEffect;
22497
22498 if (lastEffect !== null) {
22499 var firstEffect = lastEffect.next; // When the owner fiber is deleted, the destroy function of a passive
22500 // effect hook is called during the synchronous commit phase. This is
22501 // a concession to implementation complexity. Calling it in the
22502 // passive effect phase (like they usually are, when dependencies
22503 // change during an update) would require either traversing the
22504 // children of the deleted fiber again, or including unmount effects
22505 // as part of the fiber effect list.
22506 //
22507 // Because this is during the sync commit phase, we need to change
22508 // the priority.
22509 //
22510 // TODO: Reconsider this implementation trade off.
22511
22512 var priorityLevel = renderPriorityLevel > NormalPriority ? NormalPriority : renderPriorityLevel;
22513 runWithPriority$2(priorityLevel, function () {
22514 var effect = firstEffect;
22515
22516 do {
22517 var destroy = effect.destroy;
22518
22519 if (destroy !== undefined) {
22520 safelyCallDestroy(current$$1, destroy);
22521 }
22522
22523 effect = effect.next;
22524 } while (effect !== firstEffect);
22525 });
22526 }
22527 }
22528
22529 break;
22530 }
22531
22532 case ClassComponent:
22533 {
22534 safelyDetachRef(current$$1);
22535 var instance = current$$1.stateNode;
22536
22537 if (typeof instance.componentWillUnmount === 'function') {
22538 safelyCallComponentWillUnmount(current$$1, instance);
22539 }
22540
22541 return;
22542 }
22543
22544 case HostComponent:
22545 {
22546 if (enableFlareAPI) {
22547 var dependencies = current$$1.dependencies;
22548
22549 if (dependencies !== null) {
22550 var respondersMap = dependencies.responders;
22551
22552 if (respondersMap !== null) {
22553 var responderInstances = Array.from(respondersMap.values());
22554
22555 for (var i = 0, length = responderInstances.length; i < length; i++) {
22556 var responderInstance = responderInstances[i];
22557 unmountResponderInstance(responderInstance);
22558 }
22559
22560 dependencies.responders = null;
22561 }
22562 }
22563 }
22564
22565 safelyDetachRef(current$$1);
22566 return;
22567 }
22568
22569 case HostPortal:
22570 {
22571 // TODO: this is recursive.
22572 // We are also not using this parent because
22573 // the portal will get pushed immediately.
22574 if (supportsMutation) {
22575 unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel);
22576 } else if (supportsPersistence) {
22577 emptyPortalContainer(current$$1);
22578 }
22579
22580 return;
22581 }
22582
22583 case FundamentalComponent:
22584 {
22585 if (enableFundamentalAPI) {
22586 var fundamentalInstance = current$$1.stateNode;
22587
22588 if (fundamentalInstance !== null) {
22589 unmountFundamentalComponent(fundamentalInstance);
22590 current$$1.stateNode = null;
22591 }
22592 }
22593
22594 return;
22595 }
22596
22597 case DehydratedFragment:
22598 {
22599 if (enableSuspenseCallback) {
22600 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
22601
22602 if (hydrationCallbacks !== null) {
22603 var onDeleted = hydrationCallbacks.onDeleted;
22604
22605 if (onDeleted) {
22606 onDeleted(current$$1.stateNode);
22607 }
22608 }
22609 }
22610
22611 return;
22612 }
22613
22614 case ScopeComponent:
22615 {
22616 if (enableScopeAPI) {
22617 safelyDetachRef(current$$1);
22618 }
22619 }
22620 }
22621}
22622
22623function commitNestedUnmounts(finishedRoot, root, renderPriorityLevel) {
22624 // While we're inside a removed host node we don't want to call
22625 // removeChild on the inner nodes because they're removed by the top
22626 // call anyway. We also want to call componentWillUnmount on all
22627 // composites before this host node is removed from the tree. Therefore
22628 // we do an inner loop while we're still inside the host node.
22629 var node = root;
22630
22631 while (true) {
22632 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because they may contain more composite or host nodes.
22633 // Skip portals because commitUnmount() currently visits them recursively.
22634
22635 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
22636 // If we don't use mutation we drill down into portals here instead.
22637 !supportsMutation || node.tag !== HostPortal)) {
22638 node.child.return = node;
22639 node = node.child;
22640 continue;
22641 }
22642
22643 if (node === root) {
22644 return;
22645 }
22646
22647 while (node.sibling === null) {
22648 if (node.return === null || node.return === root) {
22649 return;
22650 }
22651
22652 node = node.return;
22653 }
22654
22655 node.sibling.return = node.return;
22656 node = node.sibling;
22657 }
22658}
22659
22660function detachFiber(current$$1) {
22661 var alternate = current$$1.alternate; // Cut off the return pointers to disconnect it from the tree. Ideally, we
22662 // should clear the child pointer of the parent alternate to let this
22663 // get GC:ed but we don't know which for sure which parent is the current
22664 // one so we'll settle for GC:ing the subtree of this child. This child
22665 // itself will be GC:ed when the parent updates the next time.
22666
22667 current$$1.return = null;
22668 current$$1.child = null;
22669 current$$1.memoizedState = null;
22670 current$$1.updateQueue = null;
22671 current$$1.dependencies = null;
22672 current$$1.alternate = null;
22673 current$$1.firstEffect = null;
22674 current$$1.lastEffect = null;
22675 current$$1.pendingProps = null;
22676 current$$1.memoizedProps = null;
22677
22678 if (alternate !== null) {
22679 detachFiber(alternate);
22680 }
22681}
22682
22683function emptyPortalContainer(current$$1) {
22684 if (!supportsPersistence) {
22685 return;
22686 }
22687
22688 var portal = current$$1.stateNode;
22689 var containerInfo = portal.containerInfo;
22690 var emptyChildSet = createContainerChildSet(containerInfo);
22691 replaceContainerChildren(containerInfo, emptyChildSet);
22692}
22693
22694function commitContainer(finishedWork) {
22695 if (!supportsPersistence) {
22696 return;
22697 }
22698
22699 switch (finishedWork.tag) {
22700 case ClassComponent:
22701 case HostComponent:
22702 case HostText:
22703 case FundamentalComponent:
22704 {
22705 return;
22706 }
22707
22708 case HostRoot:
22709 case HostPortal:
22710 {
22711 var portalOrRoot = finishedWork.stateNode;
22712 var containerInfo = portalOrRoot.containerInfo,
22713 pendingChildren = portalOrRoot.pendingChildren;
22714 replaceContainerChildren(containerInfo, pendingChildren);
22715 return;
22716 }
22717
22718 default:
22719 {
22720 {
22721 {
22722 throw Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.");
22723 }
22724 }
22725 }
22726 }
22727}
22728
22729function getHostParentFiber(fiber) {
22730 var parent = fiber.return;
22731
22732 while (parent !== null) {
22733 if (isHostParent(parent)) {
22734 return parent;
22735 }
22736
22737 parent = parent.return;
22738 }
22739
22740 {
22741 {
22742 throw Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.");
22743 }
22744 }
22745}
22746
22747function isHostParent(fiber) {
22748 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
22749}
22750
22751function getHostSibling(fiber) {
22752 // We're going to search forward into the tree until we find a sibling host
22753 // node. Unfortunately, if multiple insertions are done in a row we have to
22754 // search past them. This leads to exponential search for the next sibling.
22755 // TODO: Find a more efficient way to do this.
22756 var node = fiber;
22757
22758 siblings: while (true) {
22759 // If we didn't find anything, let's try the next sibling.
22760 while (node.sibling === null) {
22761 if (node.return === null || isHostParent(node.return)) {
22762 // If we pop out of the root or hit the parent the fiber we are the
22763 // last sibling.
22764 return null;
22765 }
22766
22767 node = node.return;
22768 }
22769
22770 node.sibling.return = node.return;
22771 node = node.sibling;
22772
22773 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
22774 // If it is not host node and, we might have a host node inside it.
22775 // Try to search down until we find one.
22776 if (node.effectTag & Placement) {
22777 // If we don't have a child, try the siblings instead.
22778 continue siblings;
22779 } // If we don't have a child, try the siblings instead.
22780 // We also skip portals because they are not part of this host tree.
22781
22782
22783 if (node.child === null || node.tag === HostPortal) {
22784 continue siblings;
22785 } else {
22786 node.child.return = node;
22787 node = node.child;
22788 }
22789 } // Check if this host node is stable or about to be placed.
22790
22791
22792 if (!(node.effectTag & Placement)) {
22793 // Found it!
22794 return node.stateNode;
22795 }
22796 }
22797}
22798
22799function commitPlacement(finishedWork) {
22800 if (!supportsMutation) {
22801 return;
22802 } // Recursively insert all host nodes into the parent.
22803
22804
22805 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
22806
22807 var parent;
22808 var isContainer;
22809 var parentStateNode = parentFiber.stateNode;
22810
22811 switch (parentFiber.tag) {
22812 case HostComponent:
22813 parent = parentStateNode;
22814 isContainer = false;
22815 break;
22816
22817 case HostRoot:
22818 parent = parentStateNode.containerInfo;
22819 isContainer = true;
22820 break;
22821
22822 case HostPortal:
22823 parent = parentStateNode.containerInfo;
22824 isContainer = true;
22825 break;
22826
22827 case FundamentalComponent:
22828 if (enableFundamentalAPI) {
22829 parent = parentStateNode.instance;
22830 isContainer = false;
22831 }
22832
22833 // eslint-disable-next-line-no-fallthrough
22834
22835 default:
22836 {
22837 {
22838 throw Error("Invalid host parent fiber. This error is likely caused by a bug in React. Please file an issue.");
22839 }
22840 }
22841
22842 }
22843
22844 if (parentFiber.effectTag & ContentReset) {
22845 // Reset the text content of the parent before doing any insertions
22846 resetTextContent(parent); // Clear ContentReset from the effect tag
22847
22848 parentFiber.effectTag &= ~ContentReset;
22849 }
22850
22851 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
22852 // children to find all the terminal nodes.
22853
22854 var node = finishedWork;
22855
22856 while (true) {
22857 var isHost = node.tag === HostComponent || node.tag === HostText;
22858
22859 if (isHost || enableFundamentalAPI && node.tag === FundamentalComponent) {
22860 var stateNode = isHost ? node.stateNode : node.stateNode.instance;
22861
22862 if (before) {
22863 if (isContainer) {
22864 insertInContainerBefore(parent, stateNode, before);
22865 } else {
22866 insertBefore(parent, stateNode, before);
22867 }
22868 } else {
22869 if (isContainer) {
22870 appendChildToContainer(parent, stateNode);
22871 } else {
22872 appendChild(parent, stateNode);
22873 }
22874 }
22875 } else if (node.tag === HostPortal) {// If the insertion itself is a portal, then we don't want to traverse
22876 // down its children. Instead, we'll get insertions from each child in
22877 // the portal directly.
22878 } else if (node.child !== null) {
22879 node.child.return = node;
22880 node = node.child;
22881 continue;
22882 }
22883
22884 if (node === finishedWork) {
22885 return;
22886 }
22887
22888 while (node.sibling === null) {
22889 if (node.return === null || node.return === finishedWork) {
22890 return;
22891 }
22892
22893 node = node.return;
22894 }
22895
22896 node.sibling.return = node.return;
22897 node = node.sibling;
22898 }
22899}
22900
22901function unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel) {
22902 // We only have the top Fiber that was deleted but we need to recurse down its
22903 // children to find all the terminal nodes.
22904 var node = current$$1; // Each iteration, currentParent is populated with node's host parent if not
22905 // currentParentIsValid.
22906
22907 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
22908
22909 var currentParent;
22910 var currentParentIsContainer;
22911
22912 while (true) {
22913 if (!currentParentIsValid) {
22914 var parent = node.return;
22915
22916 findParent: while (true) {
22917 if (!(parent !== null)) {
22918 {
22919 throw Error("Expected to find a host parent. This error is likely caused by a bug in React. Please file an issue.");
22920 }
22921 }
22922
22923 var parentStateNode = parent.stateNode;
22924
22925 switch (parent.tag) {
22926 case HostComponent:
22927 currentParent = parentStateNode;
22928 currentParentIsContainer = false;
22929 break findParent;
22930
22931 case HostRoot:
22932 currentParent = parentStateNode.containerInfo;
22933 currentParentIsContainer = true;
22934 break findParent;
22935
22936 case HostPortal:
22937 currentParent = parentStateNode.containerInfo;
22938 currentParentIsContainer = true;
22939 break findParent;
22940
22941 case FundamentalComponent:
22942 if (enableFundamentalAPI) {
22943 currentParent = parentStateNode.instance;
22944 currentParentIsContainer = false;
22945 }
22946
22947 }
22948
22949 parent = parent.return;
22950 }
22951
22952 currentParentIsValid = true;
22953 }
22954
22955 if (node.tag === HostComponent || node.tag === HostText) {
22956 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
22957 // node from the tree.
22958
22959 if (currentParentIsContainer) {
22960 removeChildFromContainer(currentParent, node.stateNode);
22961 } else {
22962 removeChild(currentParent, node.stateNode);
22963 } // Don't visit children because we already visited them.
22964
22965 } else if (enableFundamentalAPI && node.tag === FundamentalComponent) {
22966 var fundamentalNode = node.stateNode.instance;
22967 commitNestedUnmounts(finishedRoot, node, renderPriorityLevel); // After all the children have unmounted, it is now safe to remove the
22968 // node from the tree.
22969
22970 if (currentParentIsContainer) {
22971 removeChildFromContainer(currentParent, fundamentalNode);
22972 } else {
22973 removeChild(currentParent, fundamentalNode);
22974 }
22975 } else if (enableSuspenseServerRenderer && node.tag === DehydratedFragment) {
22976 if (enableSuspenseCallback) {
22977 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
22978
22979 if (hydrationCallbacks !== null) {
22980 var onDeleted = hydrationCallbacks.onDeleted;
22981
22982 if (onDeleted) {
22983 onDeleted(node.stateNode);
22984 }
22985 }
22986 } // Delete the dehydrated suspense boundary and all of its content.
22987
22988
22989 if (currentParentIsContainer) {
22990 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
22991 } else {
22992 clearSuspenseBoundary(currentParent, node.stateNode);
22993 }
22994 } else if (node.tag === HostPortal) {
22995 if (node.child !== null) {
22996 // When we go into a portal, it becomes the parent to remove from.
22997 // We will reassign it back when we pop the portal on the way up.
22998 currentParent = node.stateNode.containerInfo;
22999 currentParentIsContainer = true; // Visit children because portals might contain host components.
23000
23001 node.child.return = node;
23002 node = node.child;
23003 continue;
23004 }
23005 } else {
23006 commitUnmount(finishedRoot, node, renderPriorityLevel); // Visit children because we may find more host components below.
23007
23008 if (node.child !== null) {
23009 node.child.return = node;
23010 node = node.child;
23011 continue;
23012 }
23013 }
23014
23015 if (node === current$$1) {
23016 return;
23017 }
23018
23019 while (node.sibling === null) {
23020 if (node.return === null || node.return === current$$1) {
23021 return;
23022 }
23023
23024 node = node.return;
23025
23026 if (node.tag === HostPortal) {
23027 // When we go out of the portal, we need to restore the parent.
23028 // Since we don't keep a stack of them, we will search for it.
23029 currentParentIsValid = false;
23030 }
23031 }
23032
23033 node.sibling.return = node.return;
23034 node = node.sibling;
23035 }
23036}
23037
23038function commitDeletion(finishedRoot, current$$1, renderPriorityLevel) {
23039 if (supportsMutation) {
23040 // Recursively delete all host nodes from the parent.
23041 // Detach refs and call componentWillUnmount() on the whole subtree.
23042 unmountHostComponents(finishedRoot, current$$1, renderPriorityLevel);
23043 } else {
23044 // Detach refs and call componentWillUnmount() on the whole subtree.
23045 commitNestedUnmounts(finishedRoot, current$$1, renderPriorityLevel);
23046 }
23047
23048 detachFiber(current$$1);
23049}
23050
23051function commitWork(current$$1, finishedWork) {
23052 if (!supportsMutation) {
23053 switch (finishedWork.tag) {
23054 case FunctionComponent:
23055 case ForwardRef:
23056 case MemoComponent:
23057 case SimpleMemoComponent:
23058 {
23059 // Note: We currently never use MountMutation, but useLayout uses
23060 // UnmountMutation.
23061 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
23062 return;
23063 }
23064
23065 case Profiler:
23066 {
23067 return;
23068 }
23069
23070 case SuspenseComponent:
23071 {
23072 commitSuspenseComponent(finishedWork);
23073 attachSuspenseRetryListeners(finishedWork);
23074 return;
23075 }
23076
23077 case SuspenseListComponent:
23078 {
23079 attachSuspenseRetryListeners(finishedWork);
23080 return;
23081 }
23082
23083 case HostRoot:
23084 {
23085 if (supportsHydration) {
23086 var root = finishedWork.stateNode;
23087
23088 if (root.hydrate) {
23089 // We've just hydrated. No need to hydrate again.
23090 root.hydrate = false;
23091 commitHydratedContainer(root.containerInfo);
23092 }
23093 }
23094
23095 break;
23096 }
23097 }
23098
23099 commitContainer(finishedWork);
23100 return;
23101 }
23102
23103 switch (finishedWork.tag) {
23104 case FunctionComponent:
23105 case ForwardRef:
23106 case MemoComponent:
23107 case SimpleMemoComponent:
23108 {
23109 // Note: We currently never use MountMutation, but useLayout uses
23110 // UnmountMutation.
23111 commitHookEffectList(UnmountMutation, MountMutation, finishedWork);
23112 return;
23113 }
23114
23115 case ClassComponent:
23116 {
23117 return;
23118 }
23119
23120 case HostComponent:
23121 {
23122 var instance = finishedWork.stateNode;
23123
23124 if (instance != null) {
23125 // Commit the work prepared earlier.
23126 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
23127 // as the newProps. The updatePayload will contain the real change in
23128 // this case.
23129
23130 var oldProps = current$$1 !== null ? current$$1.memoizedProps : newProps;
23131 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
23132
23133 var updatePayload = finishedWork.updateQueue;
23134 finishedWork.updateQueue = null;
23135
23136 if (updatePayload !== null) {
23137 commitUpdate(instance, updatePayload, type, oldProps, newProps, finishedWork);
23138 }
23139
23140 if (enableFlareAPI) {
23141 var prevListeners = oldProps.listeners;
23142 var nextListeners = newProps.listeners;
23143
23144 if (prevListeners !== nextListeners) {
23145 updateEventListeners(nextListeners, finishedWork, null);
23146 }
23147 }
23148 }
23149
23150 return;
23151 }
23152
23153 case HostText:
23154 {
23155 if (!(finishedWork.stateNode !== null)) {
23156 {
23157 throw Error("This should have a text node initialized. This error is likely caused by a bug in React. Please file an issue.");
23158 }
23159 }
23160
23161 var textInstance = finishedWork.stateNode;
23162 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
23163 // as the newProps. The updatePayload will contain the real change in
23164 // this case.
23165
23166 var oldText = current$$1 !== null ? current$$1.memoizedProps : newText;
23167 commitTextUpdate(textInstance, oldText, newText);
23168 return;
23169 }
23170
23171 case HostRoot:
23172 {
23173 if (supportsHydration) {
23174 var _root = finishedWork.stateNode;
23175
23176 if (_root.hydrate) {
23177 // We've just hydrated. No need to hydrate again.
23178 _root.hydrate = false;
23179 commitHydratedContainer(_root.containerInfo);
23180 }
23181 }
23182
23183 return;
23184 }
23185
23186 case Profiler:
23187 {
23188 return;
23189 }
23190
23191 case SuspenseComponent:
23192 {
23193 commitSuspenseComponent(finishedWork);
23194 attachSuspenseRetryListeners(finishedWork);
23195 return;
23196 }
23197
23198 case SuspenseListComponent:
23199 {
23200 attachSuspenseRetryListeners(finishedWork);
23201 return;
23202 }
23203
23204 case IncompleteClassComponent:
23205 {
23206 return;
23207 }
23208
23209 case FundamentalComponent:
23210 {
23211 if (enableFundamentalAPI) {
23212 var fundamentalInstance = finishedWork.stateNode;
23213 updateFundamentalComponent(fundamentalInstance);
23214 }
23215
23216 return;
23217 }
23218
23219 case ScopeComponent:
23220 {
23221 if (enableScopeAPI) {
23222 var scopeInstance = finishedWork.stateNode;
23223 scopeInstance.fiber = finishedWork;
23224
23225 if (enableFlareAPI) {
23226 var _newProps = finishedWork.memoizedProps;
23227
23228 var _oldProps = current$$1 !== null ? current$$1.memoizedProps : _newProps;
23229
23230 var _prevListeners = _oldProps.listeners;
23231 var _nextListeners = _newProps.listeners;
23232
23233 if (_prevListeners !== _nextListeners) {
23234 updateEventListeners(_nextListeners, finishedWork, null);
23235 }
23236 }
23237 }
23238
23239 return;
23240 }
23241
23242 default:
23243 {
23244 {
23245 {
23246 throw Error("This unit of work tag should not have side-effects. This error is likely caused by a bug in React. Please file an issue.");
23247 }
23248 }
23249 }
23250 }
23251}
23252
23253function commitSuspenseComponent(finishedWork) {
23254 var newState = finishedWork.memoizedState;
23255 var newDidTimeout;
23256 var primaryChildParent = finishedWork;
23257
23258 if (newState === null) {
23259 newDidTimeout = false;
23260 } else {
23261 newDidTimeout = true;
23262 primaryChildParent = finishedWork.child;
23263 markCommitTimeOfFallback();
23264 }
23265
23266 if (supportsMutation && primaryChildParent !== null) {
23267 hideOrUnhideAllChildren(primaryChildParent, newDidTimeout);
23268 }
23269
23270 if (enableSuspenseCallback && newState !== null) {
23271 var suspenseCallback = finishedWork.memoizedProps.suspenseCallback;
23272
23273 if (typeof suspenseCallback === 'function') {
23274 var thenables = finishedWork.updateQueue;
23275
23276 if (thenables !== null) {
23277 suspenseCallback(new Set(thenables));
23278 }
23279 } else {
23280 if (suspenseCallback !== undefined) {
23281 warning$1(false, 'Unexpected type for suspenseCallback.');
23282 }
23283 }
23284 }
23285}
23286
23287function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
23288 if (!supportsHydration) {
23289 return;
23290 }
23291
23292 var newState = finishedWork.memoizedState;
23293
23294 if (newState === null) {
23295 var current$$1 = finishedWork.alternate;
23296
23297 if (current$$1 !== null) {
23298 var prevState = current$$1.memoizedState;
23299
23300 if (prevState !== null) {
23301 var suspenseInstance = prevState.dehydrated;
23302
23303 if (suspenseInstance !== null) {
23304 commitHydratedSuspenseInstance(suspenseInstance);
23305
23306 if (enableSuspenseCallback) {
23307 var hydrationCallbacks = finishedRoot.hydrationCallbacks;
23308
23309 if (hydrationCallbacks !== null) {
23310 var onHydrated = hydrationCallbacks.onHydrated;
23311
23312 if (onHydrated) {
23313 onHydrated(suspenseInstance);
23314 }
23315 }
23316 }
23317 }
23318 }
23319 }
23320 }
23321}
23322
23323function attachSuspenseRetryListeners(finishedWork) {
23324 // If this boundary just timed out, then it will have a set of thenables.
23325 // For each thenable, attach a listener so that when it resolves, React
23326 // attempts to re-render the boundary in the primary (pre-timeout) state.
23327 var thenables = finishedWork.updateQueue;
23328
23329 if (thenables !== null) {
23330 finishedWork.updateQueue = null;
23331 var retryCache = finishedWork.stateNode;
23332
23333 if (retryCache === null) {
23334 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
23335 }
23336
23337 thenables.forEach(function (thenable) {
23338 // Memoize using the boundary fiber to prevent redundant listeners.
23339 var retry = resolveRetryThenable.bind(null, finishedWork, thenable);
23340
23341 if (!retryCache.has(thenable)) {
23342 if (enableSchedulerTracing) {
23343 if (thenable.__reactDoNotTraceInteractions !== true) {
23344 retry = unstable_wrap(retry);
23345 }
23346 }
23347
23348 retryCache.add(thenable);
23349 thenable.then(retry, retry);
23350 }
23351 });
23352 }
23353}
23354
23355function commitResetTextContent(current$$1) {
23356 if (!supportsMutation) {
23357 return;
23358 }
23359
23360 resetTextContent(current$$1.stateNode);
23361}
23362
23363var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
23364
23365function createRootErrorUpdate(fiber, errorInfo, expirationTime) {
23366 var update = createUpdate(expirationTime, null); // Unmount the root by rendering null.
23367
23368 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
23369 // being called "element".
23370
23371 update.payload = {
23372 element: null
23373 };
23374 var error = errorInfo.value;
23375
23376 update.callback = function () {
23377 onUncaughtError(error);
23378 logError(fiber, errorInfo);
23379 };
23380
23381 return update;
23382}
23383
23384function createClassErrorUpdate(fiber, errorInfo, expirationTime) {
23385 var update = createUpdate(expirationTime, null);
23386 update.tag = CaptureUpdate;
23387 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
23388
23389 if (typeof getDerivedStateFromError === 'function') {
23390 var error = errorInfo.value;
23391
23392 update.payload = function () {
23393 logError(fiber, errorInfo);
23394 return getDerivedStateFromError(error);
23395 };
23396 }
23397
23398 var inst = fiber.stateNode;
23399
23400 if (inst !== null && typeof inst.componentDidCatch === 'function') {
23401 update.callback = function callback() {
23402 {
23403 markFailedErrorBoundaryForHotReloading(fiber);
23404 }
23405
23406 if (typeof getDerivedStateFromError !== 'function') {
23407 // To preserve the preexisting retry behavior of error boundaries,
23408 // we keep track of which ones already failed during this batch.
23409 // This gets reset before we yield back to the browser.
23410 // TODO: Warn in strict mode if getDerivedStateFromError is
23411 // not defined.
23412 markLegacyErrorBoundaryAsFailed(this); // Only log here if componentDidCatch is the only error boundary method defined
23413
23414 logError(fiber, errorInfo);
23415 }
23416
23417 var error = errorInfo.value;
23418 var stack = errorInfo.stack;
23419 this.componentDidCatch(error, {
23420 componentStack: stack !== null ? stack : ''
23421 });
23422
23423 {
23424 if (typeof getDerivedStateFromError !== 'function') {
23425 // If componentDidCatch is the only error boundary method defined,
23426 // then it needs to call setState to recover from errors.
23427 // If no state update is scheduled then the boundary will swallow the error.
23428 !(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;
23429 }
23430 }
23431 };
23432 } else {
23433 update.callback = function () {
23434 markFailedErrorBoundaryForHotReloading(fiber);
23435 };
23436 }
23437
23438 return update;
23439}
23440
23441function attachPingListener(root, renderExpirationTime, thenable) {
23442 // Attach a listener to the promise to "ping" the root and retry. But
23443 // only if one does not already exist for the current render expiration
23444 // time (which acts like a "thread ID" here).
23445 var pingCache = root.pingCache;
23446 var threadIDs;
23447
23448 if (pingCache === null) {
23449 pingCache = root.pingCache = new PossiblyWeakMap$1();
23450 threadIDs = new Set();
23451 pingCache.set(thenable, threadIDs);
23452 } else {
23453 threadIDs = pingCache.get(thenable);
23454
23455 if (threadIDs === undefined) {
23456 threadIDs = new Set();
23457 pingCache.set(thenable, threadIDs);
23458 }
23459 }
23460
23461 if (!threadIDs.has(renderExpirationTime)) {
23462 // Memoize using the thread ID to prevent redundant listeners.
23463 threadIDs.add(renderExpirationTime);
23464 var ping = pingSuspendedRoot.bind(null, root, thenable, renderExpirationTime);
23465 thenable.then(ping, ping);
23466 }
23467}
23468
23469function throwException(root, returnFiber, sourceFiber, value, renderExpirationTime) {
23470 // The source fiber did not complete.
23471 sourceFiber.effectTag |= Incomplete; // Its effect list is no longer valid.
23472
23473 sourceFiber.firstEffect = sourceFiber.lastEffect = null;
23474
23475 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
23476 // This is a thenable.
23477 var thenable = value;
23478 checkForWrongSuspensePriorityInDEV(sourceFiber);
23479 var hasInvisibleParentBoundary = hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext); // Schedule the nearest Suspense to re-render the timed out view.
23480
23481 var _workInProgress = returnFiber;
23482
23483 do {
23484 if (_workInProgress.tag === SuspenseComponent && shouldCaptureSuspense(_workInProgress, hasInvisibleParentBoundary)) {
23485 // Found the nearest boundary.
23486 // Stash the promise on the boundary fiber. If the boundary times out, we'll
23487 // attach another listener to flip the boundary back to its normal state.
23488 var thenables = _workInProgress.updateQueue;
23489
23490 if (thenables === null) {
23491 var updateQueue = new Set();
23492 updateQueue.add(thenable);
23493 _workInProgress.updateQueue = updateQueue;
23494 } else {
23495 thenables.add(thenable);
23496 } // If the boundary is outside of blocking mode, we should *not*
23497 // suspend the commit. Pretend as if the suspended component rendered
23498 // null and keep rendering. In the commit phase, we'll schedule a
23499 // subsequent synchronous update to re-render the Suspense.
23500 //
23501 // Note: It doesn't matter whether the component that suspended was
23502 // inside a blocking mode tree. If the Suspense is outside of it, we
23503 // should *not* suspend the commit.
23504
23505
23506 if ((_workInProgress.mode & BlockingMode) === NoMode) {
23507 _workInProgress.effectTag |= DidCapture; // We're going to commit this fiber even though it didn't complete.
23508 // But we shouldn't call any lifecycle methods or callbacks. Remove
23509 // all lifecycle effect tags.
23510
23511 sourceFiber.effectTag &= ~(LifecycleEffectMask | Incomplete);
23512
23513 if (sourceFiber.tag === ClassComponent) {
23514 var currentSourceFiber = sourceFiber.alternate;
23515
23516 if (currentSourceFiber === null) {
23517 // This is a new mount. Change the tag so it's not mistaken for a
23518 // completed class component. For example, we should not call
23519 // componentWillUnmount if it is deleted.
23520 sourceFiber.tag = IncompleteClassComponent;
23521 } else {
23522 // When we try rendering again, we should not reuse the current fiber,
23523 // since it's known to be in an inconsistent state. Use a force update to
23524 // prevent a bail out.
23525 var update = createUpdate(Sync, null);
23526 update.tag = ForceUpdate;
23527 enqueueUpdate(sourceFiber, update);
23528 }
23529 } // The source fiber did not complete. Mark it with Sync priority to
23530 // indicate that it still has pending work.
23531
23532
23533 sourceFiber.expirationTime = Sync; // Exit without suspending.
23534
23535 return;
23536 } // Confirmed that the boundary is in a concurrent mode tree. Continue
23537 // with the normal suspend path.
23538 //
23539 // After this we'll use a set of heuristics to determine whether this
23540 // render pass will run to completion or restart or "suspend" the commit.
23541 // The actual logic for this is spread out in different places.
23542 //
23543 // This first principle is that if we're going to suspend when we complete
23544 // a root, then we should also restart if we get an update or ping that
23545 // might unsuspend it, and vice versa. The only reason to suspend is
23546 // because you think you might want to restart before committing. However,
23547 // it doesn't make sense to restart only while in the period we're suspended.
23548 //
23549 // Restarting too aggressively is also not good because it starves out any
23550 // intermediate loading state. So we use heuristics to determine when.
23551 // Suspense Heuristics
23552 //
23553 // If nothing threw a Promise or all the same fallbacks are already showing,
23554 // then don't suspend/restart.
23555 //
23556 // If this is an initial render of a new tree of Suspense boundaries and
23557 // those trigger a fallback, then don't suspend/restart. We want to ensure
23558 // that we can show the initial loading state as quickly as possible.
23559 //
23560 // If we hit a "Delayed" case, such as when we'd switch from content back into
23561 // a fallback, then we should always suspend/restart. SuspenseConfig applies to
23562 // this case. If none is defined, JND is used instead.
23563 //
23564 // If we're already showing a fallback and it gets "retried", allowing us to show
23565 // another level, but there's still an inner boundary that would show a fallback,
23566 // then we suspend/restart for 500ms since the last time we showed a fallback
23567 // anywhere in the tree. This effectively throttles progressive loading into a
23568 // consistent train of commits. This also gives us an opportunity to restart to
23569 // get to the completed state slightly earlier.
23570 //
23571 // If there's ambiguity due to batching it's resolved in preference of:
23572 // 1) "delayed", 2) "initial render", 3) "retry".
23573 //
23574 // We want to ensure that a "busy" state doesn't get force committed. We want to
23575 // ensure that new initial loading states can commit as soon as possible.
23576
23577
23578 attachPingListener(root, renderExpirationTime, thenable);
23579 _workInProgress.effectTag |= ShouldCapture;
23580 _workInProgress.expirationTime = renderExpirationTime;
23581 return;
23582 } // This boundary already captured during this render. Continue to the next
23583 // boundary.
23584
23585
23586 _workInProgress = _workInProgress.return;
23587 } while (_workInProgress !== null); // No boundary was found. Fallthrough to error mode.
23588 // TODO: Use invariant so the message is stripped in prod?
23589
23590
23591 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));
23592 } // We didn't find a boundary that could handle this type of exception. Start
23593 // over and traverse parent path again, this time treating the exception
23594 // as an error.
23595
23596
23597 renderDidError();
23598 value = createCapturedValue(value, sourceFiber);
23599 var workInProgress = returnFiber;
23600
23601 do {
23602 switch (workInProgress.tag) {
23603 case HostRoot:
23604 {
23605 var _errorInfo = value;
23606 workInProgress.effectTag |= ShouldCapture;
23607 workInProgress.expirationTime = renderExpirationTime;
23608
23609 var _update = createRootErrorUpdate(workInProgress, _errorInfo, renderExpirationTime);
23610
23611 enqueueCapturedUpdate(workInProgress, _update);
23612 return;
23613 }
23614
23615 case ClassComponent:
23616 // Capture and retry
23617 var errorInfo = value;
23618 var ctor = workInProgress.type;
23619 var instance = workInProgress.stateNode;
23620
23621 if ((workInProgress.effectTag & DidCapture) === NoEffect && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
23622 workInProgress.effectTag |= ShouldCapture;
23623 workInProgress.expirationTime = renderExpirationTime; // Schedule the error boundary to re-render using updated state
23624
23625 var _update2 = createClassErrorUpdate(workInProgress, errorInfo, renderExpirationTime);
23626
23627 enqueueCapturedUpdate(workInProgress, _update2);
23628 return;
23629 }
23630
23631 break;
23632
23633 default:
23634 break;
23635 }
23636
23637 workInProgress = workInProgress.return;
23638 } while (workInProgress !== null);
23639}
23640
23641var ceil = Math.ceil;
23642var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
23643var ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner;
23644var IsSomeRendererActing = ReactSharedInternals.IsSomeRendererActing;
23645var NoContext =
23646/* */
236470;
23648var BatchedContext =
23649/* */
236501;
23651var EventContext =
23652/* */
236532;
23654var DiscreteEventContext =
23655/* */
236564;
23657var LegacyUnbatchedContext =
23658/* */
236598;
23660var RenderContext =
23661/* */
2366216;
23663var CommitContext =
23664/* */
2366532;
23666var RootIncomplete = 0;
23667var RootFatalErrored = 1;
23668var RootErrored = 2;
23669var RootSuspended = 3;
23670var RootSuspendedWithDelay = 4;
23671var RootCompleted = 5;
23672// Describes where we are in the React execution stack
23673var executionContext = NoContext; // The root we're working on
23674
23675var workInProgressRoot = null; // The fiber we're working on
23676
23677var workInProgress = null; // The expiration time we're rendering
23678
23679var renderExpirationTime = NoWork; // Whether to root completed, errored, suspended, etc.
23680
23681var workInProgressRootExitStatus = RootIncomplete; // A fatal error, if one is thrown
23682
23683var workInProgressRootFatalError = null; // Most recent event time among processed updates during this render.
23684// This is conceptually a time stamp but expressed in terms of an ExpirationTime
23685// because we deal mostly with expiration times in the hot path, so this avoids
23686// the conversion happening in the hot path.
23687
23688var workInProgressRootLatestProcessedExpirationTime = Sync;
23689var workInProgressRootLatestSuspenseTimeout = Sync;
23690var workInProgressRootCanSuspendUsingConfig = null; // The work left over by components that were visited during this render. Only
23691// includes unprocessed updates, not work in bailed out children.
23692
23693var workInProgressRootNextUnprocessedUpdateTime = NoWork; // If we're pinged while rendering we don't always restart immediately.
23694// This flag determines if it might be worthwhile to restart if an opportunity
23695// happens latere.
23696
23697var workInProgressRootHasPendingPing = false; // The most recent time we committed a fallback. This lets us ensure a train
23698// model where we don't commit new loading states in too quick succession.
23699
23700var globalMostRecentFallbackTime = 0;
23701var FALLBACK_THROTTLE_MS = 500;
23702var nextEffect = null;
23703var hasUncaughtError = false;
23704var firstUncaughtError = null;
23705var legacyErrorBoundariesThatAlreadyFailed = null;
23706var rootDoesHavePassiveEffects = false;
23707var rootWithPendingPassiveEffects = null;
23708var pendingPassiveEffectsRenderPriority = NoPriority;
23709var pendingPassiveEffectsExpirationTime = NoWork;
23710var rootsWithPendingDiscreteUpdates = null; // Use these to prevent an infinite loop of nested updates
23711
23712var NESTED_UPDATE_LIMIT = 50;
23713var nestedUpdateCount = 0;
23714var rootWithNestedUpdates = null;
23715var NESTED_PASSIVE_UPDATE_LIMIT = 50;
23716var nestedPassiveUpdateCount = 0;
23717var interruptedBy = null; // Marks the need to reschedule pending interactions at these expiration times
23718// during the commit phase. This enables them to be traced across components
23719// that spawn new work during render. E.g. hidden boundaries, suspended SSR
23720// hydration or SuspenseList.
23721
23722var spawnedWorkDuringRender = null; // Expiration times are computed by adding to the current time (the start
23723// time). However, if two updates are scheduled within the same event, we
23724// should treat their start times as simultaneous, even if the actual clock
23725// time has advanced between the first and second call.
23726// In other words, because expiration times determine how updates are batched,
23727// we want all updates of like priority that occur within the same event to
23728// receive the same expiration time. Otherwise we get tearing.
23729
23730var currentEventTime = NoWork;
23731function requestCurrentTimeForUpdate() {
23732 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
23733 // We're inside React, so it's fine to read the actual time.
23734 return msToExpirationTime(now());
23735 } // We're not inside React, so we may be in the middle of a browser event.
23736
23737
23738 if (currentEventTime !== NoWork) {
23739 // Use the same start time for all updates until we enter React again.
23740 return currentEventTime;
23741 } // This is the first update since React yielded. Compute a new start time.
23742
23743
23744 currentEventTime = msToExpirationTime(now());
23745 return currentEventTime;
23746}
23747function getCurrentTime() {
23748 return msToExpirationTime(now());
23749}
23750function computeExpirationForFiber(currentTime, fiber, suspenseConfig) {
23751 var mode = fiber.mode;
23752
23753 if ((mode & BlockingMode) === NoMode) {
23754 return Sync;
23755 }
23756
23757 var priorityLevel = getCurrentPriorityLevel();
23758
23759 if ((mode & ConcurrentMode) === NoMode) {
23760 return priorityLevel === ImmediatePriority ? Sync : Batched;
23761 }
23762
23763 if ((executionContext & RenderContext) !== NoContext) {
23764 // Use whatever time we're already rendering
23765 // TODO: Should there be a way to opt out, like with `runWithPriority`?
23766 return renderExpirationTime;
23767 }
23768
23769 var expirationTime;
23770
23771 if (suspenseConfig !== null) {
23772 // Compute an expiration time based on the Suspense timeout.
23773 expirationTime = computeSuspenseExpiration(currentTime, suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
23774 } else {
23775 // Compute an expiration time based on the Scheduler priority.
23776 switch (priorityLevel) {
23777 case ImmediatePriority:
23778 expirationTime = Sync;
23779 break;
23780
23781 case UserBlockingPriority$2:
23782 // TODO: Rename this to computeUserBlockingExpiration
23783 expirationTime = computeInteractiveExpiration(currentTime);
23784 break;
23785
23786 case NormalPriority:
23787 case LowPriority:
23788 // TODO: Handle LowPriority
23789 // TODO: Rename this to... something better.
23790 expirationTime = computeAsyncExpiration(currentTime);
23791 break;
23792
23793 case IdlePriority:
23794 expirationTime = Idle;
23795 break;
23796
23797 default:
23798 {
23799 {
23800 throw Error("Expected a valid priority level");
23801 }
23802 }
23803
23804 }
23805 } // If we're in the middle of rendering a tree, do not update at the same
23806 // expiration time that is already rendering.
23807 // TODO: We shouldn't have to do this if the update is on a different root.
23808 // Refactor computeExpirationForFiber + scheduleUpdate so we have access to
23809 // the root when we check for this condition.
23810
23811
23812 if (workInProgressRoot !== null && expirationTime === renderExpirationTime) {
23813 // This is a trick to move this update into a separate batch
23814 expirationTime -= 1;
23815 }
23816
23817 return expirationTime;
23818}
23819function scheduleUpdateOnFiber(fiber, expirationTime) {
23820 checkForNestedUpdates();
23821 warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber);
23822 var root = markUpdateTimeFromFiberToRoot(fiber, expirationTime);
23823
23824 if (root === null) {
23825 warnAboutUpdateOnUnmountedFiberInDEV(fiber);
23826 return;
23827 }
23828
23829 checkForInterruption(fiber, expirationTime);
23830 recordScheduleUpdate(); // TODO: computeExpirationForFiber also reads the priority. Pass the
23831 // priority as an argument to that function and this one.
23832
23833 var priorityLevel = getCurrentPriorityLevel();
23834
23835 if (expirationTime === Sync) {
23836 if ( // Check if we're inside unbatchedUpdates
23837 (executionContext & LegacyUnbatchedContext) !== NoContext && // Check if we're not already rendering
23838 (executionContext & (RenderContext | CommitContext)) === NoContext) {
23839 // Register pending interactions on the root to avoid losing traced interaction data.
23840 schedulePendingInteractions(root, expirationTime); // This is a legacy edge case. The initial mount of a ReactDOM.render-ed
23841 // root inside of batchedUpdates should be synchronous, but layout updates
23842 // should be deferred until the end of the batch.
23843
23844 performSyncWorkOnRoot(root);
23845 } else {
23846 ensureRootIsScheduled(root);
23847 schedulePendingInteractions(root, expirationTime);
23848
23849 if (executionContext === NoContext) {
23850 // Flush the synchronous work now, unless we're already working or inside
23851 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
23852 // scheduleCallbackForFiber to preserve the ability to schedule a callback
23853 // without immediately flushing it. We only do this for user-initiated
23854 // updates, to preserve historical behavior of legacy mode.
23855 flushSyncCallbackQueue();
23856 }
23857 }
23858 } else {
23859 ensureRootIsScheduled(root);
23860 schedulePendingInteractions(root, expirationTime);
23861 }
23862
23863 if ((executionContext & DiscreteEventContext) !== NoContext && ( // Only updates at user-blocking priority or greater are considered
23864 // discrete, even inside a discrete event.
23865 priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority)) {
23866 // This is the result of a discrete event. Track the lowest priority
23867 // discrete update per root so we can flush them early, if needed.
23868 if (rootsWithPendingDiscreteUpdates === null) {
23869 rootsWithPendingDiscreteUpdates = new Map([[root, expirationTime]]);
23870 } else {
23871 var lastDiscreteTime = rootsWithPendingDiscreteUpdates.get(root);
23872
23873 if (lastDiscreteTime === undefined || lastDiscreteTime > expirationTime) {
23874 rootsWithPendingDiscreteUpdates.set(root, expirationTime);
23875 }
23876 }
23877 }
23878}
23879var scheduleWork = scheduleUpdateOnFiber; // This is split into a separate function so we can mark a fiber with pending
23880// work without treating it as a typical update that originates from an event;
23881// e.g. retrying a Suspense boundary isn't an update, but it does schedule work
23882// on a fiber.
23883
23884function markUpdateTimeFromFiberToRoot(fiber, expirationTime) {
23885 // Update the source fiber's expiration time
23886 if (fiber.expirationTime < expirationTime) {
23887 fiber.expirationTime = expirationTime;
23888 }
23889
23890 var alternate = fiber.alternate;
23891
23892 if (alternate !== null && alternate.expirationTime < expirationTime) {
23893 alternate.expirationTime = expirationTime;
23894 } // Walk the parent path to the root and update the child expiration time.
23895
23896
23897 var node = fiber.return;
23898 var root = null;
23899
23900 if (node === null && fiber.tag === HostRoot) {
23901 root = fiber.stateNode;
23902 } else {
23903 while (node !== null) {
23904 alternate = node.alternate;
23905
23906 if (node.childExpirationTime < expirationTime) {
23907 node.childExpirationTime = expirationTime;
23908
23909 if (alternate !== null && alternate.childExpirationTime < expirationTime) {
23910 alternate.childExpirationTime = expirationTime;
23911 }
23912 } else if (alternate !== null && alternate.childExpirationTime < expirationTime) {
23913 alternate.childExpirationTime = expirationTime;
23914 }
23915
23916 if (node.return === null && node.tag === HostRoot) {
23917 root = node.stateNode;
23918 break;
23919 }
23920
23921 node = node.return;
23922 }
23923 }
23924
23925 if (root !== null) {
23926 if (workInProgressRoot === root) {
23927 // Received an update to a tree that's in the middle of rendering. Mark
23928 // that's unprocessed work on this root.
23929 markUnprocessedUpdateTime(expirationTime);
23930
23931 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
23932 // The root already suspended with a delay, which means this render
23933 // definitely won't finish. Since we have a new update, let's mark it as
23934 // suspended now, right before marking the incoming update. This has the
23935 // effect of interrupting the current render and switching to the update.
23936 // TODO: This happens to work when receiving an update during the render
23937 // phase, because of the trick inside computeExpirationForFiber to
23938 // subtract 1 from `renderExpirationTime` to move it into a
23939 // separate bucket. But we should probably model it with an exception,
23940 // using the same mechanism we use to force hydration of a subtree.
23941 // TODO: This does not account for low pri updates that were already
23942 // scheduled before the root started rendering. Need to track the next
23943 // pending expiration time (perhaps by backtracking the return path) and
23944 // then trigger a restart in the `renderDidSuspendDelayIfPossible` path.
23945 markRootSuspendedAtTime(root, renderExpirationTime);
23946 }
23947 } // Mark that the root has a pending update.
23948
23949
23950 markRootUpdatedAtTime(root, expirationTime);
23951 }
23952
23953 return root;
23954}
23955
23956function getNextRootExpirationTimeToWorkOn(root) {
23957 // Determines the next expiration time that the root should render, taking
23958 // into account levels that may be suspended, or levels that may have
23959 // received a ping.
23960 var lastExpiredTime = root.lastExpiredTime;
23961
23962 if (lastExpiredTime !== NoWork) {
23963 return lastExpiredTime;
23964 } // "Pending" refers to any update that hasn't committed yet, including if it
23965 // suspended. The "suspended" range is therefore a subset.
23966
23967
23968 var firstPendingTime = root.firstPendingTime;
23969
23970 if (!isRootSuspendedAtTime(root, firstPendingTime)) {
23971 // The highest priority pending time is not suspended. Let's work on that.
23972 return firstPendingTime;
23973 } // If the first pending time is suspended, check if there's a lower priority
23974 // pending level that we know about. Or check if we received a ping. Work
23975 // on whichever is higher priority.
23976
23977
23978 var lastPingedTime = root.lastPingedTime;
23979 var nextKnownPendingLevel = root.nextKnownPendingLevel;
23980 return lastPingedTime > nextKnownPendingLevel ? lastPingedTime : nextKnownPendingLevel;
23981} // Use this function to schedule a task for a root. There's only one task per
23982// root; if a task was already scheduled, we'll check to make sure the
23983// expiration time of the existing task is the same as the expiration time of
23984// the next level that the root has work on. This function is called on every
23985// update, and right before exiting a task.
23986
23987
23988function ensureRootIsScheduled(root) {
23989 var lastExpiredTime = root.lastExpiredTime;
23990
23991 if (lastExpiredTime !== NoWork) {
23992 // Special case: Expired work should flush synchronously.
23993 root.callbackExpirationTime = Sync;
23994 root.callbackPriority = ImmediatePriority;
23995 root.callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
23996 return;
23997 }
23998
23999 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
24000 var existingCallbackNode = root.callbackNode;
24001
24002 if (expirationTime === NoWork) {
24003 // There's nothing to work on.
24004 if (existingCallbackNode !== null) {
24005 root.callbackNode = null;
24006 root.callbackExpirationTime = NoWork;
24007 root.callbackPriority = NoPriority;
24008 }
24009
24010 return;
24011 } // TODO: If this is an update, we already read the current time. Pass the
24012 // time as an argument.
24013
24014
24015 var currentTime = requestCurrentTimeForUpdate();
24016 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime); // If there's an existing render task, confirm it has the correct priority and
24017 // expiration time. Otherwise, we'll cancel it and schedule a new one.
24018
24019 if (existingCallbackNode !== null) {
24020 var existingCallbackPriority = root.callbackPriority;
24021 var existingCallbackExpirationTime = root.callbackExpirationTime;
24022
24023 if ( // Callback must have the exact same expiration time.
24024 existingCallbackExpirationTime === expirationTime && // Callback must have greater or equal priority.
24025 existingCallbackPriority >= priorityLevel) {
24026 // Existing callback is sufficient.
24027 return;
24028 } // Need to schedule a new task.
24029 // TODO: Instead of scheduling a new task, we should be able to change the
24030 // priority of the existing one.
24031
24032
24033 cancelCallback(existingCallbackNode);
24034 }
24035
24036 root.callbackExpirationTime = expirationTime;
24037 root.callbackPriority = priorityLevel;
24038 var callbackNode;
24039
24040 if (expirationTime === Sync) {
24041 // Sync React callbacks are scheduled on a special internal queue
24042 callbackNode = scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
24043 } else if (disableSchedulerTimeoutBasedOnReactExpirationTime) {
24044 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root));
24045 } else {
24046 callbackNode = scheduleCallback(priorityLevel, performConcurrentWorkOnRoot.bind(null, root), // Compute a task timeout based on the expiration time. This also affects
24047 // ordering because tasks are processed in timeout order.
24048 {
24049 timeout: expirationTimeToMs(expirationTime) - now()
24050 });
24051 }
24052
24053 root.callbackNode = callbackNode;
24054} // This is the entry point for every concurrent task, i.e. anything that
24055// goes through Scheduler.
24056
24057
24058function performConcurrentWorkOnRoot(root, didTimeout) {
24059 // Since we know we're in a React event, we can clear the current
24060 // event time. The next update will compute a new event time.
24061 currentEventTime = NoWork;
24062
24063 if (didTimeout) {
24064 // The render task took too long to complete. Mark the current time as
24065 // expired to synchronously render all expired work in a single batch.
24066 var currentTime = requestCurrentTimeForUpdate();
24067 markRootExpiredAtTime(root, currentTime); // This will schedule a synchronous callback.
24068
24069 ensureRootIsScheduled(root);
24070 return null;
24071 } // Determine the next expiration time to work on, using the fields stored
24072 // on the root.
24073
24074
24075 var expirationTime = getNextRootExpirationTimeToWorkOn(root);
24076
24077 if (expirationTime !== NoWork) {
24078 var originalCallbackNode = root.callbackNode;
24079
24080 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
24081 {
24082 throw Error("Should not already be working.");
24083 }
24084 }
24085
24086 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
24087 // and prepare a fresh one. Otherwise we'll continue where we left off.
24088
24089 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
24090 prepareFreshStack(root, expirationTime);
24091 startWorkOnPendingInteractions(root, expirationTime);
24092 } // If we have a work-in-progress fiber, it means there's still work to do
24093 // in this root.
24094
24095
24096 if (workInProgress !== null) {
24097 var prevExecutionContext = executionContext;
24098 executionContext |= RenderContext;
24099 var prevDispatcher = pushDispatcher(root);
24100 var prevInteractions = pushInteractions(root);
24101 startWorkLoopTimer(workInProgress);
24102
24103 do {
24104 try {
24105 workLoopConcurrent();
24106 break;
24107 } catch (thrownValue) {
24108 handleError(root, thrownValue);
24109 }
24110 } while (true);
24111
24112 resetContextDependencies();
24113 executionContext = prevExecutionContext;
24114 popDispatcher(prevDispatcher);
24115
24116 if (enableSchedulerTracing) {
24117 popInteractions(prevInteractions);
24118 }
24119
24120 if (workInProgressRootExitStatus === RootFatalErrored) {
24121 var fatalError = workInProgressRootFatalError;
24122 stopInterruptedWorkLoopTimer();
24123 prepareFreshStack(root, expirationTime);
24124 markRootSuspendedAtTime(root, expirationTime);
24125 ensureRootIsScheduled(root);
24126 throw fatalError;
24127 }
24128
24129 if (workInProgress !== null) {
24130 // There's still work left over. Exit without committing.
24131 stopInterruptedWorkLoopTimer();
24132 } else {
24133 // We now have a consistent tree. The next step is either to commit it,
24134 // or, if something suspended, wait to commit it after a timeout.
24135 stopFinishedWorkLoopTimer();
24136 var finishedWork = root.finishedWork = root.current.alternate;
24137 root.finishedExpirationTime = expirationTime;
24138 finishConcurrentRender(root, finishedWork, workInProgressRootExitStatus, expirationTime);
24139 }
24140
24141 ensureRootIsScheduled(root);
24142
24143 if (root.callbackNode === originalCallbackNode) {
24144 // The task node scheduled for this root is the same one that's
24145 // currently executed. Need to return a continuation.
24146 return performConcurrentWorkOnRoot.bind(null, root);
24147 }
24148 }
24149 }
24150
24151 return null;
24152}
24153
24154function finishConcurrentRender(root, finishedWork, exitStatus, expirationTime) {
24155 // Set this to null to indicate there's no in-progress render.
24156 workInProgressRoot = null;
24157
24158 switch (exitStatus) {
24159 case RootIncomplete:
24160 case RootFatalErrored:
24161 {
24162 {
24163 {
24164 throw Error("Root did not complete. This is a bug in React.");
24165 }
24166 }
24167 }
24168 // Flow knows about invariant, so it complains if I add a break
24169 // statement, but eslint doesn't know about invariant, so it complains
24170 // if I do. eslint-disable-next-line no-fallthrough
24171
24172 case RootErrored:
24173 {
24174 // If this was an async render, the error may have happened due to
24175 // a mutation in a concurrent event. Try rendering one more time,
24176 // synchronously, to see if the error goes away. If there are
24177 // lower priority updates, let's include those, too, in case they
24178 // fix the inconsistency. Render at Idle to include all updates.
24179 // If it was Idle or Never or some not-yet-invented time, render
24180 // at that time.
24181 markRootExpiredAtTime(root, expirationTime > Idle ? Idle : expirationTime); // We assume that this second render pass will be synchronous
24182 // and therefore not hit this path again.
24183
24184 break;
24185 }
24186
24187 case RootSuspended:
24188 {
24189 markRootSuspendedAtTime(root, expirationTime);
24190 var lastSuspendedTime = root.lastSuspendedTime;
24191
24192 if (expirationTime === lastSuspendedTime) {
24193 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
24194 }
24195
24196 flushSuspensePriorityWarningInDEV(); // We have an acceptable loading state. We need to figure out if we
24197 // should immediately commit it or wait a bit.
24198 // If we have processed new updates during this render, we may now
24199 // have a new loading state ready. We want to ensure that we commit
24200 // that as soon as possible.
24201
24202 var hasNotProcessedNewUpdates = workInProgressRootLatestProcessedExpirationTime === Sync;
24203
24204 if (hasNotProcessedNewUpdates && // do not delay if we're inside an act() scope
24205 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
24206 // If we have not processed any new updates during this pass, then
24207 // this is either a retry of an existing fallback state or a
24208 // hidden tree. Hidden trees shouldn't be batched with other work
24209 // and after that's fixed it can only be a retry. We're going to
24210 // throttle committing retries so that we don't show too many
24211 // loading states too quickly.
24212 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
24213
24214 if (msUntilTimeout > 10) {
24215 if (workInProgressRootHasPendingPing) {
24216 var lastPingedTime = root.lastPingedTime;
24217
24218 if (lastPingedTime === NoWork || lastPingedTime >= expirationTime) {
24219 // This render was pinged but we didn't get to restart
24220 // earlier so try restarting now instead.
24221 root.lastPingedTime = expirationTime;
24222 prepareFreshStack(root, expirationTime);
24223 break;
24224 }
24225 }
24226
24227 var nextTime = getNextRootExpirationTimeToWorkOn(root);
24228
24229 if (nextTime !== NoWork && nextTime !== expirationTime) {
24230 // There's additional work on this root.
24231 break;
24232 }
24233
24234 if (lastSuspendedTime !== NoWork && lastSuspendedTime !== expirationTime) {
24235 // We should prefer to render the fallback of at the last
24236 // suspended level. Ping the last suspended level to try
24237 // rendering it again.
24238 root.lastPingedTime = lastSuspendedTime;
24239 break;
24240 } // The render is suspended, it hasn't timed out, and there's no
24241 // lower priority work to do. Instead of committing the fallback
24242 // immediately, wait for more data to arrive.
24243
24244
24245 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), msUntilTimeout);
24246 break;
24247 }
24248 } // The work expired. Commit immediately.
24249
24250
24251 commitRoot(root);
24252 break;
24253 }
24254
24255 case RootSuspendedWithDelay:
24256 {
24257 markRootSuspendedAtTime(root, expirationTime);
24258 var _lastSuspendedTime = root.lastSuspendedTime;
24259
24260 if (expirationTime === _lastSuspendedTime) {
24261 root.nextKnownPendingLevel = getRemainingExpirationTime(finishedWork);
24262 }
24263
24264 flushSuspensePriorityWarningInDEV();
24265
24266 if ( // do not delay if we're inside an act() scope
24267 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current)) {
24268 // We're suspended in a state that should be avoided. We'll try to
24269 // avoid committing it for as long as the timeouts let us.
24270 if (workInProgressRootHasPendingPing) {
24271 var _lastPingedTime = root.lastPingedTime;
24272
24273 if (_lastPingedTime === NoWork || _lastPingedTime >= expirationTime) {
24274 // This render was pinged but we didn't get to restart earlier
24275 // so try restarting now instead.
24276 root.lastPingedTime = expirationTime;
24277 prepareFreshStack(root, expirationTime);
24278 break;
24279 }
24280 }
24281
24282 var _nextTime = getNextRootExpirationTimeToWorkOn(root);
24283
24284 if (_nextTime !== NoWork && _nextTime !== expirationTime) {
24285 // There's additional work on this root.
24286 break;
24287 }
24288
24289 if (_lastSuspendedTime !== NoWork && _lastSuspendedTime !== expirationTime) {
24290 // We should prefer to render the fallback of at the last
24291 // suspended level. Ping the last suspended level to try
24292 // rendering it again.
24293 root.lastPingedTime = _lastSuspendedTime;
24294 break;
24295 }
24296
24297 var _msUntilTimeout;
24298
24299 if (workInProgressRootLatestSuspenseTimeout !== Sync) {
24300 // We have processed a suspense config whose expiration time we
24301 // can use as the timeout.
24302 _msUntilTimeout = expirationTimeToMs(workInProgressRootLatestSuspenseTimeout) - now();
24303 } else if (workInProgressRootLatestProcessedExpirationTime === Sync) {
24304 // This should never normally happen because only new updates
24305 // cause delayed states, so we should have processed something.
24306 // However, this could also happen in an offscreen tree.
24307 _msUntilTimeout = 0;
24308 } else {
24309 // If we don't have a suspense config, we're going to use a
24310 // heuristic to determine how long we can suspend.
24311 var eventTimeMs = inferTimeFromExpirationTime(workInProgressRootLatestProcessedExpirationTime);
24312 var currentTimeMs = now();
24313 var timeUntilExpirationMs = expirationTimeToMs(expirationTime) - currentTimeMs;
24314 var timeElapsed = currentTimeMs - eventTimeMs;
24315
24316 if (timeElapsed < 0) {
24317 // We get this wrong some time since we estimate the time.
24318 timeElapsed = 0;
24319 }
24320
24321 _msUntilTimeout = jnd(timeElapsed) - timeElapsed; // Clamp the timeout to the expiration time. TODO: Once the
24322 // event time is exact instead of inferred from expiration time
24323 // we don't need this.
24324
24325 if (timeUntilExpirationMs < _msUntilTimeout) {
24326 _msUntilTimeout = timeUntilExpirationMs;
24327 }
24328 } // Don't bother with a very short suspense time.
24329
24330
24331 if (_msUntilTimeout > 10) {
24332 // The render is suspended, it hasn't timed out, and there's no
24333 // lower priority work to do. Instead of committing the fallback
24334 // immediately, wait for more data to arrive.
24335 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout);
24336 break;
24337 }
24338 } // The work expired. Commit immediately.
24339
24340
24341 commitRoot(root);
24342 break;
24343 }
24344
24345 case RootCompleted:
24346 {
24347 // The work completed. Ready to commit.
24348 if ( // do not delay if we're inside an act() scope
24349 !(true && flushSuspenseFallbacksInTests && IsThisRendererActing.current) && workInProgressRootLatestProcessedExpirationTime !== Sync && workInProgressRootCanSuspendUsingConfig !== null) {
24350 // If we have exceeded the minimum loading delay, which probably
24351 // means we have shown a spinner already, we might have to suspend
24352 // a bit longer to ensure that the spinner is shown for
24353 // enough time.
24354 var _msUntilTimeout2 = computeMsUntilSuspenseLoadingDelay(workInProgressRootLatestProcessedExpirationTime, expirationTime, workInProgressRootCanSuspendUsingConfig);
24355
24356 if (_msUntilTimeout2 > 10) {
24357 markRootSuspendedAtTime(root, expirationTime);
24358 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root), _msUntilTimeout2);
24359 break;
24360 }
24361 }
24362
24363 commitRoot(root);
24364 break;
24365 }
24366
24367 default:
24368 {
24369 {
24370 {
24371 throw Error("Unknown root exit status.");
24372 }
24373 }
24374 }
24375 }
24376} // This is the entry point for synchronous tasks that don't go
24377// through Scheduler
24378
24379
24380function performSyncWorkOnRoot(root) {
24381 // Check if there's expired work on this root. Otherwise, render at Sync.
24382 var lastExpiredTime = root.lastExpiredTime;
24383 var expirationTime = lastExpiredTime !== NoWork ? lastExpiredTime : Sync;
24384
24385 if (root.finishedExpirationTime === expirationTime) {
24386 // There's already a pending commit at this expiration time.
24387 // TODO: This is poorly factored. This case only exists for the
24388 // batch.commit() API.
24389 commitRoot(root);
24390 } else {
24391 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
24392 {
24393 throw Error("Should not already be working.");
24394 }
24395 }
24396
24397 flushPassiveEffects(); // If the root or expiration time have changed, throw out the existing stack
24398 // and prepare a fresh one. Otherwise we'll continue where we left off.
24399
24400 if (root !== workInProgressRoot || expirationTime !== renderExpirationTime) {
24401 prepareFreshStack(root, expirationTime);
24402 startWorkOnPendingInteractions(root, expirationTime);
24403 } // If we have a work-in-progress fiber, it means there's still work to do
24404 // in this root.
24405
24406
24407 if (workInProgress !== null) {
24408 var prevExecutionContext = executionContext;
24409 executionContext |= RenderContext;
24410 var prevDispatcher = pushDispatcher(root);
24411 var prevInteractions = pushInteractions(root);
24412 startWorkLoopTimer(workInProgress);
24413
24414 do {
24415 try {
24416 workLoopSync();
24417 break;
24418 } catch (thrownValue) {
24419 handleError(root, thrownValue);
24420 }
24421 } while (true);
24422
24423 resetContextDependencies();
24424 executionContext = prevExecutionContext;
24425 popDispatcher(prevDispatcher);
24426
24427 if (enableSchedulerTracing) {
24428 popInteractions(prevInteractions);
24429 }
24430
24431 if (workInProgressRootExitStatus === RootFatalErrored) {
24432 var fatalError = workInProgressRootFatalError;
24433 stopInterruptedWorkLoopTimer();
24434 prepareFreshStack(root, expirationTime);
24435 markRootSuspendedAtTime(root, expirationTime);
24436 ensureRootIsScheduled(root);
24437 throw fatalError;
24438 }
24439
24440 if (workInProgress !== null) {
24441 // This is a sync render, so we should have finished the whole tree.
24442 {
24443 {
24444 throw Error("Cannot commit an incomplete root. This error is likely caused by a bug in React. Please file an issue.");
24445 }
24446 }
24447 } else {
24448 // We now have a consistent tree. Because this is a sync render, we
24449 // will commit it even if something suspended.
24450 stopFinishedWorkLoopTimer();
24451 root.finishedWork = root.current.alternate;
24452 root.finishedExpirationTime = expirationTime;
24453 finishSyncRender(root, workInProgressRootExitStatus, expirationTime);
24454 } // Before exiting, make sure there's a callback scheduled for the next
24455 // pending level.
24456
24457
24458 ensureRootIsScheduled(root);
24459 }
24460 }
24461
24462 return null;
24463}
24464
24465function finishSyncRender(root, exitStatus, expirationTime) {
24466 // Set this to null to indicate there's no in-progress render.
24467 workInProgressRoot = null;
24468
24469 {
24470 if (exitStatus === RootSuspended || exitStatus === RootSuspendedWithDelay) {
24471 flushSuspensePriorityWarningInDEV();
24472 }
24473 }
24474
24475 commitRoot(root);
24476}
24477
24478function flushRoot(root, expirationTime) {
24479 markRootExpiredAtTime(root, expirationTime);
24480 ensureRootIsScheduled(root);
24481
24482 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
24483 flushSyncCallbackQueue();
24484 }
24485}
24486function flushDiscreteUpdates() {
24487 // TODO: Should be able to flush inside batchedUpdates, but not inside `act`.
24488 // However, `act` uses `batchedUpdates`, so there's no way to distinguish
24489 // those two cases. Need to fix this before exposing flushDiscreteUpdates
24490 // as a public API.
24491 if ((executionContext & (BatchedContext | RenderContext | CommitContext)) !== NoContext) {
24492 if (true && (executionContext & RenderContext) !== NoContext) {
24493 warning$1(false, 'unstable_flushDiscreteUpdates: Cannot flush updates when React is ' + 'already rendering.');
24494 } // We're already rendering, so we can't synchronously flush pending work.
24495 // This is probably a nested event dispatch triggered by a lifecycle/effect,
24496 // like `el.focus()`. Exit.
24497
24498
24499 return;
24500 }
24501
24502 flushPendingDiscreteUpdates(); // If the discrete updates scheduled passive effects, flush them now so that
24503 // they fire before the next serial event.
24504
24505 flushPassiveEffects();
24506}
24507
24508function syncUpdates(fn, a, b, c) {
24509 return runWithPriority$2(ImmediatePriority, fn.bind(null, a, b, c));
24510}
24511
24512function flushPendingDiscreteUpdates() {
24513 if (rootsWithPendingDiscreteUpdates !== null) {
24514 // For each root with pending discrete updates, schedule a callback to
24515 // immediately flush them.
24516 var roots = rootsWithPendingDiscreteUpdates;
24517 rootsWithPendingDiscreteUpdates = null;
24518 roots.forEach(function (expirationTime, root) {
24519 markRootExpiredAtTime(root, expirationTime);
24520 ensureRootIsScheduled(root);
24521 }); // Now flush the immediate queue.
24522
24523 flushSyncCallbackQueue();
24524 }
24525}
24526
24527function batchedUpdates$1(fn, a) {
24528 var prevExecutionContext = executionContext;
24529 executionContext |= BatchedContext;
24530
24531 try {
24532 return fn(a);
24533 } finally {
24534 executionContext = prevExecutionContext;
24535
24536 if (executionContext === NoContext) {
24537 // Flush the immediate callbacks that were scheduled during this batch
24538 flushSyncCallbackQueue();
24539 }
24540 }
24541}
24542function batchedEventUpdates$1(fn, a) {
24543 var prevExecutionContext = executionContext;
24544 executionContext |= EventContext;
24545
24546 try {
24547 return fn(a);
24548 } finally {
24549 executionContext = prevExecutionContext;
24550
24551 if (executionContext === NoContext) {
24552 // Flush the immediate callbacks that were scheduled during this batch
24553 flushSyncCallbackQueue();
24554 }
24555 }
24556}
24557function discreteUpdates$1(fn, a, b, c) {
24558 var prevExecutionContext = executionContext;
24559 executionContext |= DiscreteEventContext;
24560
24561 try {
24562 // Should this
24563 return runWithPriority$2(UserBlockingPriority$2, fn.bind(null, a, b, c));
24564 } finally {
24565 executionContext = prevExecutionContext;
24566
24567 if (executionContext === NoContext) {
24568 // Flush the immediate callbacks that were scheduled during this batch
24569 flushSyncCallbackQueue();
24570 }
24571 }
24572}
24573function unbatchedUpdates(fn, a) {
24574 var prevExecutionContext = executionContext;
24575 executionContext &= ~BatchedContext;
24576 executionContext |= LegacyUnbatchedContext;
24577
24578 try {
24579 return fn(a);
24580 } finally {
24581 executionContext = prevExecutionContext;
24582
24583 if (executionContext === NoContext) {
24584 // Flush the immediate callbacks that were scheduled during this batch
24585 flushSyncCallbackQueue();
24586 }
24587 }
24588}
24589function flushSync(fn, a) {
24590 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
24591 {
24592 {
24593 throw Error("flushSync was called from inside a lifecycle method. It cannot be called when React is already rendering.");
24594 }
24595 }
24596 }
24597
24598 var prevExecutionContext = executionContext;
24599 executionContext |= BatchedContext;
24600
24601 try {
24602 return runWithPriority$2(ImmediatePriority, fn.bind(null, a));
24603 } finally {
24604 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
24605 // Note that this will happen even if batchedUpdates is higher up
24606 // the stack.
24607
24608 flushSyncCallbackQueue();
24609 }
24610}
24611function flushControlled(fn) {
24612 var prevExecutionContext = executionContext;
24613 executionContext |= BatchedContext;
24614
24615 try {
24616 runWithPriority$2(ImmediatePriority, fn);
24617 } finally {
24618 executionContext = prevExecutionContext;
24619
24620 if (executionContext === NoContext) {
24621 // Flush the immediate callbacks that were scheduled during this batch
24622 flushSyncCallbackQueue();
24623 }
24624 }
24625}
24626
24627function prepareFreshStack(root, expirationTime) {
24628 root.finishedWork = null;
24629 root.finishedExpirationTime = NoWork;
24630 var timeoutHandle = root.timeoutHandle;
24631
24632 if (timeoutHandle !== noTimeout) {
24633 // The root previous suspended and scheduled a timeout to commit a fallback
24634 // state. Now that we have additional work, cancel the timeout.
24635 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
24636
24637 cancelTimeout(timeoutHandle);
24638 }
24639
24640 if (workInProgress !== null) {
24641 var interruptedWork = workInProgress.return;
24642
24643 while (interruptedWork !== null) {
24644 unwindInterruptedWork(interruptedWork);
24645 interruptedWork = interruptedWork.return;
24646 }
24647 }
24648
24649 workInProgressRoot = root;
24650 workInProgress = createWorkInProgress(root.current, null, expirationTime);
24651 renderExpirationTime = expirationTime;
24652 workInProgressRootExitStatus = RootIncomplete;
24653 workInProgressRootFatalError = null;
24654 workInProgressRootLatestProcessedExpirationTime = Sync;
24655 workInProgressRootLatestSuspenseTimeout = Sync;
24656 workInProgressRootCanSuspendUsingConfig = null;
24657 workInProgressRootNextUnprocessedUpdateTime = NoWork;
24658 workInProgressRootHasPendingPing = false;
24659
24660 if (enableSchedulerTracing) {
24661 spawnedWorkDuringRender = null;
24662 }
24663
24664 {
24665 ReactStrictModeWarnings.discardPendingWarnings();
24666 componentsThatTriggeredHighPriSuspend = null;
24667 }
24668}
24669
24670function handleError(root, thrownValue) {
24671 do {
24672 try {
24673 // Reset module-level state that was set during the render phase.
24674 resetContextDependencies();
24675 resetHooks();
24676 resetCurrentFiber();
24677
24678 if (workInProgress === null || workInProgress.return === null) {
24679 // Expected to be working on a non-root fiber. This is a fatal error
24680 // because there's no ancestor that can handle it; the root is
24681 // supposed to capture all errors that weren't caught by an error
24682 // boundary.
24683 workInProgressRootExitStatus = RootFatalErrored;
24684 workInProgressRootFatalError = thrownValue;
24685 return null;
24686 }
24687
24688 if (enableProfilerTimer && workInProgress.mode & ProfileMode) {
24689 // Record the time spent rendering before an error was thrown. This
24690 // avoids inaccurate Profiler durations in the case of a
24691 // suspended render.
24692 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, true);
24693 }
24694
24695 throwException(root, workInProgress.return, workInProgress, thrownValue, renderExpirationTime);
24696 workInProgress = completeUnitOfWork(workInProgress);
24697 } catch (yetAnotherThrownValue) {
24698 // Something in the return path also threw.
24699 thrownValue = yetAnotherThrownValue;
24700 continue;
24701 } // Return to the normal work loop.
24702
24703
24704 return;
24705 } while (true);
24706}
24707
24708function pushDispatcher(root) {
24709 var prevDispatcher = ReactCurrentDispatcher.current;
24710 ReactCurrentDispatcher.current = ContextOnlyDispatcher;
24711
24712 if (prevDispatcher === null) {
24713 // The React isomorphic package does not include a default dispatcher.
24714 // Instead the first renderer will lazily attach one, in order to give
24715 // nicer error messages.
24716 return ContextOnlyDispatcher;
24717 } else {
24718 return prevDispatcher;
24719 }
24720}
24721
24722function popDispatcher(prevDispatcher) {
24723 ReactCurrentDispatcher.current = prevDispatcher;
24724}
24725
24726function pushInteractions(root) {
24727 if (enableSchedulerTracing) {
24728 var prevInteractions = __interactionsRef.current;
24729 __interactionsRef.current = root.memoizedInteractions;
24730 return prevInteractions;
24731 }
24732
24733 return null;
24734}
24735
24736function popInteractions(prevInteractions) {
24737 if (enableSchedulerTracing) {
24738 __interactionsRef.current = prevInteractions;
24739 }
24740}
24741
24742function markCommitTimeOfFallback() {
24743 globalMostRecentFallbackTime = now();
24744}
24745function markRenderEventTimeAndConfig(expirationTime, suspenseConfig) {
24746 if (expirationTime < workInProgressRootLatestProcessedExpirationTime && expirationTime > Idle) {
24747 workInProgressRootLatestProcessedExpirationTime = expirationTime;
24748 }
24749
24750 if (suspenseConfig !== null) {
24751 if (expirationTime < workInProgressRootLatestSuspenseTimeout && expirationTime > Idle) {
24752 workInProgressRootLatestSuspenseTimeout = expirationTime; // Most of the time we only have one config and getting wrong is not bad.
24753
24754 workInProgressRootCanSuspendUsingConfig = suspenseConfig;
24755 }
24756 }
24757}
24758function markUnprocessedUpdateTime(expirationTime) {
24759 if (expirationTime > workInProgressRootNextUnprocessedUpdateTime) {
24760 workInProgressRootNextUnprocessedUpdateTime = expirationTime;
24761 }
24762}
24763function renderDidSuspend() {
24764 if (workInProgressRootExitStatus === RootIncomplete) {
24765 workInProgressRootExitStatus = RootSuspended;
24766 }
24767}
24768function renderDidSuspendDelayIfPossible() {
24769 if (workInProgressRootExitStatus === RootIncomplete || workInProgressRootExitStatus === RootSuspended) {
24770 workInProgressRootExitStatus = RootSuspendedWithDelay;
24771 } // Check if there's a lower priority update somewhere else in the tree.
24772
24773
24774 if (workInProgressRootNextUnprocessedUpdateTime !== NoWork && workInProgressRoot !== null) {
24775 // Mark the current render as suspended, and then mark that there's a
24776 // pending update.
24777 // TODO: This should immediately interrupt the current render, instead
24778 // of waiting until the next time we yield.
24779 markRootSuspendedAtTime(workInProgressRoot, renderExpirationTime);
24780 markRootUpdatedAtTime(workInProgressRoot, workInProgressRootNextUnprocessedUpdateTime);
24781 }
24782}
24783function renderDidError() {
24784 if (workInProgressRootExitStatus !== RootCompleted) {
24785 workInProgressRootExitStatus = RootErrored;
24786 }
24787} // Called during render to determine if anything has suspended.
24788// Returns false if we're not sure.
24789
24790function renderHasNotSuspendedYet() {
24791 // If something errored or completed, we can't really be sure,
24792 // so those are false.
24793 return workInProgressRootExitStatus === RootIncomplete;
24794}
24795
24796function inferTimeFromExpirationTime(expirationTime) {
24797 // We don't know exactly when the update was scheduled, but we can infer an
24798 // approximate start time from the expiration time.
24799 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
24800 return earliestExpirationTimeMs - LOW_PRIORITY_EXPIRATION;
24801}
24802
24803function inferTimeFromExpirationTimeWithSuspenseConfig(expirationTime, suspenseConfig) {
24804 // We don't know exactly when the update was scheduled, but we can infer an
24805 // approximate start time from the expiration time by subtracting the timeout
24806 // that was added to the event time.
24807 var earliestExpirationTimeMs = expirationTimeToMs(expirationTime);
24808 return earliestExpirationTimeMs - (suspenseConfig.timeoutMs | 0 || LOW_PRIORITY_EXPIRATION);
24809} // The work loop is an extremely hot path. Tell Closure not to inline it.
24810
24811/** @noinline */
24812
24813
24814function workLoopSync() {
24815 // Already timed out, so perform work without checking if we need to yield.
24816 while (workInProgress !== null) {
24817 workInProgress = performUnitOfWork(workInProgress);
24818 }
24819}
24820/** @noinline */
24821
24822
24823function workLoopConcurrent() {
24824 // Perform work until Scheduler asks us to yield
24825 while (workInProgress !== null && !shouldYield()) {
24826 workInProgress = performUnitOfWork(workInProgress);
24827 }
24828}
24829
24830function performUnitOfWork(unitOfWork) {
24831 // The current, flushed, state of this fiber is the alternate. Ideally
24832 // nothing should rely on this, but relying on it here means that we don't
24833 // need an additional field on the work in progress.
24834 var current$$1 = unitOfWork.alternate;
24835 startWorkTimer(unitOfWork);
24836 setCurrentFiber(unitOfWork);
24837 var next;
24838
24839 if (enableProfilerTimer && (unitOfWork.mode & ProfileMode) !== NoMode) {
24840 startProfilerTimer(unitOfWork);
24841 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
24842 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
24843 } else {
24844 next = beginWork$$1(current$$1, unitOfWork, renderExpirationTime);
24845 }
24846
24847 resetCurrentFiber();
24848 unitOfWork.memoizedProps = unitOfWork.pendingProps;
24849
24850 if (next === null) {
24851 // If this doesn't spawn new work, complete the current work.
24852 next = completeUnitOfWork(unitOfWork);
24853 }
24854
24855 ReactCurrentOwner$2.current = null;
24856 return next;
24857}
24858
24859function completeUnitOfWork(unitOfWork) {
24860 // Attempt to complete the current unit of work, then move to the next
24861 // sibling. If there are no more siblings, return to the parent fiber.
24862 workInProgress = unitOfWork;
24863
24864 do {
24865 // The current, flushed, state of this fiber is the alternate. Ideally
24866 // nothing should rely on this, but relying on it here means that we don't
24867 // need an additional field on the work in progress.
24868 var current$$1 = workInProgress.alternate;
24869 var returnFiber = workInProgress.return; // Check if the work completed or if something threw.
24870
24871 if ((workInProgress.effectTag & Incomplete) === NoEffect) {
24872 setCurrentFiber(workInProgress);
24873 var next = void 0;
24874
24875 if (!enableProfilerTimer || (workInProgress.mode & ProfileMode) === NoMode) {
24876 next = completeWork(current$$1, workInProgress, renderExpirationTime);
24877 } else {
24878 startProfilerTimer(workInProgress);
24879 next = completeWork(current$$1, workInProgress, renderExpirationTime); // Update render duration assuming we didn't error.
24880
24881 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false);
24882 }
24883
24884 stopWorkTimer(workInProgress);
24885 resetCurrentFiber();
24886 resetChildExpirationTime(workInProgress);
24887
24888 if (next !== null) {
24889 // Completing this fiber spawned new work. Work on that next.
24890 return next;
24891 }
24892
24893 if (returnFiber !== null && // Do not append effects to parents if a sibling failed to complete
24894 (returnFiber.effectTag & Incomplete) === NoEffect) {
24895 // Append all the effects of the subtree and this fiber onto the effect
24896 // list of the parent. The completion order of the children affects the
24897 // side-effect order.
24898 if (returnFiber.firstEffect === null) {
24899 returnFiber.firstEffect = workInProgress.firstEffect;
24900 }
24901
24902 if (workInProgress.lastEffect !== null) {
24903 if (returnFiber.lastEffect !== null) {
24904 returnFiber.lastEffect.nextEffect = workInProgress.firstEffect;
24905 }
24906
24907 returnFiber.lastEffect = workInProgress.lastEffect;
24908 } // If this fiber had side-effects, we append it AFTER the children's
24909 // side-effects. We can perform certain side-effects earlier if needed,
24910 // by doing multiple passes over the effect list. We don't want to
24911 // schedule our own side-effect on our own list because if end up
24912 // reusing children we'll schedule this effect onto itself since we're
24913 // at the end.
24914
24915
24916 var effectTag = workInProgress.effectTag; // Skip both NoWork and PerformedWork tags when creating the effect
24917 // list. PerformedWork effect is read by React DevTools but shouldn't be
24918 // committed.
24919
24920 if (effectTag > PerformedWork) {
24921 if (returnFiber.lastEffect !== null) {
24922 returnFiber.lastEffect.nextEffect = workInProgress;
24923 } else {
24924 returnFiber.firstEffect = workInProgress;
24925 }
24926
24927 returnFiber.lastEffect = workInProgress;
24928 }
24929 }
24930 } else {
24931 // This fiber did not complete because something threw. Pop values off
24932 // the stack without entering the complete phase. If this is a boundary,
24933 // capture values if possible.
24934 var _next = unwindWork(workInProgress, renderExpirationTime); // Because this fiber did not complete, don't reset its expiration time.
24935
24936
24937 if (enableProfilerTimer && (workInProgress.mode & ProfileMode) !== NoMode) {
24938 // Record the render duration for the fiber that errored.
24939 stopProfilerTimerIfRunningAndRecordDelta(workInProgress, false); // Include the time spent working on failed children before continuing.
24940
24941 var actualDuration = workInProgress.actualDuration;
24942 var child = workInProgress.child;
24943
24944 while (child !== null) {
24945 actualDuration += child.actualDuration;
24946 child = child.sibling;
24947 }
24948
24949 workInProgress.actualDuration = actualDuration;
24950 }
24951
24952 if (_next !== null) {
24953 // If completing this work spawned new work, do that next. We'll come
24954 // back here again.
24955 // Since we're restarting, remove anything that is not a host effect
24956 // from the effect tag.
24957 // TODO: The name stopFailedWorkTimer is misleading because Suspense
24958 // also captures and restarts.
24959 stopFailedWorkTimer(workInProgress);
24960 _next.effectTag &= HostEffectMask;
24961 return _next;
24962 }
24963
24964 stopWorkTimer(workInProgress);
24965
24966 if (returnFiber !== null) {
24967 // Mark the parent fiber as incomplete and clear its effect list.
24968 returnFiber.firstEffect = returnFiber.lastEffect = null;
24969 returnFiber.effectTag |= Incomplete;
24970 }
24971 }
24972
24973 var siblingFiber = workInProgress.sibling;
24974
24975 if (siblingFiber !== null) {
24976 // If there is more work to do in this returnFiber, do that next.
24977 return siblingFiber;
24978 } // Otherwise, return to the parent
24979
24980
24981 workInProgress = returnFiber;
24982 } while (workInProgress !== null); // We've reached the root.
24983
24984
24985 if (workInProgressRootExitStatus === RootIncomplete) {
24986 workInProgressRootExitStatus = RootCompleted;
24987 }
24988
24989 return null;
24990}
24991
24992function getRemainingExpirationTime(fiber) {
24993 var updateExpirationTime = fiber.expirationTime;
24994 var childExpirationTime = fiber.childExpirationTime;
24995 return updateExpirationTime > childExpirationTime ? updateExpirationTime : childExpirationTime;
24996}
24997
24998function resetChildExpirationTime(completedWork) {
24999 if (renderExpirationTime !== Never && completedWork.childExpirationTime === Never) {
25000 // The children of this component are hidden. Don't bubble their
25001 // expiration times.
25002 return;
25003 }
25004
25005 var newChildExpirationTime = NoWork; // Bubble up the earliest expiration time.
25006
25007 if (enableProfilerTimer && (completedWork.mode & ProfileMode) !== NoMode) {
25008 // In profiling mode, resetChildExpirationTime is also used to reset
25009 // profiler durations.
25010 var actualDuration = completedWork.actualDuration;
25011 var treeBaseDuration = completedWork.selfBaseDuration; // When a fiber is cloned, its actualDuration is reset to 0. This value will
25012 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
25013 // When work is done, it should bubble to the parent's actualDuration. If
25014 // the fiber has not been cloned though, (meaning no work was done), then
25015 // this value will reflect the amount of time spent working on a previous
25016 // render. In that case it should not bubble. We determine whether it was
25017 // cloned by comparing the child pointer.
25018
25019 var shouldBubbleActualDurations = completedWork.alternate === null || completedWork.child !== completedWork.alternate.child;
25020 var child = completedWork.child;
25021
25022 while (child !== null) {
25023 var childUpdateExpirationTime = child.expirationTime;
25024 var childChildExpirationTime = child.childExpirationTime;
25025
25026 if (childUpdateExpirationTime > newChildExpirationTime) {
25027 newChildExpirationTime = childUpdateExpirationTime;
25028 }
25029
25030 if (childChildExpirationTime > newChildExpirationTime) {
25031 newChildExpirationTime = childChildExpirationTime;
25032 }
25033
25034 if (shouldBubbleActualDurations) {
25035 actualDuration += child.actualDuration;
25036 }
25037
25038 treeBaseDuration += child.treeBaseDuration;
25039 child = child.sibling;
25040 }
25041
25042 completedWork.actualDuration = actualDuration;
25043 completedWork.treeBaseDuration = treeBaseDuration;
25044 } else {
25045 var _child = completedWork.child;
25046
25047 while (_child !== null) {
25048 var _childUpdateExpirationTime = _child.expirationTime;
25049 var _childChildExpirationTime = _child.childExpirationTime;
25050
25051 if (_childUpdateExpirationTime > newChildExpirationTime) {
25052 newChildExpirationTime = _childUpdateExpirationTime;
25053 }
25054
25055 if (_childChildExpirationTime > newChildExpirationTime) {
25056 newChildExpirationTime = _childChildExpirationTime;
25057 }
25058
25059 _child = _child.sibling;
25060 }
25061 }
25062
25063 completedWork.childExpirationTime = newChildExpirationTime;
25064}
25065
25066function commitRoot(root) {
25067 var renderPriorityLevel = getCurrentPriorityLevel();
25068 runWithPriority$2(ImmediatePriority, commitRootImpl.bind(null, root, renderPriorityLevel));
25069 return null;
25070}
25071
25072function commitRootImpl(root, renderPriorityLevel) {
25073 do {
25074 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
25075 // means `flushPassiveEffects` will sometimes result in additional
25076 // passive effects. So we need to keep flushing in a loop until there are
25077 // no more pending effects.
25078 // TODO: Might be better if `flushPassiveEffects` did not automatically
25079 // flush synchronous work at the end, to avoid factoring hazards like this.
25080 flushPassiveEffects();
25081 } while (rootWithPendingPassiveEffects !== null);
25082
25083 flushRenderPhaseStrictModeWarningsInDEV();
25084
25085 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
25086 {
25087 throw Error("Should not already be working.");
25088 }
25089 }
25090
25091 var finishedWork = root.finishedWork;
25092 var expirationTime = root.finishedExpirationTime;
25093
25094 if (finishedWork === null) {
25095 return null;
25096 }
25097
25098 root.finishedWork = null;
25099 root.finishedExpirationTime = NoWork;
25100
25101 if (!(finishedWork !== root.current)) {
25102 {
25103 throw Error("Cannot commit the same tree as before. This error is likely caused by a bug in React. Please file an issue.");
25104 }
25105 } // commitRoot never returns a continuation; it always finishes synchronously.
25106 // So we can clear these now to allow a new callback to be scheduled.
25107
25108
25109 root.callbackNode = null;
25110 root.callbackExpirationTime = NoWork;
25111 root.callbackPriority = NoPriority;
25112 root.nextKnownPendingLevel = NoWork;
25113 startCommitTimer(); // Update the first and last pending times on this root. The new first
25114 // pending time is whatever is left on the root fiber.
25115
25116 var remainingExpirationTimeBeforeCommit = getRemainingExpirationTime(finishedWork);
25117 markRootFinishedAtTime(root, expirationTime, remainingExpirationTimeBeforeCommit);
25118
25119 if (root === workInProgressRoot) {
25120 // We can reset these now that they are finished.
25121 workInProgressRoot = null;
25122 workInProgress = null;
25123 renderExpirationTime = NoWork;
25124 } else {} // This indicates that the last root we worked on is not the same one that
25125 // we're committing now. This most commonly happens when a suspended root
25126 // times out.
25127 // Get the list of effects.
25128
25129
25130 var firstEffect;
25131
25132 if (finishedWork.effectTag > PerformedWork) {
25133 // A fiber's effect list consists only of its children, not itself. So if
25134 // the root has an effect, we need to add it to the end of the list. The
25135 // resulting list is the set that would belong to the root's parent, if it
25136 // had one; that is, all the effects in the tree including the root.
25137 if (finishedWork.lastEffect !== null) {
25138 finishedWork.lastEffect.nextEffect = finishedWork;
25139 firstEffect = finishedWork.firstEffect;
25140 } else {
25141 firstEffect = finishedWork;
25142 }
25143 } else {
25144 // There is no effect on the root.
25145 firstEffect = finishedWork.firstEffect;
25146 }
25147
25148 if (firstEffect !== null) {
25149 var prevExecutionContext = executionContext;
25150 executionContext |= CommitContext;
25151 var prevInteractions = pushInteractions(root); // Reset this to null before calling lifecycles
25152
25153 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
25154 // of the effect list for each phase: all mutation effects come before all
25155 // layout effects, and so on.
25156 // The first phase a "before mutation" phase. We use this phase to read the
25157 // state of the host tree right before we mutate it. This is where
25158 // getSnapshotBeforeUpdate is called.
25159
25160 startCommitSnapshotEffectsTimer();
25161 prepareForCommit(root.containerInfo);
25162 nextEffect = firstEffect;
25163
25164 do {
25165 {
25166 invokeGuardedCallback(null, commitBeforeMutationEffects, null);
25167
25168 if (hasCaughtError()) {
25169 if (!(nextEffect !== null)) {
25170 {
25171 throw Error("Should be working on an effect.");
25172 }
25173 }
25174
25175 var error = clearCaughtError();
25176 captureCommitPhaseError(nextEffect, error);
25177 nextEffect = nextEffect.nextEffect;
25178 }
25179 }
25180 } while (nextEffect !== null);
25181
25182 stopCommitSnapshotEffectsTimer();
25183
25184 if (enableProfilerTimer) {
25185 // Mark the current commit time to be shared by all Profilers in this
25186 // batch. This enables them to be grouped later.
25187 recordCommitTime();
25188 } // The next phase is the mutation phase, where we mutate the host tree.
25189
25190
25191 startCommitHostEffectsTimer();
25192 nextEffect = firstEffect;
25193
25194 do {
25195 {
25196 invokeGuardedCallback(null, commitMutationEffects, null, root, renderPriorityLevel);
25197
25198 if (hasCaughtError()) {
25199 if (!(nextEffect !== null)) {
25200 {
25201 throw Error("Should be working on an effect.");
25202 }
25203 }
25204
25205 var _error = clearCaughtError();
25206
25207 captureCommitPhaseError(nextEffect, _error);
25208 nextEffect = nextEffect.nextEffect;
25209 }
25210 }
25211 } while (nextEffect !== null);
25212
25213 stopCommitHostEffectsTimer();
25214 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
25215 // the mutation phase, so that the previous tree is still current during
25216 // componentWillUnmount, but before the layout phase, so that the finished
25217 // work is current during componentDidMount/Update.
25218
25219 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
25220 // the host tree after it's been mutated. The idiomatic use case for this is
25221 // layout, but class component lifecycles also fire here for legacy reasons.
25222
25223 startCommitLifeCyclesTimer();
25224 nextEffect = firstEffect;
25225
25226 do {
25227 {
25228 invokeGuardedCallback(null, commitLayoutEffects, null, root, expirationTime);
25229
25230 if (hasCaughtError()) {
25231 if (!(nextEffect !== null)) {
25232 {
25233 throw Error("Should be working on an effect.");
25234 }
25235 }
25236
25237 var _error2 = clearCaughtError();
25238
25239 captureCommitPhaseError(nextEffect, _error2);
25240 nextEffect = nextEffect.nextEffect;
25241 }
25242 }
25243 } while (nextEffect !== null);
25244
25245 stopCommitLifeCyclesTimer();
25246 nextEffect = null; // Tell Scheduler to yield at the end of the frame, so the browser has an
25247 // opportunity to paint.
25248
25249 requestPaint();
25250
25251 if (enableSchedulerTracing) {
25252 popInteractions(prevInteractions);
25253 }
25254
25255 executionContext = prevExecutionContext;
25256 } else {
25257 // No effects.
25258 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
25259 // no effects.
25260 // TODO: Maybe there's a better way to report this.
25261
25262 startCommitSnapshotEffectsTimer();
25263 stopCommitSnapshotEffectsTimer();
25264
25265 if (enableProfilerTimer) {
25266 recordCommitTime();
25267 }
25268
25269 startCommitHostEffectsTimer();
25270 stopCommitHostEffectsTimer();
25271 startCommitLifeCyclesTimer();
25272 stopCommitLifeCyclesTimer();
25273 }
25274
25275 stopCommitTimer();
25276 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
25277
25278 if (rootDoesHavePassiveEffects) {
25279 // This commit has passive effects. Stash a reference to them. But don't
25280 // schedule a callback until after flushing layout work.
25281 rootDoesHavePassiveEffects = false;
25282 rootWithPendingPassiveEffects = root;
25283 pendingPassiveEffectsExpirationTime = expirationTime;
25284 pendingPassiveEffectsRenderPriority = renderPriorityLevel;
25285 } else {
25286 // We are done with the effect chain at this point so let's clear the
25287 // nextEffect pointers to assist with GC. If we have passive effects, we'll
25288 // clear this in flushPassiveEffects.
25289 nextEffect = firstEffect;
25290
25291 while (nextEffect !== null) {
25292 var nextNextEffect = nextEffect.nextEffect;
25293 nextEffect.nextEffect = null;
25294 nextEffect = nextNextEffect;
25295 }
25296 } // Check if there's remaining work on this root
25297
25298
25299 var remainingExpirationTime = root.firstPendingTime;
25300
25301 if (remainingExpirationTime !== NoWork) {
25302 if (enableSchedulerTracing) {
25303 if (spawnedWorkDuringRender !== null) {
25304 var expirationTimes = spawnedWorkDuringRender;
25305 spawnedWorkDuringRender = null;
25306
25307 for (var i = 0; i < expirationTimes.length; i++) {
25308 scheduleInteractions(root, expirationTimes[i], root.memoizedInteractions);
25309 }
25310 }
25311
25312 schedulePendingInteractions(root, remainingExpirationTime);
25313 }
25314 } else {
25315 // If there's no remaining work, we can clear the set of already failed
25316 // error boundaries.
25317 legacyErrorBoundariesThatAlreadyFailed = null;
25318 }
25319
25320 if (enableSchedulerTracing) {
25321 if (!rootDidHavePassiveEffects) {
25322 // If there are no passive effects, then we can complete the pending interactions.
25323 // Otherwise, we'll wait until after the passive effects are flushed.
25324 // Wait to do this until after remaining work has been scheduled,
25325 // so that we don't prematurely signal complete for interactions when there's e.g. hidden work.
25326 finishPendingInteractions(root, expirationTime);
25327 }
25328 }
25329
25330 if (remainingExpirationTime === Sync) {
25331 // Count the number of times the root synchronously re-renders without
25332 // finishing. If there are too many, it indicates an infinite update loop.
25333 if (root === rootWithNestedUpdates) {
25334 nestedUpdateCount++;
25335 } else {
25336 nestedUpdateCount = 0;
25337 rootWithNestedUpdates = root;
25338 }
25339 } else {
25340 nestedUpdateCount = 0;
25341 }
25342
25343 onCommitRoot(finishedWork.stateNode, expirationTime); // Always call this before exiting `commitRoot`, to ensure that any
25344 // additional work on this root is scheduled.
25345
25346 ensureRootIsScheduled(root);
25347
25348 if (hasUncaughtError) {
25349 hasUncaughtError = false;
25350 var _error3 = firstUncaughtError;
25351 firstUncaughtError = null;
25352 throw _error3;
25353 }
25354
25355 if ((executionContext & LegacyUnbatchedContext) !== NoContext) {
25356 // This is a legacy edge case. We just committed the initial mount of
25357 // a ReactDOM.render-ed root inside of batchedUpdates. The commit fired
25358 // synchronously, but layout updates should be deferred until the end
25359 // of the batch.
25360 return null;
25361 } // If layout work was scheduled, flush it now.
25362
25363
25364 flushSyncCallbackQueue();
25365 return null;
25366}
25367
25368function commitBeforeMutationEffects() {
25369 while (nextEffect !== null) {
25370 var effectTag = nextEffect.effectTag;
25371
25372 if ((effectTag & Snapshot) !== NoEffect) {
25373 setCurrentFiber(nextEffect);
25374 recordEffect();
25375 var current$$1 = nextEffect.alternate;
25376 commitBeforeMutationLifeCycles(current$$1, nextEffect);
25377 resetCurrentFiber();
25378 }
25379
25380 if ((effectTag & Passive) !== NoEffect) {
25381 // If there are passive effects, schedule a callback to flush at
25382 // the earliest opportunity.
25383 if (!rootDoesHavePassiveEffects) {
25384 rootDoesHavePassiveEffects = true;
25385 scheduleCallback(NormalPriority, function () {
25386 flushPassiveEffects();
25387 return null;
25388 });
25389 }
25390 }
25391
25392 nextEffect = nextEffect.nextEffect;
25393 }
25394}
25395
25396function commitMutationEffects(root, renderPriorityLevel) {
25397 // TODO: Should probably move the bulk of this function to commitWork.
25398 while (nextEffect !== null) {
25399 setCurrentFiber(nextEffect);
25400 var effectTag = nextEffect.effectTag;
25401
25402 if (effectTag & ContentReset) {
25403 commitResetTextContent(nextEffect);
25404 }
25405
25406 if (effectTag & Ref) {
25407 var current$$1 = nextEffect.alternate;
25408
25409 if (current$$1 !== null) {
25410 commitDetachRef(current$$1);
25411 }
25412 } // The following switch statement is only concerned about placement,
25413 // updates, and deletions. To avoid needing to add a case for every possible
25414 // bitmap value, we remove the secondary effects from the effect tag and
25415 // switch on that value.
25416
25417
25418 var primaryEffectTag = effectTag & (Placement | Update | Deletion | Hydrating);
25419
25420 switch (primaryEffectTag) {
25421 case Placement:
25422 {
25423 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
25424 // inserted, before any life-cycles like componentDidMount gets called.
25425 // TODO: findDOMNode doesn't rely on this any more but isMounted does
25426 // and isMounted is deprecated anyway so we should be able to kill this.
25427
25428 nextEffect.effectTag &= ~Placement;
25429 break;
25430 }
25431
25432 case PlacementAndUpdate:
25433 {
25434 // Placement
25435 commitPlacement(nextEffect); // Clear the "placement" from effect tag so that we know that this is
25436 // inserted, before any life-cycles like componentDidMount gets called.
25437
25438 nextEffect.effectTag &= ~Placement; // Update
25439
25440 var _current = nextEffect.alternate;
25441 commitWork(_current, nextEffect);
25442 break;
25443 }
25444
25445 case Hydrating:
25446 {
25447 nextEffect.effectTag &= ~Hydrating;
25448 break;
25449 }
25450
25451 case HydratingAndUpdate:
25452 {
25453 nextEffect.effectTag &= ~Hydrating; // Update
25454
25455 var _current2 = nextEffect.alternate;
25456 commitWork(_current2, nextEffect);
25457 break;
25458 }
25459
25460 case Update:
25461 {
25462 var _current3 = nextEffect.alternate;
25463 commitWork(_current3, nextEffect);
25464 break;
25465 }
25466
25467 case Deletion:
25468 {
25469 commitDeletion(root, nextEffect, renderPriorityLevel);
25470 break;
25471 }
25472 } // TODO: Only record a mutation effect if primaryEffectTag is non-zero.
25473
25474
25475 recordEffect();
25476 resetCurrentFiber();
25477 nextEffect = nextEffect.nextEffect;
25478 }
25479}
25480
25481function commitLayoutEffects(root, committedExpirationTime) {
25482 // TODO: Should probably move the bulk of this function to commitWork.
25483 while (nextEffect !== null) {
25484 setCurrentFiber(nextEffect);
25485 var effectTag = nextEffect.effectTag;
25486
25487 if (effectTag & (Update | Callback)) {
25488 recordEffect();
25489 var current$$1 = nextEffect.alternate;
25490 commitLifeCycles(root, current$$1, nextEffect, committedExpirationTime);
25491 }
25492
25493 if (effectTag & Ref) {
25494 recordEffect();
25495 commitAttachRef(nextEffect);
25496 }
25497
25498 resetCurrentFiber();
25499 nextEffect = nextEffect.nextEffect;
25500 }
25501}
25502
25503function flushPassiveEffects() {
25504 if (pendingPassiveEffectsRenderPriority !== NoPriority) {
25505 var priorityLevel = pendingPassiveEffectsRenderPriority > NormalPriority ? NormalPriority : pendingPassiveEffectsRenderPriority;
25506 pendingPassiveEffectsRenderPriority = NoPriority;
25507 return runWithPriority$2(priorityLevel, flushPassiveEffectsImpl);
25508 }
25509}
25510
25511function flushPassiveEffectsImpl() {
25512 if (rootWithPendingPassiveEffects === null) {
25513 return false;
25514 }
25515
25516 var root = rootWithPendingPassiveEffects;
25517 var expirationTime = pendingPassiveEffectsExpirationTime;
25518 rootWithPendingPassiveEffects = null;
25519 pendingPassiveEffectsExpirationTime = NoWork;
25520
25521 if (!((executionContext & (RenderContext | CommitContext)) === NoContext)) {
25522 {
25523 throw Error("Cannot flush passive effects while already rendering.");
25524 }
25525 }
25526
25527 var prevExecutionContext = executionContext;
25528 executionContext |= CommitContext;
25529 var prevInteractions = pushInteractions(root); // Note: This currently assumes there are no passive effects on the root
25530 // fiber, because the root is not part of its own effect list. This could
25531 // change in the future.
25532
25533 var effect = root.current.firstEffect;
25534
25535 while (effect !== null) {
25536 {
25537 setCurrentFiber(effect);
25538 invokeGuardedCallback(null, commitPassiveHookEffects, null, effect);
25539
25540 if (hasCaughtError()) {
25541 if (!(effect !== null)) {
25542 {
25543 throw Error("Should be working on an effect.");
25544 }
25545 }
25546
25547 var error = clearCaughtError();
25548 captureCommitPhaseError(effect, error);
25549 }
25550
25551 resetCurrentFiber();
25552 }
25553
25554 var nextNextEffect = effect.nextEffect; // Remove nextEffect pointer to assist GC
25555
25556 effect.nextEffect = null;
25557 effect = nextNextEffect;
25558 }
25559
25560 if (enableSchedulerTracing) {
25561 popInteractions(prevInteractions);
25562 finishPendingInteractions(root, expirationTime);
25563 }
25564
25565 executionContext = prevExecutionContext;
25566 flushSyncCallbackQueue(); // If additional passive effects were scheduled, increment a counter. If this
25567 // exceeds the limit, we'll fire a warning.
25568
25569 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1;
25570 return true;
25571}
25572
25573function isAlreadyFailedLegacyErrorBoundary(instance) {
25574 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
25575}
25576function markLegacyErrorBoundaryAsFailed(instance) {
25577 if (legacyErrorBoundariesThatAlreadyFailed === null) {
25578 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
25579 } else {
25580 legacyErrorBoundariesThatAlreadyFailed.add(instance);
25581 }
25582}
25583
25584function prepareToThrowUncaughtError(error) {
25585 if (!hasUncaughtError) {
25586 hasUncaughtError = true;
25587 firstUncaughtError = error;
25588 }
25589}
25590
25591var onUncaughtError = prepareToThrowUncaughtError;
25592
25593function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
25594 var errorInfo = createCapturedValue(error, sourceFiber);
25595 var update = createRootErrorUpdate(rootFiber, errorInfo, Sync);
25596 enqueueUpdate(rootFiber, update);
25597 var root = markUpdateTimeFromFiberToRoot(rootFiber, Sync);
25598
25599 if (root !== null) {
25600 ensureRootIsScheduled(root);
25601 schedulePendingInteractions(root, Sync);
25602 }
25603}
25604
25605function captureCommitPhaseError(sourceFiber, error) {
25606 if (sourceFiber.tag === HostRoot) {
25607 // Error was thrown at the root. There is no parent, so the root
25608 // itself should capture it.
25609 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error);
25610 return;
25611 }
25612
25613 var fiber = sourceFiber.return;
25614
25615 while (fiber !== null) {
25616 if (fiber.tag === HostRoot) {
25617 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error);
25618 return;
25619 } else if (fiber.tag === ClassComponent) {
25620 var ctor = fiber.type;
25621 var instance = fiber.stateNode;
25622
25623 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
25624 var errorInfo = createCapturedValue(error, sourceFiber);
25625 var update = createClassErrorUpdate(fiber, errorInfo, // TODO: This is always sync
25626 Sync);
25627 enqueueUpdate(fiber, update);
25628 var root = markUpdateTimeFromFiberToRoot(fiber, Sync);
25629
25630 if (root !== null) {
25631 ensureRootIsScheduled(root);
25632 schedulePendingInteractions(root, Sync);
25633 }
25634
25635 return;
25636 }
25637 }
25638
25639 fiber = fiber.return;
25640 }
25641}
25642function pingSuspendedRoot(root, thenable, suspendedTime) {
25643 var pingCache = root.pingCache;
25644
25645 if (pingCache !== null) {
25646 // The thenable resolved, so we no longer need to memoize, because it will
25647 // never be thrown again.
25648 pingCache.delete(thenable);
25649 }
25650
25651 if (workInProgressRoot === root && renderExpirationTime === suspendedTime) {
25652 // Received a ping at the same priority level at which we're currently
25653 // rendering. We might want to restart this render. This should mirror
25654 // the logic of whether or not a root suspends once it completes.
25655 // TODO: If we're rendering sync either due to Sync, Batched or expired,
25656 // we should probably never restart.
25657 // If we're suspended with delay, we'll always suspend so we can always
25658 // restart. If we're suspended without any updates, it might be a retry.
25659 // If it's early in the retry we can restart. We can't know for sure
25660 // whether we'll eventually process an update during this render pass,
25661 // but it's somewhat unlikely that we get to a ping before that, since
25662 // getting to the root most update is usually very fast.
25663 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && workInProgressRootLatestProcessedExpirationTime === Sync && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
25664 // Restart from the root. Don't need to schedule a ping because
25665 // we're already working on this tree.
25666 prepareFreshStack(root, renderExpirationTime);
25667 } else {
25668 // Even though we can't restart right now, we might get an
25669 // opportunity later. So we mark this render as having a ping.
25670 workInProgressRootHasPendingPing = true;
25671 }
25672
25673 return;
25674 }
25675
25676 if (!isRootSuspendedAtTime(root, suspendedTime)) {
25677 // The root is no longer suspended at this time.
25678 return;
25679 }
25680
25681 var lastPingedTime = root.lastPingedTime;
25682
25683 if (lastPingedTime !== NoWork && lastPingedTime < suspendedTime) {
25684 // There's already a lower priority ping scheduled.
25685 return;
25686 } // Mark the time at which this ping was scheduled.
25687
25688
25689 root.lastPingedTime = suspendedTime;
25690
25691 if (root.finishedExpirationTime === suspendedTime) {
25692 // If there's a pending fallback waiting to commit, throw it away.
25693 root.finishedExpirationTime = NoWork;
25694 root.finishedWork = null;
25695 }
25696
25697 ensureRootIsScheduled(root);
25698 schedulePendingInteractions(root, suspendedTime);
25699}
25700
25701function retryTimedOutBoundary(boundaryFiber, retryTime) {
25702 // The boundary fiber (a Suspense component or SuspenseList component)
25703 // previously was rendered in its fallback state. One of the promises that
25704 // suspended it has resolved, which means at least part of the tree was
25705 // likely unblocked. Try rendering again, at a new expiration time.
25706 if (retryTime === NoWork) {
25707 var suspenseConfig = null; // Retries don't carry over the already committed update.
25708
25709 var currentTime = requestCurrentTimeForUpdate();
25710 retryTime = computeExpirationForFiber(currentTime, boundaryFiber, suspenseConfig);
25711 } // TODO: Special case idle priority?
25712
25713
25714 var root = markUpdateTimeFromFiberToRoot(boundaryFiber, retryTime);
25715
25716 if (root !== null) {
25717 ensureRootIsScheduled(root);
25718 schedulePendingInteractions(root, retryTime);
25719 }
25720}
25721
25722function retryDehydratedSuspenseBoundary(boundaryFiber) {
25723 var suspenseState = boundaryFiber.memoizedState;
25724 var retryTime = NoWork;
25725
25726 if (suspenseState !== null) {
25727 retryTime = suspenseState.retryTime;
25728 }
25729
25730 retryTimedOutBoundary(boundaryFiber, retryTime);
25731}
25732function resolveRetryThenable(boundaryFiber, thenable) {
25733 var retryTime = NoWork; // Default
25734
25735 var retryCache;
25736
25737 if (enableSuspenseServerRenderer) {
25738 switch (boundaryFiber.tag) {
25739 case SuspenseComponent:
25740 retryCache = boundaryFiber.stateNode;
25741 var suspenseState = boundaryFiber.memoizedState;
25742
25743 if (suspenseState !== null) {
25744 retryTime = suspenseState.retryTime;
25745 }
25746
25747 break;
25748
25749 case SuspenseListComponent:
25750 retryCache = boundaryFiber.stateNode;
25751 break;
25752
25753 default:
25754 {
25755 {
25756 throw Error("Pinged unknown suspense boundary type. This is probably a bug in React.");
25757 }
25758 }
25759
25760 }
25761 } else {
25762 retryCache = boundaryFiber.stateNode;
25763 }
25764
25765 if (retryCache !== null) {
25766 // The thenable resolved, so we no longer need to memoize, because it will
25767 // never be thrown again.
25768 retryCache.delete(thenable);
25769 }
25770
25771 retryTimedOutBoundary(boundaryFiber, retryTime);
25772} // Computes the next Just Noticeable Difference (JND) boundary.
25773// The theory is that a person can't tell the difference between small differences in time.
25774// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
25775// difference in the experience. However, waiting for longer might mean that we can avoid
25776// showing an intermediate loading state. The longer we have already waited, the harder it
25777// is to tell small differences in time. Therefore, the longer we've already waited,
25778// the longer we can wait additionally. At some point we have to give up though.
25779// We pick a train model where the next boundary commits at a consistent schedule.
25780// These particular numbers are vague estimates. We expect to adjust them based on research.
25781
25782function jnd(timeElapsed) {
25783 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
25784}
25785
25786function computeMsUntilSuspenseLoadingDelay(mostRecentEventTime, committedExpirationTime, suspenseConfig) {
25787 var busyMinDurationMs = suspenseConfig.busyMinDurationMs | 0;
25788
25789 if (busyMinDurationMs <= 0) {
25790 return 0;
25791 }
25792
25793 var busyDelayMs = suspenseConfig.busyDelayMs | 0; // Compute the time until this render pass would expire.
25794
25795 var currentTimeMs = now();
25796 var eventTimeMs = inferTimeFromExpirationTimeWithSuspenseConfig(mostRecentEventTime, suspenseConfig);
25797 var timeElapsed = currentTimeMs - eventTimeMs;
25798
25799 if (timeElapsed <= busyDelayMs) {
25800 // If we haven't yet waited longer than the initial delay, we don't
25801 // have to wait any additional time.
25802 return 0;
25803 }
25804
25805 var msUntilTimeout = busyDelayMs + busyMinDurationMs - timeElapsed; // This is the value that is passed to `setTimeout`.
25806
25807 return msUntilTimeout;
25808}
25809
25810function checkForNestedUpdates() {
25811 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
25812 nestedUpdateCount = 0;
25813 rootWithNestedUpdates = null;
25814
25815 {
25816 {
25817 throw Error("Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.");
25818 }
25819 }
25820 }
25821
25822 {
25823 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
25824 nestedPassiveUpdateCount = 0;
25825 warning$1(false, 'Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
25826 }
25827 }
25828}
25829
25830function flushRenderPhaseStrictModeWarningsInDEV() {
25831 {
25832 ReactStrictModeWarnings.flushLegacyContextWarning();
25833
25834 if (warnAboutDeprecatedLifecycles) {
25835 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
25836 }
25837 }
25838}
25839
25840function stopFinishedWorkLoopTimer() {
25841 var didCompleteRoot = true;
25842 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
25843 interruptedBy = null;
25844}
25845
25846function stopInterruptedWorkLoopTimer() {
25847 // TODO: Track which fiber caused the interruption.
25848 var didCompleteRoot = false;
25849 stopWorkLoopTimer(interruptedBy, didCompleteRoot);
25850 interruptedBy = null;
25851}
25852
25853function checkForInterruption(fiberThatReceivedUpdate, updateExpirationTime) {
25854 if (enableUserTimingAPI && workInProgressRoot !== null && updateExpirationTime > renderExpirationTime) {
25855 interruptedBy = fiberThatReceivedUpdate;
25856 }
25857}
25858
25859var didWarnStateUpdateForUnmountedComponent = null;
25860
25861function warnAboutUpdateOnUnmountedFiberInDEV(fiber) {
25862 {
25863 var tag = fiber.tag;
25864
25865 if (tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
25866 // Only warn for user-defined components, not internal ones like Suspense.
25867 return;
25868 } // We show the whole stack but dedupe on the top component's name because
25869 // the problematic code almost always lies inside that component.
25870
25871
25872 var componentName = getComponentName(fiber.type) || 'ReactComponent';
25873
25874 if (didWarnStateUpdateForUnmountedComponent !== null) {
25875 if (didWarnStateUpdateForUnmountedComponent.has(componentName)) {
25876 return;
25877 }
25878
25879 didWarnStateUpdateForUnmountedComponent.add(componentName);
25880 } else {
25881 didWarnStateUpdateForUnmountedComponent = new Set([componentName]);
25882 }
25883
25884 warningWithoutStack$1(false, "Can't perform a React state update on an unmounted component. This " + 'is a no-op, but it indicates a memory leak in your application. To ' + 'fix, cancel all subscriptions and asynchronous tasks in %s.%s', tag === ClassComponent ? 'the componentWillUnmount method' : 'a useEffect cleanup function', getStackByFiberInDevAndProd(fiber));
25885 }
25886}
25887
25888var beginWork$$1;
25889
25890if (true && replayFailedUnitOfWorkWithInvokeGuardedCallback) {
25891 var dummyFiber = null;
25892
25893 beginWork$$1 = function (current$$1, unitOfWork, expirationTime) {
25894 // If a component throws an error, we replay it again in a synchronously
25895 // dispatched event, so that the debugger will treat it as an uncaught
25896 // error See ReactErrorUtils for more information.
25897 // Before entering the begin phase, copy the work-in-progress onto a dummy
25898 // fiber. If beginWork throws, we'll use this to reset the state.
25899 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
25900
25901 try {
25902 return beginWork$1(current$$1, unitOfWork, expirationTime);
25903 } catch (originalError) {
25904 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
25905 // Don't replay promises. Treat everything else like an error.
25906 throw originalError;
25907 } // Keep this code in sync with handleError; any changes here must have
25908 // corresponding changes there.
25909
25910
25911 resetContextDependencies();
25912 resetHooks(); // Don't reset current debug fiber, since we're about to work on the
25913 // same fiber again.
25914 // Unwind the failed stack frame
25915
25916 unwindInterruptedWork(unitOfWork); // Restore the original properties of the fiber.
25917
25918 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
25919
25920 if (enableProfilerTimer && unitOfWork.mode & ProfileMode) {
25921 // Reset the profiler timer.
25922 startProfilerTimer(unitOfWork);
25923 } // Run beginWork again.
25924
25925
25926 invokeGuardedCallback(null, beginWork$1, null, current$$1, unitOfWork, expirationTime);
25927
25928 if (hasCaughtError()) {
25929 var replayError = clearCaughtError(); // `invokeGuardedCallback` sometimes sets an expando `_suppressLogging`.
25930 // Rethrow this error instead of the original one.
25931
25932 throw replayError;
25933 } else {
25934 // This branch is reachable if the render phase is impure.
25935 throw originalError;
25936 }
25937 }
25938 };
25939} else {
25940 beginWork$$1 = beginWork$1;
25941}
25942
25943var didWarnAboutUpdateInRender = false;
25944var didWarnAboutUpdateInGetChildContext = false;
25945
25946function warnAboutInvalidUpdatesOnClassComponentsInDEV(fiber) {
25947 {
25948 if (fiber.tag === ClassComponent) {
25949 switch (phase) {
25950 case 'getChildContext':
25951 if (didWarnAboutUpdateInGetChildContext) {
25952 return;
25953 }
25954
25955 warningWithoutStack$1(false, 'setState(...): Cannot call setState() inside getChildContext()');
25956 didWarnAboutUpdateInGetChildContext = true;
25957 break;
25958
25959 case 'render':
25960 if (didWarnAboutUpdateInRender) {
25961 return;
25962 }
25963
25964 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.');
25965 didWarnAboutUpdateInRender = true;
25966 break;
25967 }
25968 }
25969 }
25970} // a 'shared' variable that changes when act() opens/closes in tests.
25971
25972
25973var IsThisRendererActing = {
25974 current: false
25975};
25976function warnIfNotScopedWithMatchingAct(fiber) {
25977 {
25978 if (warnsIfNotActing === true && IsSomeRendererActing.current === true && IsThisRendererActing.current !== true) {
25979 warningWithoutStack$1(false, "It looks like you're using the wrong act() around your test interactions.\n" + 'Be sure to use the matching version of act() corresponding to your renderer:\n\n' + '// for react-dom:\n' + "import {act} from 'react-dom/test-utils';\n" + '// ...\n' + 'act(() => ...);\n\n' + '// for react-test-renderer:\n' + "import TestRenderer from 'react-test-renderer';\n" + 'const {act} = TestRenderer;\n' + '// ...\n' + 'act(() => ...);' + '%s', getStackByFiberInDevAndProd(fiber));
25980 }
25981 }
25982}
25983function warnIfNotCurrentlyActingEffectsInDEV(fiber) {
25984 {
25985 if (warnsIfNotActing === true && (fiber.mode & StrictMode) !== NoMode && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
25986 warningWithoutStack$1(false, 'An update to %s ran an effect, but was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
25987 }
25988 }
25989}
25990
25991function warnIfNotCurrentlyActingUpdatesInDEV(fiber) {
25992 {
25993 if (warnsIfNotActing === true && executionContext === NoContext && IsSomeRendererActing.current === false && IsThisRendererActing.current === false) {
25994 warningWithoutStack$1(false, 'An update to %s inside a test was not wrapped in act(...).\n\n' + 'When testing, code that causes React state updates should be ' + 'wrapped into act(...):\n\n' + 'act(() => {\n' + ' /* fire events that update state */\n' + '});\n' + '/* assert on the output */\n\n' + "This ensures that you're testing the behavior the user would see " + 'in the browser.' + ' Learn more at https://fb.me/react-wrap-tests-with-act' + '%s', getComponentName(fiber.type), getStackByFiberInDevAndProd(fiber));
25995 }
25996 }
25997}
25998
25999var warnIfNotCurrentlyActingUpdatesInDev = warnIfNotCurrentlyActingUpdatesInDEV; // In tests, we want to enforce a mocked scheduler.
26000
26001var didWarnAboutUnmockedScheduler = false; // TODO Before we release concurrent mode, revisit this and decide whether a mocked
26002// scheduler is the actual recommendation. The alternative could be a testing build,
26003// a new lib, or whatever; we dunno just yet. This message is for early adopters
26004// to get their tests right.
26005
26006function warnIfUnmockedScheduler(fiber) {
26007 {
26008 if (didWarnAboutUnmockedScheduler === false && unstable_flushAllWithoutAsserting === undefined) {
26009 if (fiber.mode & BlockingMode || fiber.mode & ConcurrentMode) {
26010 didWarnAboutUnmockedScheduler = true;
26011 warningWithoutStack$1(false, 'In Concurrent or Sync modes, the "scheduler" module needs to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
26012 } else if (warnAboutUnmockedScheduler === true) {
26013 didWarnAboutUnmockedScheduler = true;
26014 warningWithoutStack$1(false, 'Starting from React v17, the "scheduler" module will need to be mocked ' + 'to guarantee consistent behaviour across tests and browsers. ' + 'For example, with jest: \n' + "jest.mock('scheduler', () => require('scheduler/unstable_mock'));\n\n" + 'For more info, visit https://fb.me/react-mock-scheduler');
26015 }
26016 }
26017 }
26018}
26019var componentsThatTriggeredHighPriSuspend = null;
26020function checkForWrongSuspensePriorityInDEV(sourceFiber) {
26021 {
26022 var currentPriorityLevel = getCurrentPriorityLevel();
26023
26024 if ((sourceFiber.mode & ConcurrentMode) !== NoEffect && (currentPriorityLevel === UserBlockingPriority$2 || currentPriorityLevel === ImmediatePriority)) {
26025 var workInProgressNode = sourceFiber;
26026
26027 while (workInProgressNode !== null) {
26028 // Add the component that triggered the suspense
26029 var current$$1 = workInProgressNode.alternate;
26030
26031 if (current$$1 !== null) {
26032 // TODO: warn component that triggers the high priority
26033 // suspend is the HostRoot
26034 switch (workInProgressNode.tag) {
26035 case ClassComponent:
26036 // Loop through the component's update queue and see whether the component
26037 // has triggered any high priority updates
26038 var updateQueue = current$$1.updateQueue;
26039
26040 if (updateQueue !== null) {
26041 var update = updateQueue.firstUpdate;
26042
26043 while (update !== null) {
26044 var priorityLevel = update.priority;
26045
26046 if (priorityLevel === UserBlockingPriority$2 || priorityLevel === ImmediatePriority) {
26047 if (componentsThatTriggeredHighPriSuspend === null) {
26048 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
26049 } else {
26050 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
26051 }
26052
26053 break;
26054 }
26055
26056 update = update.next;
26057 }
26058 }
26059
26060 break;
26061
26062 case FunctionComponent:
26063 case ForwardRef:
26064 case SimpleMemoComponent:
26065 if (workInProgressNode.memoizedState !== null && workInProgressNode.memoizedState.baseUpdate !== null) {
26066 var _update = workInProgressNode.memoizedState.baseUpdate; // Loop through the functional component's memoized state to see whether
26067 // the component has triggered any high pri updates
26068
26069 while (_update !== null) {
26070 var priority = _update.priority;
26071
26072 if (priority === UserBlockingPriority$2 || priority === ImmediatePriority) {
26073 if (componentsThatTriggeredHighPriSuspend === null) {
26074 componentsThatTriggeredHighPriSuspend = new Set([getComponentName(workInProgressNode.type)]);
26075 } else {
26076 componentsThatTriggeredHighPriSuspend.add(getComponentName(workInProgressNode.type));
26077 }
26078
26079 break;
26080 }
26081
26082 if (_update.next === workInProgressNode.memoizedState.baseUpdate) {
26083 break;
26084 }
26085
26086 _update = _update.next;
26087 }
26088 }
26089
26090 break;
26091
26092 default:
26093 break;
26094 }
26095 }
26096
26097 workInProgressNode = workInProgressNode.return;
26098 }
26099 }
26100 }
26101}
26102
26103function flushSuspensePriorityWarningInDEV() {
26104 {
26105 if (componentsThatTriggeredHighPriSuspend !== null) {
26106 var componentNames = [];
26107 componentsThatTriggeredHighPriSuspend.forEach(function (name) {
26108 return componentNames.push(name);
26109 });
26110 componentsThatTriggeredHighPriSuspend = null;
26111
26112 if (componentNames.length > 0) {
26113 warningWithoutStack$1(false, '%s triggered a user-blocking update that suspended.' + '\n\n' + 'The fix is to split the update into multiple parts: a user-blocking ' + 'update to provide immediate feedback, and another update that ' + 'triggers the bulk of the changes.' + '\n\n' + 'Refer to the documentation for useTransition to learn how ' + 'to implement this pattern.', // TODO: Add link to React docs with more information, once it exists
26114 componentNames.sort().join(', '));
26115 }
26116 }
26117 }
26118}
26119
26120function computeThreadID(root, expirationTime) {
26121 // Interaction threads are unique per root and expiration time.
26122 return expirationTime * 1000 + root.interactionThreadID;
26123}
26124
26125function markSpawnedWork(expirationTime) {
26126 if (!enableSchedulerTracing) {
26127 return;
26128 }
26129
26130 if (spawnedWorkDuringRender === null) {
26131 spawnedWorkDuringRender = [expirationTime];
26132 } else {
26133 spawnedWorkDuringRender.push(expirationTime);
26134 }
26135}
26136
26137function scheduleInteractions(root, expirationTime, interactions) {
26138 if (!enableSchedulerTracing) {
26139 return;
26140 }
26141
26142 if (interactions.size > 0) {
26143 var pendingInteractionMap = root.pendingInteractionMap;
26144 var pendingInteractions = pendingInteractionMap.get(expirationTime);
26145
26146 if (pendingInteractions != null) {
26147 interactions.forEach(function (interaction) {
26148 if (!pendingInteractions.has(interaction)) {
26149 // Update the pending async work count for previously unscheduled interaction.
26150 interaction.__count++;
26151 }
26152
26153 pendingInteractions.add(interaction);
26154 });
26155 } else {
26156 pendingInteractionMap.set(expirationTime, new Set(interactions)); // Update the pending async work count for the current interactions.
26157
26158 interactions.forEach(function (interaction) {
26159 interaction.__count++;
26160 });
26161 }
26162
26163 var subscriber = __subscriberRef.current;
26164
26165 if (subscriber !== null) {
26166 var threadID = computeThreadID(root, expirationTime);
26167 subscriber.onWorkScheduled(interactions, threadID);
26168 }
26169 }
26170}
26171
26172function schedulePendingInteractions(root, expirationTime) {
26173 // This is called when work is scheduled on a root.
26174 // It associates the current interactions with the newly-scheduled expiration.
26175 // They will be restored when that expiration is later committed.
26176 if (!enableSchedulerTracing) {
26177 return;
26178 }
26179
26180 scheduleInteractions(root, expirationTime, __interactionsRef.current);
26181}
26182
26183function startWorkOnPendingInteractions(root, expirationTime) {
26184 // This is called when new work is started on a root.
26185 if (!enableSchedulerTracing) {
26186 return;
26187 } // Determine which interactions this batch of work currently includes, So that
26188 // we can accurately attribute time spent working on it, And so that cascading
26189 // work triggered during the render phase will be associated with it.
26190
26191
26192 var interactions = new Set();
26193 root.pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
26194 if (scheduledExpirationTime >= expirationTime) {
26195 scheduledInteractions.forEach(function (interaction) {
26196 return interactions.add(interaction);
26197 });
26198 }
26199 }); // Store the current set of interactions on the FiberRoot for a few reasons:
26200 // We can re-use it in hot functions like performConcurrentWorkOnRoot()
26201 // without having to recalculate it. We will also use it in commitWork() to
26202 // pass to any Profiler onRender() hooks. This also provides DevTools with a
26203 // way to access it when the onCommitRoot() hook is called.
26204
26205 root.memoizedInteractions = interactions;
26206
26207 if (interactions.size > 0) {
26208 var subscriber = __subscriberRef.current;
26209
26210 if (subscriber !== null) {
26211 var threadID = computeThreadID(root, expirationTime);
26212
26213 try {
26214 subscriber.onWorkStarted(interactions, threadID);
26215 } catch (error) {
26216 // If the subscriber throws, rethrow it in a separate task
26217 scheduleCallback(ImmediatePriority, function () {
26218 throw error;
26219 });
26220 }
26221 }
26222 }
26223}
26224
26225function finishPendingInteractions(root, committedExpirationTime) {
26226 if (!enableSchedulerTracing) {
26227 return;
26228 }
26229
26230 var earliestRemainingTimeAfterCommit = root.firstPendingTime;
26231 var subscriber;
26232
26233 try {
26234 subscriber = __subscriberRef.current;
26235
26236 if (subscriber !== null && root.memoizedInteractions.size > 0) {
26237 var threadID = computeThreadID(root, committedExpirationTime);
26238 subscriber.onWorkStopped(root.memoizedInteractions, threadID);
26239 }
26240 } catch (error) {
26241 // If the subscriber throws, rethrow it in a separate task
26242 scheduleCallback(ImmediatePriority, function () {
26243 throw error;
26244 });
26245 } finally {
26246 // Clear completed interactions from the pending Map.
26247 // Unless the render was suspended or cascading work was scheduled,
26248 // In which case– leave pending interactions until the subsequent render.
26249 var pendingInteractionMap = root.pendingInteractionMap;
26250 pendingInteractionMap.forEach(function (scheduledInteractions, scheduledExpirationTime) {
26251 // Only decrement the pending interaction count if we're done.
26252 // If there's still work at the current priority,
26253 // That indicates that we are waiting for suspense data.
26254 if (scheduledExpirationTime > earliestRemainingTimeAfterCommit) {
26255 pendingInteractionMap.delete(scheduledExpirationTime);
26256 scheduledInteractions.forEach(function (interaction) {
26257 interaction.__count--;
26258
26259 if (subscriber !== null && interaction.__count === 0) {
26260 try {
26261 subscriber.onInteractionScheduledWorkCompleted(interaction);
26262 } catch (error) {
26263 // If the subscriber throws, rethrow it in a separate task
26264 scheduleCallback(ImmediatePriority, function () {
26265 throw error;
26266 });
26267 }
26268 }
26269 });
26270 }
26271 });
26272 }
26273}
26274
26275var onCommitFiberRoot = null;
26276var onCommitFiberUnmount = null;
26277var hasLoggedError = false;
26278var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
26279function injectInternals(internals) {
26280 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
26281 // No DevTools
26282 return false;
26283 }
26284
26285 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
26286
26287 if (hook.isDisabled) {
26288 // This isn't a real property on the hook, but it can be set to opt out
26289 // of DevTools integration and associated warnings and logs.
26290 // https://github.com/facebook/react/issues/3877
26291 return true;
26292 }
26293
26294 if (!hook.supportsFiber) {
26295 {
26296 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');
26297 } // DevTools exists, even though it doesn't support Fiber.
26298
26299
26300 return true;
26301 }
26302
26303 try {
26304 var rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
26305
26306 onCommitFiberRoot = function (root, expirationTime) {
26307 try {
26308 var didError = (root.current.effectTag & DidCapture) === DidCapture;
26309
26310 if (enableProfilerTimer) {
26311 var currentTime = getCurrentTime();
26312 var priorityLevel = inferPriorityFromExpirationTime(currentTime, expirationTime);
26313 hook.onCommitFiberRoot(rendererID, root, priorityLevel, didError);
26314 } else {
26315 hook.onCommitFiberRoot(rendererID, root, undefined, didError);
26316 }
26317 } catch (err) {
26318 if (true && !hasLoggedError) {
26319 hasLoggedError = true;
26320 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
26321 }
26322 }
26323 };
26324
26325 onCommitFiberUnmount = function (fiber) {
26326 try {
26327 hook.onCommitFiberUnmount(rendererID, fiber);
26328 } catch (err) {
26329 if (true && !hasLoggedError) {
26330 hasLoggedError = true;
26331 warningWithoutStack$1(false, 'React DevTools encountered an error: %s', err);
26332 }
26333 }
26334 };
26335 } catch (err) {
26336 // Catch all errors because it is unsafe to throw during initialization.
26337 {
26338 warningWithoutStack$1(false, 'React DevTools encountered an error: %s.', err);
26339 }
26340 } // DevTools exists
26341
26342
26343 return true;
26344}
26345function onCommitRoot(root, expirationTime) {
26346 if (typeof onCommitFiberRoot === 'function') {
26347 onCommitFiberRoot(root, expirationTime);
26348 }
26349}
26350function onCommitUnmount(fiber) {
26351 if (typeof onCommitFiberUnmount === 'function') {
26352 onCommitFiberUnmount(fiber);
26353 }
26354}
26355
26356var hasBadMapPolyfill;
26357
26358{
26359 hasBadMapPolyfill = false;
26360
26361 try {
26362 var nonExtensibleObject = Object.preventExtensions({});
26363 var testMap = new Map([[nonExtensibleObject, null]]);
26364 var testSet = new Set([nonExtensibleObject]); // This is necessary for Rollup to not consider these unused.
26365 // https://github.com/rollup/rollup/issues/1771
26366 // TODO: we can remove these if Rollup fixes the bug.
26367
26368 testMap.set(0, 0);
26369 testSet.add(0);
26370 } catch (e) {
26371 // TODO: Consider warning about bad polyfills
26372 hasBadMapPolyfill = true;
26373 }
26374}
26375
26376var debugCounter = 1;
26377
26378function FiberNode(tag, pendingProps, key, mode) {
26379 // Instance
26380 this.tag = tag;
26381 this.key = key;
26382 this.elementType = null;
26383 this.type = null;
26384 this.stateNode = null; // Fiber
26385
26386 this.return = null;
26387 this.child = null;
26388 this.sibling = null;
26389 this.index = 0;
26390 this.ref = null;
26391 this.pendingProps = pendingProps;
26392 this.memoizedProps = null;
26393 this.updateQueue = null;
26394 this.memoizedState = null;
26395 this.dependencies = null;
26396 this.mode = mode; // Effects
26397
26398 this.effectTag = NoEffect;
26399 this.nextEffect = null;
26400 this.firstEffect = null;
26401 this.lastEffect = null;
26402 this.expirationTime = NoWork;
26403 this.childExpirationTime = NoWork;
26404 this.alternate = null;
26405
26406 if (enableProfilerTimer) {
26407 // Note: The following is done to avoid a v8 performance cliff.
26408 //
26409 // Initializing the fields below to smis and later updating them with
26410 // double values will cause Fibers to end up having separate shapes.
26411 // This behavior/bug has something to do with Object.preventExtension().
26412 // Fortunately this only impacts DEV builds.
26413 // Unfortunately it makes React unusably slow for some applications.
26414 // To work around this, initialize the fields below with doubles.
26415 //
26416 // Learn more about this here:
26417 // https://github.com/facebook/react/issues/14365
26418 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
26419 this.actualDuration = Number.NaN;
26420 this.actualStartTime = Number.NaN;
26421 this.selfBaseDuration = Number.NaN;
26422 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
26423 // This won't trigger the performance cliff mentioned above,
26424 // and it simplifies other profiler code (including DevTools).
26425
26426 this.actualDuration = 0;
26427 this.actualStartTime = -1;
26428 this.selfBaseDuration = 0;
26429 this.treeBaseDuration = 0;
26430 } // This is normally DEV-only except www when it adds listeners.
26431 // TODO: remove the User Timing integration in favor of Root Events.
26432
26433
26434 if (enableUserTimingAPI) {
26435 this._debugID = debugCounter++;
26436 this._debugIsCurrentlyTiming = false;
26437 }
26438
26439 {
26440 this._debugSource = null;
26441 this._debugOwner = null;
26442 this._debugNeedsRemount = false;
26443 this._debugHookTypes = null;
26444
26445 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
26446 Object.preventExtensions(this);
26447 }
26448 }
26449} // This is a constructor function, rather than a POJO constructor, still
26450// please ensure we do the following:
26451// 1) Nobody should add any instance methods on this. Instance methods can be
26452// more difficult to predict when they get optimized and they are almost
26453// never inlined properly in static compilers.
26454// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
26455// always know when it is a fiber.
26456// 3) We might want to experiment with using numeric keys since they are easier
26457// to optimize in a non-JIT environment.
26458// 4) We can easily go from a constructor to a createFiber object literal if that
26459// is faster.
26460// 5) It should be easy to port this to a C struct and keep a C implementation
26461// compatible.
26462
26463
26464var createFiber = function (tag, pendingProps, key, mode) {
26465 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
26466 return new FiberNode(tag, pendingProps, key, mode);
26467};
26468
26469function shouldConstruct(Component) {
26470 var prototype = Component.prototype;
26471 return !!(prototype && prototype.isReactComponent);
26472}
26473
26474function isSimpleFunctionComponent(type) {
26475 return typeof type === 'function' && !shouldConstruct(type) && type.defaultProps === undefined;
26476}
26477function resolveLazyComponentTag(Component) {
26478 if (typeof Component === 'function') {
26479 return shouldConstruct(Component) ? ClassComponent : FunctionComponent;
26480 } else if (Component !== undefined && Component !== null) {
26481 var $$typeof = Component.$$typeof;
26482
26483 if ($$typeof === REACT_FORWARD_REF_TYPE) {
26484 return ForwardRef;
26485 }
26486
26487 if ($$typeof === REACT_MEMO_TYPE) {
26488 return MemoComponent;
26489 }
26490 }
26491
26492 return IndeterminateComponent;
26493} // This is used to create an alternate fiber to do work on.
26494
26495function createWorkInProgress(current, pendingProps, expirationTime) {
26496 var workInProgress = current.alternate;
26497
26498 if (workInProgress === null) {
26499 // We use a double buffering pooling technique because we know that we'll
26500 // only ever need at most two versions of a tree. We pool the "other" unused
26501 // node that we're free to reuse. This is lazily created to avoid allocating
26502 // extra objects for things that are never updated. It also allow us to
26503 // reclaim the extra memory if needed.
26504 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
26505 workInProgress.elementType = current.elementType;
26506 workInProgress.type = current.type;
26507 workInProgress.stateNode = current.stateNode;
26508
26509 {
26510 // DEV-only fields
26511 workInProgress._debugID = current._debugID;
26512 workInProgress._debugSource = current._debugSource;
26513 workInProgress._debugOwner = current._debugOwner;
26514 workInProgress._debugHookTypes = current._debugHookTypes;
26515 }
26516
26517 workInProgress.alternate = current;
26518 current.alternate = workInProgress;
26519 } else {
26520 workInProgress.pendingProps = pendingProps; // We already have an alternate.
26521 // Reset the effect tag.
26522
26523 workInProgress.effectTag = NoEffect; // The effect list is no longer valid.
26524
26525 workInProgress.nextEffect = null;
26526 workInProgress.firstEffect = null;
26527 workInProgress.lastEffect = null;
26528
26529 if (enableProfilerTimer) {
26530 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
26531 // This prevents time from endlessly accumulating in new commits.
26532 // This has the downside of resetting values for different priority renders,
26533 // But works for yielding (the common case) and should support resuming.
26534 workInProgress.actualDuration = 0;
26535 workInProgress.actualStartTime = -1;
26536 }
26537 }
26538
26539 workInProgress.childExpirationTime = current.childExpirationTime;
26540 workInProgress.expirationTime = current.expirationTime;
26541 workInProgress.child = current.child;
26542 workInProgress.memoizedProps = current.memoizedProps;
26543 workInProgress.memoizedState = current.memoizedState;
26544 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
26545 // it cannot be shared with the current fiber.
26546
26547 var currentDependencies = current.dependencies;
26548 workInProgress.dependencies = currentDependencies === null ? null : {
26549 expirationTime: currentDependencies.expirationTime,
26550 firstContext: currentDependencies.firstContext,
26551 responders: currentDependencies.responders
26552 }; // These will be overridden during the parent's reconciliation
26553
26554 workInProgress.sibling = current.sibling;
26555 workInProgress.index = current.index;
26556 workInProgress.ref = current.ref;
26557
26558 if (enableProfilerTimer) {
26559 workInProgress.selfBaseDuration = current.selfBaseDuration;
26560 workInProgress.treeBaseDuration = current.treeBaseDuration;
26561 }
26562
26563 {
26564 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
26565
26566 switch (workInProgress.tag) {
26567 case IndeterminateComponent:
26568 case FunctionComponent:
26569 case SimpleMemoComponent:
26570 workInProgress.type = resolveFunctionForHotReloading(current.type);
26571 break;
26572
26573 case ClassComponent:
26574 workInProgress.type = resolveClassForHotReloading(current.type);
26575 break;
26576
26577 case ForwardRef:
26578 workInProgress.type = resolveForwardRefForHotReloading(current.type);
26579 break;
26580
26581 default:
26582 break;
26583 }
26584 }
26585
26586 return workInProgress;
26587} // Used to reuse a Fiber for a second pass.
26588
26589function resetWorkInProgress(workInProgress, renderExpirationTime) {
26590 // This resets the Fiber to what createFiber or createWorkInProgress would
26591 // have set the values to before during the first pass. Ideally this wouldn't
26592 // be necessary but unfortunately many code paths reads from the workInProgress
26593 // when they should be reading from current and writing to workInProgress.
26594 // We assume pendingProps, index, key, ref, return are still untouched to
26595 // avoid doing another reconciliation.
26596 // Reset the effect tag but keep any Placement tags, since that's something
26597 // that child fiber is setting, not the reconciliation.
26598 workInProgress.effectTag &= Placement; // The effect list is no longer valid.
26599
26600 workInProgress.nextEffect = null;
26601 workInProgress.firstEffect = null;
26602 workInProgress.lastEffect = null;
26603 var current = workInProgress.alternate;
26604
26605 if (current === null) {
26606 // Reset to createFiber's initial values.
26607 workInProgress.childExpirationTime = NoWork;
26608 workInProgress.expirationTime = renderExpirationTime;
26609 workInProgress.child = null;
26610 workInProgress.memoizedProps = null;
26611 workInProgress.memoizedState = null;
26612 workInProgress.updateQueue = null;
26613 workInProgress.dependencies = null;
26614
26615 if (enableProfilerTimer) {
26616 // Note: We don't reset the actualTime counts. It's useful to accumulate
26617 // actual time across multiple render passes.
26618 workInProgress.selfBaseDuration = 0;
26619 workInProgress.treeBaseDuration = 0;
26620 }
26621 } else {
26622 // Reset to the cloned values that createWorkInProgress would've.
26623 workInProgress.childExpirationTime = current.childExpirationTime;
26624 workInProgress.expirationTime = current.expirationTime;
26625 workInProgress.child = current.child;
26626 workInProgress.memoizedProps = current.memoizedProps;
26627 workInProgress.memoizedState = current.memoizedState;
26628 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
26629 // it cannot be shared with the current fiber.
26630
26631 var currentDependencies = current.dependencies;
26632 workInProgress.dependencies = currentDependencies === null ? null : {
26633 expirationTime: currentDependencies.expirationTime,
26634 firstContext: currentDependencies.firstContext,
26635 responders: currentDependencies.responders
26636 };
26637
26638 if (enableProfilerTimer) {
26639 // Note: We don't reset the actualTime counts. It's useful to accumulate
26640 // actual time across multiple render passes.
26641 workInProgress.selfBaseDuration = current.selfBaseDuration;
26642 workInProgress.treeBaseDuration = current.treeBaseDuration;
26643 }
26644 }
26645
26646 return workInProgress;
26647}
26648function createHostRootFiber(tag) {
26649 var mode;
26650
26651 if (tag === ConcurrentRoot) {
26652 mode = ConcurrentMode | BlockingMode | StrictMode;
26653 } else if (tag === BlockingRoot) {
26654 mode = BlockingMode | StrictMode;
26655 } else {
26656 mode = NoMode;
26657 }
26658
26659 if (enableProfilerTimer && isDevToolsPresent) {
26660 // Always collect profile timings when DevTools are present.
26661 // This enables DevTools to start capturing timing at any point–
26662 // Without some nodes in the tree having empty base times.
26663 mode |= ProfileMode;
26664 }
26665
26666 return createFiber(HostRoot, null, null, mode);
26667}
26668function createFiberFromTypeAndProps(type, // React$ElementType
26669key, pendingProps, owner, mode, expirationTime) {
26670 var fiber;
26671 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
26672
26673 var resolvedType = type;
26674
26675 if (typeof type === 'function') {
26676 if (shouldConstruct(type)) {
26677 fiberTag = ClassComponent;
26678
26679 {
26680 resolvedType = resolveClassForHotReloading(resolvedType);
26681 }
26682 } else {
26683 {
26684 resolvedType = resolveFunctionForHotReloading(resolvedType);
26685 }
26686 }
26687 } else if (typeof type === 'string') {
26688 fiberTag = HostComponent;
26689 } else {
26690 getTag: switch (type) {
26691 case REACT_FRAGMENT_TYPE:
26692 return createFiberFromFragment(pendingProps.children, mode, expirationTime, key);
26693
26694 case REACT_CONCURRENT_MODE_TYPE:
26695 fiberTag = Mode;
26696 mode |= ConcurrentMode | BlockingMode | StrictMode;
26697 break;
26698
26699 case REACT_STRICT_MODE_TYPE:
26700 fiberTag = Mode;
26701 mode |= StrictMode;
26702 break;
26703
26704 case REACT_PROFILER_TYPE:
26705 return createFiberFromProfiler(pendingProps, mode, expirationTime, key);
26706
26707 case REACT_SUSPENSE_TYPE:
26708 return createFiberFromSuspense(pendingProps, mode, expirationTime, key);
26709
26710 case REACT_SUSPENSE_LIST_TYPE:
26711 return createFiberFromSuspenseList(pendingProps, mode, expirationTime, key);
26712
26713 default:
26714 {
26715 if (typeof type === 'object' && type !== null) {
26716 switch (type.$$typeof) {
26717 case REACT_PROVIDER_TYPE:
26718 fiberTag = ContextProvider;
26719 break getTag;
26720
26721 case REACT_CONTEXT_TYPE:
26722 // This is a consumer
26723 fiberTag = ContextConsumer;
26724 break getTag;
26725
26726 case REACT_FORWARD_REF_TYPE:
26727 fiberTag = ForwardRef;
26728
26729 {
26730 resolvedType = resolveForwardRefForHotReloading(resolvedType);
26731 }
26732
26733 break getTag;
26734
26735 case REACT_MEMO_TYPE:
26736 fiberTag = MemoComponent;
26737 break getTag;
26738
26739 case REACT_LAZY_TYPE:
26740 fiberTag = LazyComponent;
26741 resolvedType = null;
26742 break getTag;
26743
26744 case REACT_FUNDAMENTAL_TYPE:
26745 if (enableFundamentalAPI) {
26746 return createFiberFromFundamental(type, pendingProps, mode, expirationTime, key);
26747 }
26748
26749 break;
26750
26751 case REACT_SCOPE_TYPE:
26752 if (enableScopeAPI) {
26753 return createFiberFromScope(type, pendingProps, mode, expirationTime, key);
26754 }
26755
26756 }
26757 }
26758
26759 var info = '';
26760
26761 {
26762 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
26763 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.';
26764 }
26765
26766 var ownerName = owner ? getComponentName(owner.type) : null;
26767
26768 if (ownerName) {
26769 info += '\n\nCheck the render method of `' + ownerName + '`.';
26770 }
26771 }
26772
26773 {
26774 {
26775 throw Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: " + (type == null ? type : typeof type) + "." + info);
26776 }
26777 }
26778 }
26779 }
26780 }
26781
26782 fiber = createFiber(fiberTag, pendingProps, key, mode);
26783 fiber.elementType = type;
26784 fiber.type = resolvedType;
26785 fiber.expirationTime = expirationTime;
26786 return fiber;
26787}
26788function createFiberFromElement(element, mode, expirationTime) {
26789 var owner = null;
26790
26791 {
26792 owner = element._owner;
26793 }
26794
26795 var type = element.type;
26796 var key = element.key;
26797 var pendingProps = element.props;
26798 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, expirationTime);
26799
26800 {
26801 fiber._debugSource = element._source;
26802 fiber._debugOwner = element._owner;
26803 }
26804
26805 return fiber;
26806}
26807function createFiberFromFragment(elements, mode, expirationTime, key) {
26808 var fiber = createFiber(Fragment, elements, key, mode);
26809 fiber.expirationTime = expirationTime;
26810 return fiber;
26811}
26812function createFiberFromFundamental(fundamentalComponent, pendingProps, mode, expirationTime, key) {
26813 var fiber = createFiber(FundamentalComponent, pendingProps, key, mode);
26814 fiber.elementType = fundamentalComponent;
26815 fiber.type = fundamentalComponent;
26816 fiber.expirationTime = expirationTime;
26817 return fiber;
26818}
26819
26820function createFiberFromScope(scope, pendingProps, mode, expirationTime, key) {
26821 var fiber = createFiber(ScopeComponent, pendingProps, key, mode);
26822 fiber.type = scope;
26823 fiber.elementType = scope;
26824 fiber.expirationTime = expirationTime;
26825 return fiber;
26826}
26827
26828function createFiberFromProfiler(pendingProps, mode, expirationTime, key) {
26829 {
26830 if (typeof pendingProps.id !== 'string' || typeof pendingProps.onRender !== 'function') {
26831 warningWithoutStack$1(false, 'Profiler must specify an "id" string and "onRender" function as props');
26832 }
26833 }
26834
26835 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode); // TODO: The Profiler fiber shouldn't have a type. It has a tag.
26836
26837 fiber.elementType = REACT_PROFILER_TYPE;
26838 fiber.type = REACT_PROFILER_TYPE;
26839 fiber.expirationTime = expirationTime;
26840 return fiber;
26841}
26842
26843function createFiberFromSuspense(pendingProps, mode, expirationTime, key) {
26844 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode); // TODO: The SuspenseComponent fiber shouldn't have a type. It has a tag.
26845 // This needs to be fixed in getComponentName so that it relies on the tag
26846 // instead.
26847
26848 fiber.type = REACT_SUSPENSE_TYPE;
26849 fiber.elementType = REACT_SUSPENSE_TYPE;
26850 fiber.expirationTime = expirationTime;
26851 return fiber;
26852}
26853function createFiberFromSuspenseList(pendingProps, mode, expirationTime, key) {
26854 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
26855
26856 {
26857 // TODO: The SuspenseListComponent fiber shouldn't have a type. It has a tag.
26858 // This needs to be fixed in getComponentName so that it relies on the tag
26859 // instead.
26860 fiber.type = REACT_SUSPENSE_LIST_TYPE;
26861 }
26862
26863 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
26864 fiber.expirationTime = expirationTime;
26865 return fiber;
26866}
26867function createFiberFromText(content, mode, expirationTime) {
26868 var fiber = createFiber(HostText, content, null, mode);
26869 fiber.expirationTime = expirationTime;
26870 return fiber;
26871}
26872function createFiberFromHostInstanceForDeletion() {
26873 var fiber = createFiber(HostComponent, null, null, NoMode); // TODO: These should not need a type.
26874
26875 fiber.elementType = 'DELETED';
26876 fiber.type = 'DELETED';
26877 return fiber;
26878}
26879function createFiberFromDehydratedFragment(dehydratedNode) {
26880 var fiber = createFiber(DehydratedFragment, null, null, NoMode);
26881 fiber.stateNode = dehydratedNode;
26882 return fiber;
26883}
26884function createFiberFromPortal(portal, mode, expirationTime) {
26885 var pendingProps = portal.children !== null ? portal.children : [];
26886 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
26887 fiber.expirationTime = expirationTime;
26888 fiber.stateNode = {
26889 containerInfo: portal.containerInfo,
26890 pendingChildren: null,
26891 // Used by persistent updates
26892 implementation: portal.implementation
26893 };
26894 return fiber;
26895} // Used for stashing WIP properties to replay failed work in DEV.
26896
26897function assignFiberPropertiesInDEV(target, source) {
26898 if (target === null) {
26899 // This Fiber's initial properties will always be overwritten.
26900 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
26901 target = createFiber(IndeterminateComponent, null, null, NoMode);
26902 } // This is intentionally written as a list of all properties.
26903 // We tried to use Object.assign() instead but this is called in
26904 // the hottest path, and Object.assign() was too slow:
26905 // https://github.com/facebook/react/issues/12502
26906 // This code is DEV-only so size is not a concern.
26907
26908
26909 target.tag = source.tag;
26910 target.key = source.key;
26911 target.elementType = source.elementType;
26912 target.type = source.type;
26913 target.stateNode = source.stateNode;
26914 target.return = source.return;
26915 target.child = source.child;
26916 target.sibling = source.sibling;
26917 target.index = source.index;
26918 target.ref = source.ref;
26919 target.pendingProps = source.pendingProps;
26920 target.memoizedProps = source.memoizedProps;
26921 target.updateQueue = source.updateQueue;
26922 target.memoizedState = source.memoizedState;
26923 target.dependencies = source.dependencies;
26924 target.mode = source.mode;
26925 target.effectTag = source.effectTag;
26926 target.nextEffect = source.nextEffect;
26927 target.firstEffect = source.firstEffect;
26928 target.lastEffect = source.lastEffect;
26929 target.expirationTime = source.expirationTime;
26930 target.childExpirationTime = source.childExpirationTime;
26931 target.alternate = source.alternate;
26932
26933 if (enableProfilerTimer) {
26934 target.actualDuration = source.actualDuration;
26935 target.actualStartTime = source.actualStartTime;
26936 target.selfBaseDuration = source.selfBaseDuration;
26937 target.treeBaseDuration = source.treeBaseDuration;
26938 }
26939
26940 target._debugID = source._debugID;
26941 target._debugSource = source._debugSource;
26942 target._debugOwner = source._debugOwner;
26943 target._debugIsCurrentlyTiming = source._debugIsCurrentlyTiming;
26944 target._debugNeedsRemount = source._debugNeedsRemount;
26945 target._debugHookTypes = source._debugHookTypes;
26946 return target;
26947}
26948
26949function FiberRootNode(containerInfo, tag, hydrate) {
26950 this.tag = tag;
26951 this.current = null;
26952 this.containerInfo = containerInfo;
26953 this.pendingChildren = null;
26954 this.pingCache = null;
26955 this.finishedExpirationTime = NoWork;
26956 this.finishedWork = null;
26957 this.timeoutHandle = noTimeout;
26958 this.context = null;
26959 this.pendingContext = null;
26960 this.hydrate = hydrate;
26961 this.callbackNode = null;
26962 this.callbackPriority = NoPriority;
26963 this.firstPendingTime = NoWork;
26964 this.firstSuspendedTime = NoWork;
26965 this.lastSuspendedTime = NoWork;
26966 this.nextKnownPendingLevel = NoWork;
26967 this.lastPingedTime = NoWork;
26968 this.lastExpiredTime = NoWork;
26969
26970 if (enableSchedulerTracing) {
26971 this.interactionThreadID = unstable_getThreadID();
26972 this.memoizedInteractions = new Set();
26973 this.pendingInteractionMap = new Map();
26974 }
26975
26976 if (enableSuspenseCallback) {
26977 this.hydrationCallbacks = null;
26978 }
26979}
26980
26981function createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks) {
26982 var root = new FiberRootNode(containerInfo, tag, hydrate);
26983
26984 if (enableSuspenseCallback) {
26985 root.hydrationCallbacks = hydrationCallbacks;
26986 } // Cyclic construction. This cheats the type system right now because
26987 // stateNode is any.
26988
26989
26990 var uninitializedFiber = createHostRootFiber(tag);
26991 root.current = uninitializedFiber;
26992 uninitializedFiber.stateNode = root;
26993 return root;
26994}
26995function isRootSuspendedAtTime(root, expirationTime) {
26996 var firstSuspendedTime = root.firstSuspendedTime;
26997 var lastSuspendedTime = root.lastSuspendedTime;
26998 return firstSuspendedTime !== NoWork && firstSuspendedTime >= expirationTime && lastSuspendedTime <= expirationTime;
26999}
27000function markRootSuspendedAtTime(root, expirationTime) {
27001 var firstSuspendedTime = root.firstSuspendedTime;
27002 var lastSuspendedTime = root.lastSuspendedTime;
27003
27004 if (firstSuspendedTime < expirationTime) {
27005 root.firstSuspendedTime = expirationTime;
27006 }
27007
27008 if (lastSuspendedTime > expirationTime || firstSuspendedTime === NoWork) {
27009 root.lastSuspendedTime = expirationTime;
27010 }
27011
27012 if (expirationTime <= root.lastPingedTime) {
27013 root.lastPingedTime = NoWork;
27014 }
27015
27016 if (expirationTime <= root.lastExpiredTime) {
27017 root.lastExpiredTime = NoWork;
27018 }
27019}
27020function markRootUpdatedAtTime(root, expirationTime) {
27021 // Update the range of pending times
27022 var firstPendingTime = root.firstPendingTime;
27023
27024 if (expirationTime > firstPendingTime) {
27025 root.firstPendingTime = expirationTime;
27026 } // Update the range of suspended times. Treat everything lower priority or
27027 // equal to this update as unsuspended.
27028
27029
27030 var firstSuspendedTime = root.firstSuspendedTime;
27031
27032 if (firstSuspendedTime !== NoWork) {
27033 if (expirationTime >= firstSuspendedTime) {
27034 // The entire suspended range is now unsuspended.
27035 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
27036 } else if (expirationTime >= root.lastSuspendedTime) {
27037 root.lastSuspendedTime = expirationTime + 1;
27038 } // This is a pending level. Check if it's higher priority than the next
27039 // known pending level.
27040
27041
27042 if (expirationTime > root.nextKnownPendingLevel) {
27043 root.nextKnownPendingLevel = expirationTime;
27044 }
27045 }
27046}
27047function markRootFinishedAtTime(root, finishedExpirationTime, remainingExpirationTime) {
27048 // Update the range of pending times
27049 root.firstPendingTime = remainingExpirationTime; // Update the range of suspended times. Treat everything higher priority or
27050 // equal to this update as unsuspended.
27051
27052 if (finishedExpirationTime <= root.lastSuspendedTime) {
27053 // The entire suspended range is now unsuspended.
27054 root.firstSuspendedTime = root.lastSuspendedTime = root.nextKnownPendingLevel = NoWork;
27055 } else if (finishedExpirationTime <= root.firstSuspendedTime) {
27056 // Part of the suspended range is now unsuspended. Narrow the range to
27057 // include everything between the unsuspended time (non-inclusive) and the
27058 // last suspended time.
27059 root.firstSuspendedTime = finishedExpirationTime - 1;
27060 }
27061
27062 if (finishedExpirationTime <= root.lastPingedTime) {
27063 // Clear the pinged time
27064 root.lastPingedTime = NoWork;
27065 }
27066
27067 if (finishedExpirationTime <= root.lastExpiredTime) {
27068 // Clear the expired time
27069 root.lastExpiredTime = NoWork;
27070 }
27071}
27072function markRootExpiredAtTime(root, expirationTime) {
27073 var lastExpiredTime = root.lastExpiredTime;
27074
27075 if (lastExpiredTime === NoWork || lastExpiredTime > expirationTime) {
27076 root.lastExpiredTime = expirationTime;
27077 }
27078}
27079
27080// This lets us hook into Fiber to debug what it's doing.
27081// See https://github.com/facebook/react/pull/8033.
27082// This is not part of the public API, not even for React DevTools.
27083// You may only inject a debugTool if you work on React Fiber itself.
27084var ReactFiberInstrumentation = {
27085 debugTool: null
27086};
27087var ReactFiberInstrumentation_1 = ReactFiberInstrumentation;
27088
27089var didWarnAboutNestedUpdates;
27090var didWarnAboutFindNodeInStrictMode;
27091
27092{
27093 didWarnAboutNestedUpdates = false;
27094 didWarnAboutFindNodeInStrictMode = {};
27095}
27096
27097function getContextForSubtree(parentComponent) {
27098 if (!parentComponent) {
27099 return emptyContextObject;
27100 }
27101
27102 var fiber = get(parentComponent);
27103 var parentContext = findCurrentUnmaskedContext(fiber);
27104
27105 if (fiber.tag === ClassComponent) {
27106 var Component = fiber.type;
27107
27108 if (isContextProvider(Component)) {
27109 return processChildContext(fiber, Component, parentContext);
27110 }
27111 }
27112
27113 return parentContext;
27114}
27115
27116function findHostInstance(component) {
27117 var fiber = get(component);
27118
27119 if (fiber === undefined) {
27120 if (typeof component.render === 'function') {
27121 {
27122 {
27123 throw Error("Unable to find node on an unmounted component.");
27124 }
27125 }
27126 } else {
27127 {
27128 {
27129 throw Error("Argument appears to not be a ReactComponent. Keys: " + Object.keys(component));
27130 }
27131 }
27132 }
27133 }
27134
27135 var hostFiber = findCurrentHostFiber(fiber);
27136
27137 if (hostFiber === null) {
27138 return null;
27139 }
27140
27141 return hostFiber.stateNode;
27142}
27143
27144function findHostInstanceWithWarning(component, methodName) {
27145 {
27146 var fiber = get(component);
27147
27148 if (fiber === undefined) {
27149 if (typeof component.render === 'function') {
27150 {
27151 {
27152 throw Error("Unable to find node on an unmounted component.");
27153 }
27154 }
27155 } else {
27156 {
27157 {
27158 throw Error("Argument appears to not be a ReactComponent. Keys: " + Object.keys(component));
27159 }
27160 }
27161 }
27162 }
27163
27164 var hostFiber = findCurrentHostFiber(fiber);
27165
27166 if (hostFiber === null) {
27167 return null;
27168 }
27169
27170 if (hostFiber.mode & StrictMode) {
27171 var componentName = getComponentName(fiber.type) || 'Component';
27172
27173 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
27174 didWarnAboutFindNodeInStrictMode[componentName] = true;
27175
27176 if (fiber.mode & StrictMode) {
27177 warningWithoutStack$1(false, '%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which is inside StrictMode. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-find-node%s', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));
27178 } else {
27179 warningWithoutStack$1(false, '%s is deprecated in StrictMode. ' + '%s was passed an instance of %s which renders StrictMode children. ' + 'Instead, add a ref directly to the element you want to reference. ' + 'Learn more about using refs safely here: ' + 'https://fb.me/react-strict-mode-find-node%s', methodName, methodName, componentName, getStackByFiberInDevAndProd(hostFiber));
27180 }
27181 }
27182 }
27183
27184 return hostFiber.stateNode;
27185 }
27186
27187 return findHostInstance(component);
27188}
27189
27190function createContainer(containerInfo, tag, hydrate, hydrationCallbacks) {
27191 return createFiberRoot(containerInfo, tag, hydrate, hydrationCallbacks);
27192}
27193function updateContainer(element, container, parentComponent, callback) {
27194 var current$$1 = container.current;
27195 var currentTime = requestCurrentTimeForUpdate();
27196
27197 {
27198 // $FlowExpectedError - jest isn't a global, and isn't recognized outside of tests
27199 if ('undefined' !== typeof jest) {
27200 warnIfUnmockedScheduler(current$$1);
27201 warnIfNotScopedWithMatchingAct(current$$1);
27202 }
27203 }
27204
27205 var suspenseConfig = requestCurrentSuspenseConfig();
27206 var expirationTime = computeExpirationForFiber(currentTime, current$$1, suspenseConfig);
27207
27208 {
27209 if (ReactFiberInstrumentation_1.debugTool) {
27210 if (current$$1.alternate === null) {
27211 ReactFiberInstrumentation_1.debugTool.onMountContainer(container);
27212 } else if (element === null) {
27213 ReactFiberInstrumentation_1.debugTool.onUnmountContainer(container);
27214 } else {
27215 ReactFiberInstrumentation_1.debugTool.onUpdateContainer(container);
27216 }
27217 }
27218 }
27219
27220 var context = getContextForSubtree(parentComponent);
27221
27222 if (container.context === null) {
27223 container.context = context;
27224 } else {
27225 container.pendingContext = context;
27226 }
27227
27228 {
27229 if (phase === 'render' && current !== null && !didWarnAboutNestedUpdates) {
27230 didWarnAboutNestedUpdates = true;
27231 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.type) || 'Unknown');
27232 }
27233 }
27234
27235 var update = createUpdate(expirationTime, suspenseConfig); // Caution: React DevTools currently depends on this property
27236 // being called "element".
27237
27238 update.payload = {
27239 element: element
27240 };
27241 callback = callback === undefined ? null : callback;
27242
27243 if (callback !== null) {
27244 !(typeof callback === 'function') ? warningWithoutStack$1(false, 'render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback) : void 0;
27245 update.callback = callback;
27246 }
27247
27248 enqueueUpdate(current$$1, update);
27249 scheduleWork(current$$1, expirationTime);
27250 return expirationTime;
27251}
27252function getPublicRootInstance(container) {
27253 var containerFiber = container.current;
27254
27255 if (!containerFiber.child) {
27256 return null;
27257 }
27258
27259 switch (containerFiber.child.tag) {
27260 case HostComponent:
27261 return getPublicInstance(containerFiber.child.stateNode);
27262
27263 default:
27264 return containerFiber.child.stateNode;
27265 }
27266}
27267function attemptSynchronousHydration$1(fiber) {
27268 switch (fiber.tag) {
27269 case HostRoot:
27270 var root = fiber.stateNode;
27271
27272 if (root.hydrate) {
27273 // Flush the first scheduled "update".
27274 flushRoot(root, root.firstPendingTime);
27275 }
27276
27277 break;
27278
27279 case SuspenseComponent:
27280 flushSync(function () {
27281 return scheduleWork(fiber, Sync);
27282 }); // If we're still blocked after this, we need to increase
27283 // the priority of any promises resolving within this
27284 // boundary so that they next attempt also has higher pri.
27285
27286 var retryExpTime = computeInteractiveExpiration(requestCurrentTimeForUpdate());
27287 markRetryTimeIfNotHydrated(fiber, retryExpTime);
27288 break;
27289 }
27290}
27291
27292function markRetryTimeImpl(fiber, retryTime) {
27293 var suspenseState = fiber.memoizedState;
27294
27295 if (suspenseState !== null && suspenseState.dehydrated !== null) {
27296 if (suspenseState.retryTime < retryTime) {
27297 suspenseState.retryTime = retryTime;
27298 }
27299 }
27300} // Increases the priority of thennables when they resolve within this boundary.
27301
27302
27303function markRetryTimeIfNotHydrated(fiber, retryTime) {
27304 markRetryTimeImpl(fiber, retryTime);
27305 var alternate = fiber.alternate;
27306
27307 if (alternate) {
27308 markRetryTimeImpl(alternate, retryTime);
27309 }
27310}
27311
27312function attemptUserBlockingHydration$1(fiber) {
27313 if (fiber.tag !== SuspenseComponent) {
27314 // We ignore HostRoots here because we can't increase
27315 // their priority and they should not suspend on I/O,
27316 // since you have to wrap anything that might suspend in
27317 // Suspense.
27318 return;
27319 }
27320
27321 var expTime = computeInteractiveExpiration(requestCurrentTimeForUpdate());
27322 scheduleWork(fiber, expTime);
27323 markRetryTimeIfNotHydrated(fiber, expTime);
27324}
27325function attemptContinuousHydration$1(fiber) {
27326 if (fiber.tag !== SuspenseComponent) {
27327 // We ignore HostRoots here because we can't increase
27328 // their priority and they should not suspend on I/O,
27329 // since you have to wrap anything that might suspend in
27330 // Suspense.
27331 return;
27332 }
27333
27334 var expTime = computeContinuousHydrationExpiration(requestCurrentTimeForUpdate());
27335 scheduleWork(fiber, expTime);
27336 markRetryTimeIfNotHydrated(fiber, expTime);
27337}
27338function attemptHydrationAtCurrentPriority$1(fiber) {
27339 if (fiber.tag !== SuspenseComponent) {
27340 // We ignore HostRoots here because we can't increase
27341 // their priority other than synchronously flush it.
27342 return;
27343 }
27344
27345 var currentTime = requestCurrentTimeForUpdate();
27346 var expTime = computeExpirationForFiber(currentTime, fiber, null);
27347 scheduleWork(fiber, expTime);
27348 markRetryTimeIfNotHydrated(fiber, expTime);
27349}
27350function findHostInstanceWithNoPortals(fiber) {
27351 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
27352
27353 if (hostFiber === null) {
27354 return null;
27355 }
27356
27357 if (hostFiber.tag === FundamentalComponent) {
27358 return hostFiber.stateNode.instance;
27359 }
27360
27361 return hostFiber.stateNode;
27362}
27363
27364var shouldSuspendImpl = function (fiber) {
27365 return false;
27366};
27367
27368function shouldSuspend(fiber) {
27369 return shouldSuspendImpl(fiber);
27370}
27371var overrideHookState = null;
27372var overrideProps = null;
27373var scheduleUpdate = null;
27374var setSuspenseHandler = null;
27375
27376{
27377 var copyWithSetImpl = function (obj, path, idx, value) {
27378 if (idx >= path.length) {
27379 return value;
27380 }
27381
27382 var key = path[idx];
27383 var updated = Array.isArray(obj) ? obj.slice() : _assign({}, obj); // $FlowFixMe number or string is fine here
27384
27385 updated[key] = copyWithSetImpl(obj[key], path, idx + 1, value);
27386 return updated;
27387 };
27388
27389 var copyWithSet = function (obj, path, value) {
27390 return copyWithSetImpl(obj, path, 0, value);
27391 }; // Support DevTools editable values for useState and useReducer.
27392
27393
27394 overrideHookState = function (fiber, id, path, value) {
27395 // For now, the "id" of stateful hooks is just the stateful hook index.
27396 // This may change in the future with e.g. nested hooks.
27397 var currentHook = fiber.memoizedState;
27398
27399 while (currentHook !== null && id > 0) {
27400 currentHook = currentHook.next;
27401 id--;
27402 }
27403
27404 if (currentHook !== null) {
27405 var newState = copyWithSet(currentHook.memoizedState, path, value);
27406 currentHook.memoizedState = newState;
27407 currentHook.baseState = newState; // We aren't actually adding an update to the queue,
27408 // because there is no update we can add for useReducer hooks that won't trigger an error.
27409 // (There's no appropriate action type for DevTools overrides.)
27410 // As a result though, React will see the scheduled update as a noop and bailout.
27411 // Shallow cloning props works as a workaround for now to bypass the bailout check.
27412
27413 fiber.memoizedProps = _assign({}, fiber.memoizedProps);
27414 scheduleWork(fiber, Sync);
27415 }
27416 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
27417
27418
27419 overrideProps = function (fiber, path, value) {
27420 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
27421
27422 if (fiber.alternate) {
27423 fiber.alternate.pendingProps = fiber.pendingProps;
27424 }
27425
27426 scheduleWork(fiber, Sync);
27427 };
27428
27429 scheduleUpdate = function (fiber) {
27430 scheduleWork(fiber, Sync);
27431 };
27432
27433 setSuspenseHandler = function (newShouldSuspendImpl) {
27434 shouldSuspendImpl = newShouldSuspendImpl;
27435 };
27436}
27437
27438function injectIntoDevTools(devToolsConfig) {
27439 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
27440 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
27441 return injectInternals(_assign({}, devToolsConfig, {
27442 overrideHookState: overrideHookState,
27443 overrideProps: overrideProps,
27444 setSuspenseHandler: setSuspenseHandler,
27445 scheduleUpdate: scheduleUpdate,
27446 currentDispatcherRef: ReactCurrentDispatcher,
27447 findHostInstanceByFiber: function (fiber) {
27448 var hostFiber = findCurrentHostFiber(fiber);
27449
27450 if (hostFiber === null) {
27451 return null;
27452 }
27453
27454 return hostFiber.stateNode;
27455 },
27456 findFiberByHostInstance: function (instance) {
27457 if (!findFiberByHostInstance) {
27458 // Might not be implemented by the renderer.
27459 return null;
27460 }
27461
27462 return findFiberByHostInstance(instance);
27463 },
27464 // React Refresh
27465 findHostInstancesForRefresh: findHostInstancesForRefresh,
27466 scheduleRefresh: scheduleRefresh,
27467 scheduleRoot: scheduleRoot,
27468 setRefreshHandler: setRefreshHandler,
27469 // Enables DevTools to append owner stacks to error messages in DEV mode.
27470 getCurrentFiber: function () {
27471 return current;
27472 }
27473 }));
27474}
27475
27476// This file intentionally does *not* have the Flow annotation.
27477// Don't add it. See `./inline-typed.js` for an explanation.
27478
27479// TODO: This type is shared between the reconciler and ReactDOM, but will
27480// eventually be lifted out to the renderer.
27481function ReactDOMRoot(container, options) {
27482 this._internalRoot = createRootImpl(container, ConcurrentRoot, options);
27483}
27484
27485function ReactDOMBlockingRoot(container, tag, options) {
27486 this._internalRoot = createRootImpl(container, tag, options);
27487}
27488
27489ReactDOMRoot.prototype.render = ReactDOMBlockingRoot.prototype.render = function (children, callback) {
27490 var root = this._internalRoot;
27491 var cb = callback === undefined ? null : callback;
27492
27493 {
27494 warnOnInvalidCallback(cb, 'render');
27495 }
27496
27497 updateContainer(children, root, null, cb);
27498};
27499
27500ReactDOMRoot.prototype.unmount = ReactDOMBlockingRoot.prototype.unmount = function (callback) {
27501 var root = this._internalRoot;
27502 var cb = callback === undefined ? null : callback;
27503
27504 {
27505 warnOnInvalidCallback(cb, 'render');
27506 }
27507
27508 var container = root.containerInfo;
27509 updateContainer(null, root, null, function () {
27510 unmarkContainerAsRoot(container);
27511
27512 if (cb !== null) {
27513 cb();
27514 }
27515 });
27516};
27517
27518function createRootImpl(container, tag, options) {
27519 // Tag is either LegacyRoot or Concurrent Root
27520 var hydrate = options != null && options.hydrate === true;
27521 var hydrationCallbacks = options != null && options.hydrationOptions || null;
27522 var root = createContainer(container, tag, hydrate, hydrationCallbacks);
27523 markContainerAsRoot(root.current, container);
27524
27525 if (hydrate && tag !== LegacyRoot) {
27526 var doc = container.nodeType === DOCUMENT_NODE ? container : container.ownerDocument;
27527 eagerlyTrapReplayableEvents(doc);
27528 }
27529
27530 return root;
27531}
27532
27533function createRoot(container, options) {
27534 if (!isValidContainer(container)) {
27535 {
27536 throw Error("createRoot(...): Target container is not a DOM element.");
27537 }
27538 }
27539
27540 warnIfReactDOMContainerInDEV(container);
27541 return new ReactDOMRoot(container, options);
27542}
27543function createBlockingRoot(container, options) {
27544 if (!isValidContainer(container)) {
27545 {
27546 throw Error("createRoot(...): Target container is not a DOM element.");
27547 }
27548 }
27549
27550 warnIfReactDOMContainerInDEV(container);
27551 return new ReactDOMBlockingRoot(container, BlockingRoot, options);
27552}
27553function createLegacyRoot(container, options) {
27554 return new ReactDOMBlockingRoot(container, LegacyRoot, options);
27555}
27556function isValidContainer(node) {
27557 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || node.nodeType === COMMENT_NODE && node.nodeValue === ' react-mount-point-unstable '));
27558}
27559function warnOnInvalidCallback(callback, callerName) {
27560 {
27561 !(callback === null || typeof callback === 'function') ? warningWithoutStack$1(false, '%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback) : void 0;
27562 }
27563}
27564
27565function warnIfReactDOMContainerInDEV(container) {
27566 {
27567 if (isContainerMarkedAsRoot(container)) {
27568 if (container._reactRootContainer) {
27569 warningWithoutStack$1(false, 'You are calling ReactDOM.createRoot() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.');
27570 } else {
27571 warningWithoutStack$1(false, 'You are calling ReactDOM.createRoot() on a container that ' + 'has already been passed to createRoot() before. Instead, call ' + 'root.render() on the existing root instead if you want to update it.');
27572 }
27573 }
27574 }
27575}
27576
27577var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
27578var topLevelUpdateWarnings;
27579var warnedAboutHydrateAPI = false;
27580
27581{
27582 topLevelUpdateWarnings = function (container) {
27583 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
27584 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer._internalRoot.current);
27585
27586 if (hostInstance) {
27587 !(hostInstance.parentNode === container) ? warningWithoutStack$1(false, 'render(...): It looks like the React-rendered content of this ' + 'container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + 'ReactDOM.unmountComponentAtNode to empty a container.') : void 0;
27588 }
27589 }
27590
27591 var isRootRenderedBySomeReact = !!container._reactRootContainer;
27592 var rootEl = getReactRootElementInContainer(container);
27593 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode$1(rootEl));
27594 !(!hasNonRootReactChild || isRootRenderedBySomeReact) ? warningWithoutStack$1(false, 'render(...): Replacing React-rendered children with a new root ' + 'component. If you intended to update the children of this node, ' + 'you should instead have the existing children update their state ' + 'and render the new components instead of calling ReactDOM.render.') : void 0;
27595 !(container.nodeType !== ELEMENT_NODE || !container.tagName || container.tagName.toUpperCase() !== 'BODY') ? warningWithoutStack$1(false, 'render(): Rendering components directly into document.body is ' + 'discouraged, since its children are often manipulated by third-party ' + 'scripts and browser extensions. This may lead to subtle ' + 'reconciliation issues. Try rendering into a container element created ' + 'for your app.') : void 0;
27596 };
27597}
27598
27599function getReactRootElementInContainer(container) {
27600 if (!container) {
27601 return null;
27602 }
27603
27604 if (container.nodeType === DOCUMENT_NODE) {
27605 return container.documentElement;
27606 } else {
27607 return container.firstChild;
27608 }
27609}
27610
27611function shouldHydrateDueToLegacyHeuristic(container) {
27612 var rootElement = getReactRootElementInContainer(container);
27613 return !!(rootElement && rootElement.nodeType === ELEMENT_NODE && rootElement.hasAttribute(ROOT_ATTRIBUTE_NAME));
27614}
27615
27616function legacyCreateRootFromDOMContainer(container, forceHydrate) {
27617 var shouldHydrate = forceHydrate || shouldHydrateDueToLegacyHeuristic(container); // First clear any existing content.
27618
27619 if (!shouldHydrate) {
27620 var warned = false;
27621 var rootSibling;
27622
27623 while (rootSibling = container.lastChild) {
27624 {
27625 if (!warned && rootSibling.nodeType === ELEMENT_NODE && rootSibling.hasAttribute(ROOT_ATTRIBUTE_NAME)) {
27626 warned = true;
27627 warningWithoutStack$1(false, 'render(): Target node has markup rendered by React, but there ' + 'are unrelated nodes as well. This is most commonly caused by ' + 'white-space inserted around server-rendered markup.');
27628 }
27629 }
27630
27631 container.removeChild(rootSibling);
27632 }
27633 }
27634
27635 {
27636 if (shouldHydrate && !forceHydrate && !warnedAboutHydrateAPI) {
27637 warnedAboutHydrateAPI = true;
27638 lowPriorityWarningWithoutStack$1(false, 'render(): Calling ReactDOM.render() to hydrate server-rendered markup ' + 'will stop working in React v17. Replace the ReactDOM.render() call ' + 'with ReactDOM.hydrate() if you want React to attach to the server HTML.');
27639 }
27640 }
27641
27642 return createLegacyRoot(container, shouldHydrate ? {
27643 hydrate: true
27644 } : undefined);
27645}
27646
27647function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
27648 {
27649 topLevelUpdateWarnings(container);
27650 warnOnInvalidCallback(callback === undefined ? null : callback, 'render');
27651 } // TODO: Without `any` type, Flow says "Property cannot be accessed on any
27652 // member of intersection type." Whyyyyyy.
27653
27654
27655 var root = container._reactRootContainer;
27656 var fiberRoot;
27657
27658 if (!root) {
27659 // Initial mount
27660 root = container._reactRootContainer = legacyCreateRootFromDOMContainer(container, forceHydrate);
27661 fiberRoot = root._internalRoot;
27662
27663 if (typeof callback === 'function') {
27664 var originalCallback = callback;
27665
27666 callback = function () {
27667 var instance = getPublicRootInstance(fiberRoot);
27668 originalCallback.call(instance);
27669 };
27670 } // Initial mount should not be batched.
27671
27672
27673 unbatchedUpdates(function () {
27674 updateContainer(children, fiberRoot, parentComponent, callback);
27675 });
27676 } else {
27677 fiberRoot = root._internalRoot;
27678
27679 if (typeof callback === 'function') {
27680 var _originalCallback = callback;
27681
27682 callback = function () {
27683 var instance = getPublicRootInstance(fiberRoot);
27684
27685 _originalCallback.call(instance);
27686 };
27687 } // Update
27688
27689
27690 updateContainer(children, fiberRoot, parentComponent, callback);
27691 }
27692
27693 return getPublicRootInstance(fiberRoot);
27694}
27695
27696function findDOMNode(componentOrElement) {
27697 {
27698 var owner = ReactCurrentOwner$1.current;
27699
27700 if (owner !== null && owner.stateNode !== null) {
27701 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
27702 !warnedAboutRefsInRender ? warningWithoutStack$1(false, '%s is accessing findDOMNode inside its render(). ' + '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(owner.type) || 'A component') : void 0;
27703 owner.stateNode._warnedAboutRefsInRender = true;
27704 }
27705 }
27706
27707 if (componentOrElement == null) {
27708 return null;
27709 }
27710
27711 if (componentOrElement.nodeType === ELEMENT_NODE) {
27712 return componentOrElement;
27713 }
27714
27715 {
27716 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
27717 }
27718
27719 return findHostInstance(componentOrElement);
27720}
27721function hydrate(element, container, callback) {
27722 if (!isValidContainer(container)) {
27723 {
27724 throw Error("Target container is not a DOM element.");
27725 }
27726 }
27727
27728 {
27729 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
27730
27731 if (isModernRoot) {
27732 warningWithoutStack$1(false, 'You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call createRoot(container, {hydrate: true}).render(element)?');
27733 }
27734 } // TODO: throw or warn if we couldn't hydrate?
27735
27736
27737 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
27738}
27739function render(element, container, callback) {
27740 if (!isValidContainer(container)) {
27741 {
27742 throw Error("Target container is not a DOM element.");
27743 }
27744 }
27745
27746 {
27747 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
27748
27749 if (isModernRoot) {
27750 warningWithoutStack$1(false, 'You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?');
27751 }
27752 }
27753
27754 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
27755}
27756function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
27757 if (!isValidContainer(containerNode)) {
27758 {
27759 throw Error("Target container is not a DOM element.");
27760 }
27761 }
27762
27763 if (!(parentComponent != null && has$1(parentComponent))) {
27764 {
27765 throw Error("parentComponent must be a valid React Component");
27766 }
27767 }
27768
27769 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
27770}
27771function unmountComponentAtNode(container) {
27772 if (!isValidContainer(container)) {
27773 {
27774 throw Error("unmountComponentAtNode(...): Target container is not a DOM element.");
27775 }
27776 }
27777
27778 {
27779 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
27780
27781 if (isModernRoot) {
27782 warningWithoutStack$1(false, 'You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOM.createRoot(). This is not supported. Did you mean to call root.unmount()?');
27783 }
27784 }
27785
27786 if (container._reactRootContainer) {
27787 {
27788 var rootEl = getReactRootElementInContainer(container);
27789 var renderedByDifferentReact = rootEl && !getInstanceFromNode$1(rootEl);
27790 !!renderedByDifferentReact ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.') : void 0;
27791 } // Unmount should not be batched.
27792
27793
27794 unbatchedUpdates(function () {
27795 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
27796 container._reactRootContainer = null;
27797 unmarkContainerAsRoot(container);
27798 });
27799 }); // If you call unmountComponentAtNode twice in quick succession, you'll
27800 // get `true` twice. That's probably fine?
27801
27802 return true;
27803 } else {
27804 {
27805 var _rootEl = getReactRootElementInContainer(container);
27806
27807 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode$1(_rootEl)); // Check if the container itself is a React root node.
27808
27809 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainer(container.parentNode) && !!container.parentNode._reactRootContainer;
27810 !!hasNonRootReactChild ? warningWithoutStack$1(false, "unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by React and is not a top-level container. %s', isContainerReactRoot ? 'You may have accidentally passed in a React root node instead ' + 'of its container.' : 'Instead, have the parent component update its state and ' + 'rerender in order to remove this component.') : void 0;
27811 }
27812
27813 return false;
27814 }
27815}
27816
27817function createPortal$1(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
27818implementation) {
27819 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
27820 return {
27821 // This tag allow us to uniquely identify this as a React Portal
27822 $$typeof: REACT_PORTAL_TYPE,
27823 key: key == null ? null : '' + key,
27824 children: children,
27825 containerInfo: containerInfo,
27826 implementation: implementation
27827 };
27828}
27829
27830// TODO: this is special because it gets imported during build.
27831
27832var ReactVersion = '16.12.0';
27833
27834setAttemptSynchronousHydration(attemptSynchronousHydration$1);
27835setAttemptUserBlockingHydration(attemptUserBlockingHydration$1);
27836setAttemptContinuousHydration(attemptContinuousHydration$1);
27837setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
27838var didWarnAboutUnstableCreatePortal = false;
27839
27840{
27841 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
27842 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
27843 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
27844 warningWithoutStack$1(false, 'React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
27845 }
27846}
27847
27848setRestoreImplementation(restoreControlledState$$1);
27849setBatchingImplementation(batchedUpdates$1, discreteUpdates$1, flushDiscreteUpdates, batchedEventUpdates$1);
27850
27851function createPortal$$1(children, container) {
27852 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
27853
27854 if (!isValidContainer(container)) {
27855 {
27856 throw Error("Target container is not a DOM element.");
27857 }
27858 } // TODO: pass ReactDOM portal implementation as third argument
27859
27860
27861 return createPortal$1(children, container, null, key);
27862}
27863
27864var ReactDOM = {
27865 createPortal: createPortal$$1,
27866 // Legacy
27867 findDOMNode: findDOMNode,
27868 hydrate: hydrate,
27869 render: render,
27870 unstable_renderSubtreeIntoContainer: unstable_renderSubtreeIntoContainer,
27871 unmountComponentAtNode: unmountComponentAtNode,
27872 // Temporary alias since we already shipped React 16 RC with it.
27873 // TODO: remove in React 17.
27874 unstable_createPortal: function () {
27875 if (!didWarnAboutUnstableCreatePortal) {
27876 didWarnAboutUnstableCreatePortal = true;
27877 lowPriorityWarningWithoutStack$1(false, 'The ReactDOM.unstable_createPortal() alias has been deprecated, ' + 'and will be removed in React 17+. Update your code to use ' + 'ReactDOM.createPortal() instead. It has the exact same API, ' + 'but without the "unstable_" prefix.');
27878 }
27879
27880 return createPortal$$1.apply(void 0, arguments);
27881 },
27882 unstable_batchedUpdates: batchedUpdates$1,
27883 flushSync: flushSync,
27884 __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {
27885 // Keep in sync with ReactDOMUnstableNativeDependencies.js
27886 // ReactTestUtils.js, and ReactTestUtilsAct.js. This is an array for better minification.
27887 Events: [getInstanceFromNode$1, getNodeFromInstance$1, getFiberCurrentPropsFromNode$1, injection.injectEventPluginsByName, eventNameDispatchConfigs, accumulateTwoPhaseDispatches, accumulateDirectDispatches, enqueueStateRestore, restoreStateIfNeeded, dispatchEvent, runEventsInBatch, flushPassiveEffects, IsThisRendererActing]
27888 }
27889};
27890
27891if (exposeConcurrentModeAPIs) {
27892 ReactDOM.createRoot = createRoot;
27893 ReactDOM.createBlockingRoot = createBlockingRoot;
27894 ReactDOM.unstable_discreteUpdates = discreteUpdates$1;
27895 ReactDOM.unstable_flushDiscreteUpdates = flushDiscreteUpdates;
27896 ReactDOM.unstable_flushControlled = flushControlled;
27897
27898 ReactDOM.unstable_scheduleHydration = function (target) {
27899 if (target) {
27900 queueExplicitHydrationTarget(target);
27901 }
27902 };
27903}
27904
27905var foundDevTools = injectIntoDevTools({
27906 findFiberByHostInstance: getClosestInstanceFromNode,
27907 bundleType: 1,
27908 version: ReactVersion,
27909 rendererPackageName: 'react-dom'
27910});
27911
27912{
27913 if (!foundDevTools && canUseDOM && window.top === window.self) {
27914 // If we're in Chrome or Firefox, provide a download link if not installed.
27915 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
27916 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
27917
27918 if (/^(https?|file):$/.test(protocol)) {
27919 console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://fb.me/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://fb.me/react-devtools-faq' : ''), 'font-weight:bold');
27920 }
27921 }
27922 }
27923}
27924
27925
27926
27927var ReactDOM$2 = Object.freeze({
27928 default: ReactDOM
27929});
27930
27931var ReactDOM$3 = ( ReactDOM$2 && ReactDOM ) || ReactDOM$2;
27932
27933// TODO: decide on the top-level export form.
27934// This is hacky but makes it work with both Rollup and Jest.
27935
27936
27937var reactDom = ReactDOM$3.default || ReactDOM$3;
27938
27939return reactDom;
27940
27941})));