UNPKG

1.03 MBJavaScriptView Raw
1/**
2 * @license React
3 * react-dom.development.js
4 *
5 * Copyright (c) Facebook, Inc. and its affiliates.
6 *
7 * This source code is licensed under the MIT license found in the
8 * LICENSE file in the root directory of this source tree.
9 */
10
11'use strict';
12
13if (process.env.NODE_ENV !== "production") {
14 (function() {
15
16 'use strict';
17
18/* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
19if (
20 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
21 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart ===
22 'function'
23) {
24 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
25}
26 var React = require('react');
27var Scheduler = require('scheduler');
28
29var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
30
31var suppressWarning = false;
32function setSuppressWarning(newSuppressWarning) {
33 {
34 suppressWarning = newSuppressWarning;
35 }
36} // In DEV, calls to console.warn and console.error get replaced
37// by calls to these methods by a Babel plugin.
38//
39// In PROD (or in packages without access to React internals),
40// they are left as they are instead.
41
42function warn(format) {
43 {
44 if (!suppressWarning) {
45 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
46 args[_key - 1] = arguments[_key];
47 }
48
49 printWarning('warn', format, args);
50 }
51 }
52}
53function error(format) {
54 {
55 if (!suppressWarning) {
56 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
57 args[_key2 - 1] = arguments[_key2];
58 }
59
60 printWarning('error', format, args);
61 }
62 }
63}
64
65function printWarning(level, format, args) {
66 // When changing this logic, you might want to also
67 // update consoleWithStackDev.www.js as well.
68 {
69 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
70 var stack = ReactDebugCurrentFrame.getStackAddendum();
71
72 if (stack !== '') {
73 format += '%s';
74 args = args.concat([stack]);
75 } // eslint-disable-next-line react-internal/safe-string-coercion
76
77
78 var argsWithFormat = args.map(function (item) {
79 return String(item);
80 }); // Careful: RN currently depends on this prefix
81
82 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
83 // breaks IE9: https://github.com/facebook/react/issues/13610
84 // eslint-disable-next-line react-internal/no-production-logging
85
86 Function.prototype.apply.call(console[level], console, argsWithFormat);
87 }
88}
89
90var FunctionComponent = 0;
91var ClassComponent = 1;
92var IndeterminateComponent = 2; // Before we know whether it is function or class
93
94var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
95
96var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
97
98var HostComponent = 5;
99var HostText = 6;
100var Fragment = 7;
101var Mode = 8;
102var ContextConsumer = 9;
103var ContextProvider = 10;
104var ForwardRef = 11;
105var Profiler = 12;
106var SuspenseComponent = 13;
107var MemoComponent = 14;
108var SimpleMemoComponent = 15;
109var LazyComponent = 16;
110var IncompleteClassComponent = 17;
111var DehydratedFragment = 18;
112var SuspenseListComponent = 19;
113var ScopeComponent = 21;
114var OffscreenComponent = 22;
115var LegacyHiddenComponent = 23;
116var CacheComponent = 24;
117var TracingMarkerComponent = 25;
118
119// -----------------------------------------------------------------------------
120
121var enableClientRenderFallbackOnTextMismatch = true; // TODO: Need to review this code one more time before landing
122// the react-reconciler package.
123
124var enableNewReconciler = false; // Support legacy Primer support on internal FB www
125
126var enableLazyContextPropagation = false; // FB-only usage. The new API has different semantics.
127
128var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
129
130var enableSuspenseAvoidThisFallback = false; // Enables unstable_avoidThisFallback feature in Fizz
131// React DOM Chopping Block
132//
133// Similar to main Chopping Block but only flags related to React DOM. These are
134// grouped because we will likely batch all of them into a single major release.
135// -----------------------------------------------------------------------------
136// Disable support for comment nodes as React DOM containers. Already disabled
137// in open source, but www codebase still relies on it. Need to remove.
138
139var disableCommentsAsDOMContainers = true; // Disable javascript: URL strings in href for XSS protection.
140// and client rendering, mostly to allow JSX attributes to apply to the custom
141// element's object properties instead of only HTML attributes.
142// https://github.com/facebook/react/issues/11347
143
144var enableCustomElementPropertySupport = false; // Disables children for <textarea> elements
145var warnAboutStringRefs = false; // -----------------------------------------------------------------------------
146// Debugging and DevTools
147// -----------------------------------------------------------------------------
148// Adds user timing marks for e.g. state updates, suspense, and work loop stuff,
149// for an experimental timeline tool.
150
151var enableSchedulingProfiler = true; // Helps identify side effects in render-phase lifecycle hooks and setState
152
153var enableProfilerTimer = true; // Record durations for commit and passive effects phases.
154
155var enableProfilerCommitHooks = true; // Phase param passed to onRender callback differentiates between an "update" and a "cascading-update".
156
157var allNativeEvents = new Set();
158/**
159 * Mapping from registration name to event name
160 */
161
162
163var registrationNameDependencies = {};
164/**
165 * Mapping from lowercase registration names to the properly cased version,
166 * used to warn in the case of missing event handlers. Available
167 * only in true.
168 * @type {Object}
169 */
170
171var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
172
173function registerTwoPhaseEvent(registrationName, dependencies) {
174 registerDirectEvent(registrationName, dependencies);
175 registerDirectEvent(registrationName + 'Capture', dependencies);
176}
177function registerDirectEvent(registrationName, dependencies) {
178 {
179 if (registrationNameDependencies[registrationName]) {
180 error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName);
181 }
182 }
183
184 registrationNameDependencies[registrationName] = dependencies;
185
186 {
187 var lowerCasedName = registrationName.toLowerCase();
188 possibleRegistrationNames[lowerCasedName] = registrationName;
189
190 if (registrationName === 'onDoubleClick') {
191 possibleRegistrationNames.ondblclick = registrationName;
192 }
193 }
194
195 for (var i = 0; i < dependencies.length; i++) {
196 allNativeEvents.add(dependencies[i]);
197 }
198}
199
200var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
201
202var hasOwnProperty = Object.prototype.hasOwnProperty;
203
204/*
205 * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol
206 * and Temporal.* types. See https://github.com/facebook/react/pull/22064.
207 *
208 * The functions in this module will throw an easier-to-understand,
209 * easier-to-debug exception with a clear errors message message explaining the
210 * problem. (Instead of a confusing exception thrown inside the implementation
211 * of the `value` object).
212 */
213// $FlowFixMe only called in DEV, so void return is not possible.
214function typeName(value) {
215 {
216 // toStringTag is needed for namespaced types like Temporal.Instant
217 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;
218 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object';
219 return type;
220 }
221} // $FlowFixMe only called in DEV, so void return is not possible.
222
223
224function willCoercionThrow(value) {
225 {
226 try {
227 testStringCoercion(value);
228 return false;
229 } catch (e) {
230 return true;
231 }
232 }
233}
234
235function testStringCoercion(value) {
236 // If you ended up here by following an exception call stack, here's what's
237 // happened: you supplied an object or symbol value to React (as a prop, key,
238 // DOM attribute, CSS property, string ref, etc.) and when React tried to
239 // coerce it to a string using `'' + value`, an exception was thrown.
240 //
241 // The most common types that will cause this exception are `Symbol` instances
242 // and Temporal objects like `Temporal.Instant`. But any object that has a
243 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this
244 // exception. (Library authors do this to prevent users from using built-in
245 // numeric operators like `+` or comparison operators like `>=` because custom
246 // methods are needed to perform accurate arithmetic or comparison.)
247 //
248 // To fix the problem, coerce this object or symbol value to a string before
249 // passing it to React. The most reliable way is usually `String(value)`.
250 //
251 // To find which value is throwing, check the browser or debugger console.
252 // Before this exception was thrown, there should be `console.error` output
253 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the
254 // problem and how that type was used: key, atrribute, input value prop, etc.
255 // In most cases, this console output also shows the component and its
256 // ancestor components where the exception happened.
257 //
258 // eslint-disable-next-line react-internal/safe-string-coercion
259 return '' + value;
260}
261
262function checkAttributeStringCoercion(value, attributeName) {
263 {
264 if (willCoercionThrow(value)) {
265 error('The provided `%s` attribute is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', attributeName, typeName(value));
266
267 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
268 }
269 }
270}
271function checkKeyStringCoercion(value) {
272 {
273 if (willCoercionThrow(value)) {
274 error('The provided key is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
275
276 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
277 }
278 }
279}
280function checkPropStringCoercion(value, propName) {
281 {
282 if (willCoercionThrow(value)) {
283 error('The provided `%s` prop is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value));
284
285 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
286 }
287 }
288}
289function checkCSSPropertyStringCoercion(value, propName) {
290 {
291 if (willCoercionThrow(value)) {
292 error('The provided `%s` CSS property is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', propName, typeName(value));
293
294 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
295 }
296 }
297}
298function checkHtmlStringCoercion(value) {
299 {
300 if (willCoercionThrow(value)) {
301 error('The provided HTML markup uses a value of unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
302
303 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
304 }
305 }
306}
307function checkFormFieldValueStringCoercion(value) {
308 {
309 if (willCoercionThrow(value)) {
310 error('Form field values (value, checked, defaultValue, or defaultChecked props)' + ' must be strings, not %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
311
312 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
313 }
314 }
315}
316
317// A reserved attribute.
318// It is handled by React separately and shouldn't be written to the DOM.
319var RESERVED = 0; // A simple string attribute.
320// Attributes that aren't in the filter are presumed to have this type.
321
322var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
323// "enumerated" attributes with "true" and "false" as possible values.
324// When true, it should be set to a "true" string.
325// When false, it should be set to a "false" string.
326
327var BOOLEANISH_STRING = 2; // A real boolean attribute.
328// When true, it should be present (set either to an empty string or its name).
329// When false, it should be omitted.
330
331var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
332// When true, it should be present (set either to an empty string or its name).
333// When false, it should be omitted.
334// For any other value, should be present with that value.
335
336var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
337// When falsy, it should be removed.
338
339var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
340// When falsy, it should be removed.
341
342var POSITIVE_NUMERIC = 6;
343
344/* eslint-disable max-len */
345var 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";
346/* eslint-enable max-len */
347
348var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
349var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
350var illegalAttributeNameCache = {};
351var validatedAttributeNameCache = {};
352function isAttributeNameSafe(attributeName) {
353 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
354 return true;
355 }
356
357 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
358 return false;
359 }
360
361 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
362 validatedAttributeNameCache[attributeName] = true;
363 return true;
364 }
365
366 illegalAttributeNameCache[attributeName] = true;
367
368 {
369 error('Invalid attribute name: `%s`', attributeName);
370 }
371
372 return false;
373}
374function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
375 if (propertyInfo !== null) {
376 return propertyInfo.type === RESERVED;
377 }
378
379 if (isCustomComponentTag) {
380 return false;
381 }
382
383 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
384 return true;
385 }
386
387 return false;
388}
389function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
390 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
391 return false;
392 }
393
394 switch (typeof value) {
395 case 'function': // $FlowIssue symbol is perfectly valid here
396
397 case 'symbol':
398 // eslint-disable-line
399 return true;
400
401 case 'boolean':
402 {
403 if (isCustomComponentTag) {
404 return false;
405 }
406
407 if (propertyInfo !== null) {
408 return !propertyInfo.acceptsBooleans;
409 } else {
410 var prefix = name.toLowerCase().slice(0, 5);
411 return prefix !== 'data-' && prefix !== 'aria-';
412 }
413 }
414
415 default:
416 return false;
417 }
418}
419function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
420 if (value === null || typeof value === 'undefined') {
421 return true;
422 }
423
424 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
425 return true;
426 }
427
428 if (isCustomComponentTag) {
429
430 return false;
431 }
432
433 if (propertyInfo !== null) {
434
435 switch (propertyInfo.type) {
436 case BOOLEAN:
437 return !value;
438
439 case OVERLOADED_BOOLEAN:
440 return value === false;
441
442 case NUMERIC:
443 return isNaN(value);
444
445 case POSITIVE_NUMERIC:
446 return isNaN(value) || value < 1;
447 }
448 }
449
450 return false;
451}
452function getPropertyInfo(name) {
453 return properties.hasOwnProperty(name) ? properties[name] : null;
454}
455
456function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) {
457 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
458 this.attributeName = attributeName;
459 this.attributeNamespace = attributeNamespace;
460 this.mustUseProperty = mustUseProperty;
461 this.propertyName = name;
462 this.type = type;
463 this.sanitizeURL = sanitizeURL;
464 this.removeEmptyString = removeEmptyString;
465} // When adding attributes to this list, be sure to also add them to
466// the `possibleStandardNames` module to ensure casing and incorrect
467// name warnings.
468
469
470var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
471
472var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
473// elements (not just inputs). Now that ReactDOMInput assigns to the
474// defaultValue property -- do we need this?
475'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];
476
477reservedProps.forEach(function (name) {
478 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
479 name, // attributeName
480 null, // attributeNamespace
481 false, // sanitizeURL
482 false);
483}); // A few React string attributes have a different name.
484// This is a mapping from React prop names to the attribute names.
485
486[['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
487 var name = _ref[0],
488 attributeName = _ref[1];
489 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
490 attributeName, // attributeName
491 null, // attributeNamespace
492 false, // sanitizeURL
493 false);
494}); // These are "enumerated" HTML attributes that accept "true" and "false".
495// In React, we let users pass `true` and `false` even though technically
496// these aren't boolean attributes (they are coerced to strings).
497
498['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
499 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
500 name.toLowerCase(), // attributeName
501 null, // attributeNamespace
502 false, // sanitizeURL
503 false);
504}); // These are "enumerated" SVG attributes that accept "true" and "false".
505// In React, we let users pass `true` and `false` even though technically
506// these aren't boolean attributes (they are coerced to strings).
507// Since these are SVG attributes, their attribute names are case-sensitive.
508
509['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
510 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
511 name, // attributeName
512 null, // attributeNamespace
513 false, // sanitizeURL
514 false);
515}); // These are HTML boolean attributes.
516
517['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
518// on the client side because the browsers are inconsistent. Instead we call focus().
519'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
520'itemScope'].forEach(function (name) {
521 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
522 name.toLowerCase(), // attributeName
523 null, // attributeNamespace
524 false, // sanitizeURL
525 false);
526}); // These are the few React props that we set as DOM properties
527// rather than attributes. These are all booleans.
528
529['checked', // Note: `option.selected` is not updated if `select.multiple` is
530// disabled with `removeAttribute`. We have special logic for handling this.
531'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,
532// you'll need to set attributeName to name.toLowerCase()
533// instead in the assignment below.
534].forEach(function (name) {
535 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
536 name, // attributeName
537 null, // attributeNamespace
538 false, // sanitizeURL
539 false);
540}); // These are HTML attributes that are "overloaded booleans": they behave like
541// booleans, but can also accept a string value.
542
543['capture', 'download' // NOTE: if you add a camelCased prop to this list,
544// you'll need to set attributeName to name.toLowerCase()
545// instead in the assignment below.
546].forEach(function (name) {
547 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
548 name, // attributeName
549 null, // attributeNamespace
550 false, // sanitizeURL
551 false);
552}); // These are HTML attributes that must be positive numbers.
553
554['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
555// you'll need to set attributeName to name.toLowerCase()
556// instead in the assignment below.
557].forEach(function (name) {
558 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
559 name, // attributeName
560 null, // attributeNamespace
561 false, // sanitizeURL
562 false);
563}); // These are HTML attributes that must be numbers.
564
565['rowSpan', 'start'].forEach(function (name) {
566 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
567 name.toLowerCase(), // attributeName
568 null, // attributeNamespace
569 false, // sanitizeURL
570 false);
571});
572var CAMELIZE = /[\-\:]([a-z])/g;
573
574var capitalize = function (token) {
575 return token[1].toUpperCase();
576}; // This is a list of all SVG attributes that need special casing, namespacing,
577// or boolean value assignment. Regular attributes that just accept strings
578// and have the same names are omitted, just like in the HTML attribute filter.
579// Some of these attributes can be hard to find. This list was created by
580// scraping the MDN documentation.
581
582
583['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' // NOTE: if you add a camelCased prop to this list,
584// you'll need to set attributeName to name.toLowerCase()
585// instead in the assignment below.
586].forEach(function (attributeName) {
587 var name = attributeName.replace(CAMELIZE, capitalize);
588 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
589 attributeName, null, // attributeNamespace
590 false, // sanitizeURL
591 false);
592}); // String SVG attributes with the xlink namespace.
593
594['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
595// you'll need to set attributeName to name.toLowerCase()
596// instead in the assignment below.
597].forEach(function (attributeName) {
598 var name = attributeName.replace(CAMELIZE, capitalize);
599 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
600 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL
601 false);
602}); // String SVG attributes with the xml namespace.
603
604['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
605// you'll need to set attributeName to name.toLowerCase()
606// instead in the assignment below.
607].forEach(function (attributeName) {
608 var name = attributeName.replace(CAMELIZE, capitalize);
609 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
610 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL
611 false);
612}); // These attribute exists both in HTML and SVG.
613// The attribute name is case-sensitive in SVG so we can't just use
614// the React name like we do for attributes that exist only in HTML.
615
616['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
617 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
618 attributeName.toLowerCase(), // attributeName
619 null, // attributeNamespace
620 false, // sanitizeURL
621 false);
622}); // These attributes accept URLs. These must not allow javascript: URLS.
623// These will also need to accept Trusted Types object in the future.
624
625var xlinkHref = 'xlinkHref';
626properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
627'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL
628false);
629['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
630 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
631 attributeName.toLowerCase(), // attributeName
632 null, // attributeNamespace
633 true, // sanitizeURL
634 true);
635});
636
637// and any newline or tab are filtered out as if they're not part of the URL.
638// https://url.spec.whatwg.org/#url-parsing
639// Tab or newline are defined as \r\n\t:
640// https://infra.spec.whatwg.org/#ascii-tab-or-newline
641// A C0 control is a code point in the range \u0000 NULL to \u001F
642// INFORMATION SEPARATOR ONE, inclusive:
643// https://infra.spec.whatwg.org/#c0-control-or-space
644
645/* eslint-disable max-len */
646
647var 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;
648var didWarn = false;
649
650function sanitizeURL(url) {
651 {
652 if (!didWarn && isJavaScriptProtocol.test(url)) {
653 didWarn = true;
654
655 error('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));
656 }
657 }
658}
659
660/**
661 * Get the value for a property on a node. Only used in DEV for SSR validation.
662 * The "expected" argument is used as a hint of what the expected value is.
663 * Some properties have multiple equivalent values.
664 */
665function getValueForProperty(node, name, expected, propertyInfo) {
666 {
667 if (propertyInfo.mustUseProperty) {
668 var propertyName = propertyInfo.propertyName;
669 return node[propertyName];
670 } else {
671 // This check protects multiple uses of `expected`, which is why the
672 // react-internal/safe-string-coercion rule is disabled in several spots
673 // below.
674 {
675 checkAttributeStringCoercion(expected, name);
676 }
677
678 if ( propertyInfo.sanitizeURL) {
679 // If we haven't fully disabled javascript: URLs, and if
680 // the hydration is successful of a javascript: URL, we
681 // still want to warn on the client.
682 // eslint-disable-next-line react-internal/safe-string-coercion
683 sanitizeURL('' + expected);
684 }
685
686 var attributeName = propertyInfo.attributeName;
687 var stringValue = null;
688
689 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
690 if (node.hasAttribute(attributeName)) {
691 var value = node.getAttribute(attributeName);
692
693 if (value === '') {
694 return true;
695 }
696
697 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
698 return value;
699 } // eslint-disable-next-line react-internal/safe-string-coercion
700
701
702 if (value === '' + expected) {
703 return expected;
704 }
705
706 return value;
707 }
708 } else if (node.hasAttribute(attributeName)) {
709 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
710 // We had an attribute but shouldn't have had one, so read it
711 // for the error message.
712 return node.getAttribute(attributeName);
713 }
714
715 if (propertyInfo.type === BOOLEAN) {
716 // If this was a boolean, it doesn't matter what the value is
717 // the fact that we have it is the same as the expected.
718 return expected;
719 } // Even if this property uses a namespace we use getAttribute
720 // because we assume its namespaced name is the same as our config.
721 // To use getAttributeNS we need the local name which we don't have
722 // in our config atm.
723
724
725 stringValue = node.getAttribute(attributeName);
726 }
727
728 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
729 return stringValue === null ? expected : stringValue; // eslint-disable-next-line react-internal/safe-string-coercion
730 } else if (stringValue === '' + expected) {
731 return expected;
732 } else {
733 return stringValue;
734 }
735 }
736 }
737}
738/**
739 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
740 * The third argument is used as a hint of what the expected value is. Some
741 * attributes have multiple equivalent values.
742 */
743
744function getValueForAttribute(node, name, expected, isCustomComponentTag) {
745 {
746 if (!isAttributeNameSafe(name)) {
747 return;
748 }
749
750 if (!node.hasAttribute(name)) {
751 return expected === undefined ? undefined : null;
752 }
753
754 var value = node.getAttribute(name);
755
756 {
757 checkAttributeStringCoercion(expected, name);
758 }
759
760 if (value === '' + expected) {
761 return expected;
762 }
763
764 return value;
765 }
766}
767/**
768 * Sets the value for a property on a node.
769 *
770 * @param {DOMElement} node
771 * @param {string} name
772 * @param {*} value
773 */
774
775function setValueForProperty(node, name, value, isCustomComponentTag) {
776 var propertyInfo = getPropertyInfo(name);
777
778 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
779 return;
780 }
781
782 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
783 value = null;
784 }
785
786
787 if (isCustomComponentTag || propertyInfo === null) {
788 if (isAttributeNameSafe(name)) {
789 var _attributeName = name;
790
791 if (value === null) {
792 node.removeAttribute(_attributeName);
793 } else {
794 {
795 checkAttributeStringCoercion(value, name);
796 }
797
798 node.setAttribute(_attributeName, '' + value);
799 }
800 }
801
802 return;
803 }
804
805 var mustUseProperty = propertyInfo.mustUseProperty;
806
807 if (mustUseProperty) {
808 var propertyName = propertyInfo.propertyName;
809
810 if (value === null) {
811 var type = propertyInfo.type;
812 node[propertyName] = type === BOOLEAN ? false : '';
813 } else {
814 // Contrary to `setAttribute`, object properties are properly
815 // `toString`ed by IE8/9.
816 node[propertyName] = value;
817 }
818
819 return;
820 } // The rest are treated as attributes with special cases.
821
822
823 var attributeName = propertyInfo.attributeName,
824 attributeNamespace = propertyInfo.attributeNamespace;
825
826 if (value === null) {
827 node.removeAttribute(attributeName);
828 } else {
829 var _type = propertyInfo.type;
830 var attributeValue;
831
832 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
833 // If attribute type is boolean, we know for sure it won't be an execution sink
834 // and we won't require Trusted Type here.
835 attributeValue = '';
836 } else {
837 // `setAttribute` with objects becomes only `[object]` in IE8/9,
838 // ('' + value) makes it output the correct toString()-value.
839 {
840 {
841 checkAttributeStringCoercion(value, attributeName);
842 }
843
844 attributeValue = '' + value;
845 }
846
847 if (propertyInfo.sanitizeURL) {
848 sanitizeURL(attributeValue.toString());
849 }
850 }
851
852 if (attributeNamespace) {
853 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
854 } else {
855 node.setAttribute(attributeName, attributeValue);
856 }
857 }
858}
859
860// ATTENTION
861// When adding new symbols to this file,
862// Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
863// The Symbol used to tag the ReactElement-like types.
864var REACT_ELEMENT_TYPE = Symbol.for('react.element');
865var REACT_PORTAL_TYPE = Symbol.for('react.portal');
866var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
867var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
868var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
869var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
870var REACT_CONTEXT_TYPE = Symbol.for('react.context');
871var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
872var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
873var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
874var REACT_MEMO_TYPE = Symbol.for('react.memo');
875var REACT_LAZY_TYPE = Symbol.for('react.lazy');
876var REACT_SCOPE_TYPE = Symbol.for('react.scope');
877var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode');
878var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
879var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
880var REACT_CACHE_TYPE = Symbol.for('react.cache');
881var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
882var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
883var FAUX_ITERATOR_SYMBOL = '@@iterator';
884function getIteratorFn(maybeIterable) {
885 if (maybeIterable === null || typeof maybeIterable !== 'object') {
886 return null;
887 }
888
889 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
890
891 if (typeof maybeIterator === 'function') {
892 return maybeIterator;
893 }
894
895 return null;
896}
897
898var assign = Object.assign;
899
900// Helpers to patch console.logs to avoid logging during side-effect free
901// replaying on render function. This currently only patches the object
902// lazily which won't cover if the log function was extracted eagerly.
903// We could also eagerly patch the method.
904var disabledDepth = 0;
905var prevLog;
906var prevInfo;
907var prevWarn;
908var prevError;
909var prevGroup;
910var prevGroupCollapsed;
911var prevGroupEnd;
912
913function disabledLog() {}
914
915disabledLog.__reactDisabledLog = true;
916function disableLogs() {
917 {
918 if (disabledDepth === 0) {
919 /* eslint-disable react-internal/no-production-logging */
920 prevLog = console.log;
921 prevInfo = console.info;
922 prevWarn = console.warn;
923 prevError = console.error;
924 prevGroup = console.group;
925 prevGroupCollapsed = console.groupCollapsed;
926 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
927
928 var props = {
929 configurable: true,
930 enumerable: true,
931 value: disabledLog,
932 writable: true
933 }; // $FlowFixMe Flow thinks console is immutable.
934
935 Object.defineProperties(console, {
936 info: props,
937 log: props,
938 warn: props,
939 error: props,
940 group: props,
941 groupCollapsed: props,
942 groupEnd: props
943 });
944 /* eslint-enable react-internal/no-production-logging */
945 }
946
947 disabledDepth++;
948 }
949}
950function reenableLogs() {
951 {
952 disabledDepth--;
953
954 if (disabledDepth === 0) {
955 /* eslint-disable react-internal/no-production-logging */
956 var props = {
957 configurable: true,
958 enumerable: true,
959 writable: true
960 }; // $FlowFixMe Flow thinks console is immutable.
961
962 Object.defineProperties(console, {
963 log: assign({}, props, {
964 value: prevLog
965 }),
966 info: assign({}, props, {
967 value: prevInfo
968 }),
969 warn: assign({}, props, {
970 value: prevWarn
971 }),
972 error: assign({}, props, {
973 value: prevError
974 }),
975 group: assign({}, props, {
976 value: prevGroup
977 }),
978 groupCollapsed: assign({}, props, {
979 value: prevGroupCollapsed
980 }),
981 groupEnd: assign({}, props, {
982 value: prevGroupEnd
983 })
984 });
985 /* eslint-enable react-internal/no-production-logging */
986 }
987
988 if (disabledDepth < 0) {
989 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
990 }
991 }
992}
993
994var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
995var prefix;
996function describeBuiltInComponentFrame(name, source, ownerFn) {
997 {
998 if (prefix === undefined) {
999 // Extract the VM specific prefix used by each line.
1000 try {
1001 throw Error();
1002 } catch (x) {
1003 var match = x.stack.trim().match(/\n( *(at )?)/);
1004 prefix = match && match[1] || '';
1005 }
1006 } // We use the prefix to ensure our stacks line up with native stack frames.
1007
1008
1009 return '\n' + prefix + name;
1010 }
1011}
1012var reentry = false;
1013var componentFrameCache;
1014
1015{
1016 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
1017 componentFrameCache = new PossiblyWeakMap();
1018}
1019
1020function describeNativeComponentFrame(fn, construct) {
1021 // If something asked for a stack inside a fake render, it should get ignored.
1022 if ( !fn || reentry) {
1023 return '';
1024 }
1025
1026 {
1027 var frame = componentFrameCache.get(fn);
1028
1029 if (frame !== undefined) {
1030 return frame;
1031 }
1032 }
1033
1034 var control;
1035 reentry = true;
1036 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.
1037
1038 Error.prepareStackTrace = undefined;
1039 var previousDispatcher;
1040
1041 {
1042 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function
1043 // for warnings.
1044
1045 ReactCurrentDispatcher.current = null;
1046 disableLogs();
1047 }
1048
1049 try {
1050 // This should throw.
1051 if (construct) {
1052 // Something should be setting the props in the constructor.
1053 var Fake = function () {
1054 throw Error();
1055 }; // $FlowFixMe
1056
1057
1058 Object.defineProperty(Fake.prototype, 'props', {
1059 set: function () {
1060 // We use a throwing setter instead of frozen or non-writable props
1061 // because that won't throw in a non-strict mode function.
1062 throw Error();
1063 }
1064 });
1065
1066 if (typeof Reflect === 'object' && Reflect.construct) {
1067 // We construct a different control for this case to include any extra
1068 // frames added by the construct call.
1069 try {
1070 Reflect.construct(Fake, []);
1071 } catch (x) {
1072 control = x;
1073 }
1074
1075 Reflect.construct(fn, [], Fake);
1076 } else {
1077 try {
1078 Fake.call();
1079 } catch (x) {
1080 control = x;
1081 }
1082
1083 fn.call(Fake.prototype);
1084 }
1085 } else {
1086 try {
1087 throw Error();
1088 } catch (x) {
1089 control = x;
1090 }
1091
1092 fn();
1093 }
1094 } catch (sample) {
1095 // This is inlined manually because closure doesn't do it for us.
1096 if (sample && control && typeof sample.stack === 'string') {
1097 // This extracts the first frame from the sample that isn't also in the control.
1098 // Skipping one frame that we assume is the frame that calls the two.
1099 var sampleLines = sample.stack.split('\n');
1100 var controlLines = control.stack.split('\n');
1101 var s = sampleLines.length - 1;
1102 var c = controlLines.length - 1;
1103
1104 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
1105 // We expect at least one stack frame to be shared.
1106 // Typically this will be the root most one. However, stack frames may be
1107 // cut off due to maximum stack limits. In this case, one maybe cut off
1108 // earlier than the other. We assume that the sample is longer or the same
1109 // and there for cut off earlier. So we should find the root most frame in
1110 // the sample somewhere in the control.
1111 c--;
1112 }
1113
1114 for (; s >= 1 && c >= 0; s--, c--) {
1115 // Next we find the first one that isn't the same which should be the
1116 // frame that called our sample function and the control.
1117 if (sampleLines[s] !== controlLines[c]) {
1118 // In V8, the first line is describing the message but other VMs don't.
1119 // If we're about to return the first line, and the control is also on the same
1120 // line, that's a pretty good indicator that our sample threw at same line as
1121 // the control. I.e. before we entered the sample frame. So we ignore this result.
1122 // This can happen if you passed a class to function component, or non-function.
1123 if (s !== 1 || c !== 1) {
1124 do {
1125 s--;
1126 c--; // We may still have similar intermediate frames from the construct call.
1127 // The next one that isn't the same should be our match though.
1128
1129 if (c < 0 || sampleLines[s] !== controlLines[c]) {
1130 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
1131 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>"
1132 // but we have a user-provided "displayName"
1133 // splice it in to make the stack more readable.
1134
1135
1136 if (fn.displayName && _frame.includes('<anonymous>')) {
1137 _frame = _frame.replace('<anonymous>', fn.displayName);
1138 }
1139
1140 {
1141 if (typeof fn === 'function') {
1142 componentFrameCache.set(fn, _frame);
1143 }
1144 } // Return the line we found.
1145
1146
1147 return _frame;
1148 }
1149 } while (s >= 1 && c >= 0);
1150 }
1151
1152 break;
1153 }
1154 }
1155 }
1156 } finally {
1157 reentry = false;
1158
1159 {
1160 ReactCurrentDispatcher.current = previousDispatcher;
1161 reenableLogs();
1162 }
1163
1164 Error.prepareStackTrace = previousPrepareStackTrace;
1165 } // Fallback to just using the name if we couldn't make it throw.
1166
1167
1168 var name = fn ? fn.displayName || fn.name : '';
1169 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
1170
1171 {
1172 if (typeof fn === 'function') {
1173 componentFrameCache.set(fn, syntheticFrame);
1174 }
1175 }
1176
1177 return syntheticFrame;
1178}
1179
1180function describeClassComponentFrame(ctor, source, ownerFn) {
1181 {
1182 return describeNativeComponentFrame(ctor, true);
1183 }
1184}
1185function describeFunctionComponentFrame(fn, source, ownerFn) {
1186 {
1187 return describeNativeComponentFrame(fn, false);
1188 }
1189}
1190
1191function shouldConstruct(Component) {
1192 var prototype = Component.prototype;
1193 return !!(prototype && prototype.isReactComponent);
1194}
1195
1196function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
1197
1198 if (type == null) {
1199 return '';
1200 }
1201
1202 if (typeof type === 'function') {
1203 {
1204 return describeNativeComponentFrame(type, shouldConstruct(type));
1205 }
1206 }
1207
1208 if (typeof type === 'string') {
1209 return describeBuiltInComponentFrame(type);
1210 }
1211
1212 switch (type) {
1213 case REACT_SUSPENSE_TYPE:
1214 return describeBuiltInComponentFrame('Suspense');
1215
1216 case REACT_SUSPENSE_LIST_TYPE:
1217 return describeBuiltInComponentFrame('SuspenseList');
1218 }
1219
1220 if (typeof type === 'object') {
1221 switch (type.$$typeof) {
1222 case REACT_FORWARD_REF_TYPE:
1223 return describeFunctionComponentFrame(type.render);
1224
1225 case REACT_MEMO_TYPE:
1226 // Memo may contain any component type so we recursively resolve it.
1227 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
1228
1229 case REACT_LAZY_TYPE:
1230 {
1231 var lazyComponent = type;
1232 var payload = lazyComponent._payload;
1233 var init = lazyComponent._init;
1234
1235 try {
1236 // Lazy may contain any component type so we recursively resolve it.
1237 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
1238 } catch (x) {}
1239 }
1240 }
1241 }
1242
1243 return '';
1244}
1245
1246function describeFiber(fiber) {
1247 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ;
1248 var source = fiber._debugSource ;
1249
1250 switch (fiber.tag) {
1251 case HostComponent:
1252 return describeBuiltInComponentFrame(fiber.type);
1253
1254 case LazyComponent:
1255 return describeBuiltInComponentFrame('Lazy');
1256
1257 case SuspenseComponent:
1258 return describeBuiltInComponentFrame('Suspense');
1259
1260 case SuspenseListComponent:
1261 return describeBuiltInComponentFrame('SuspenseList');
1262
1263 case FunctionComponent:
1264 case IndeterminateComponent:
1265 case SimpleMemoComponent:
1266 return describeFunctionComponentFrame(fiber.type);
1267
1268 case ForwardRef:
1269 return describeFunctionComponentFrame(fiber.type.render);
1270
1271 case ClassComponent:
1272 return describeClassComponentFrame(fiber.type);
1273
1274 default:
1275 return '';
1276 }
1277}
1278
1279function getStackByFiberInDevAndProd(workInProgress) {
1280 try {
1281 var info = '';
1282 var node = workInProgress;
1283
1284 do {
1285 info += describeFiber(node);
1286 node = node.return;
1287 } while (node);
1288
1289 return info;
1290 } catch (x) {
1291 return '\nError generating stack: ' + x.message + '\n' + x.stack;
1292 }
1293}
1294
1295function getWrappedName(outerType, innerType, wrapperName) {
1296 var displayName = outerType.displayName;
1297
1298 if (displayName) {
1299 return displayName;
1300 }
1301
1302 var functionName = innerType.displayName || innerType.name || '';
1303 return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName;
1304} // Keep in sync with react-reconciler/getComponentNameFromFiber
1305
1306
1307function getContextName(type) {
1308 return type.displayName || 'Context';
1309} // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
1310
1311
1312function getComponentNameFromType(type) {
1313 if (type == null) {
1314 // Host root, text node or just invalid type.
1315 return null;
1316 }
1317
1318 {
1319 if (typeof type.tag === 'number') {
1320 error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.');
1321 }
1322 }
1323
1324 if (typeof type === 'function') {
1325 return type.displayName || type.name || null;
1326 }
1327
1328 if (typeof type === 'string') {
1329 return type;
1330 }
1331
1332 switch (type) {
1333 case REACT_FRAGMENT_TYPE:
1334 return 'Fragment';
1335
1336 case REACT_PORTAL_TYPE:
1337 return 'Portal';
1338
1339 case REACT_PROFILER_TYPE:
1340 return 'Profiler';
1341
1342 case REACT_STRICT_MODE_TYPE:
1343 return 'StrictMode';
1344
1345 case REACT_SUSPENSE_TYPE:
1346 return 'Suspense';
1347
1348 case REACT_SUSPENSE_LIST_TYPE:
1349 return 'SuspenseList';
1350
1351 }
1352
1353 if (typeof type === 'object') {
1354 switch (type.$$typeof) {
1355 case REACT_CONTEXT_TYPE:
1356 var context = type;
1357 return getContextName(context) + '.Consumer';
1358
1359 case REACT_PROVIDER_TYPE:
1360 var provider = type;
1361 return getContextName(provider._context) + '.Provider';
1362
1363 case REACT_FORWARD_REF_TYPE:
1364 return getWrappedName(type, type.render, 'ForwardRef');
1365
1366 case REACT_MEMO_TYPE:
1367 var outerName = type.displayName || null;
1368
1369 if (outerName !== null) {
1370 return outerName;
1371 }
1372
1373 return getComponentNameFromType(type.type) || 'Memo';
1374
1375 case REACT_LAZY_TYPE:
1376 {
1377 var lazyComponent = type;
1378 var payload = lazyComponent._payload;
1379 var init = lazyComponent._init;
1380
1381 try {
1382 return getComponentNameFromType(init(payload));
1383 } catch (x) {
1384 return null;
1385 }
1386 }
1387
1388 // eslint-disable-next-line no-fallthrough
1389 }
1390 }
1391
1392 return null;
1393}
1394
1395function getWrappedName$1(outerType, innerType, wrapperName) {
1396 var functionName = innerType.displayName || innerType.name || '';
1397 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
1398} // Keep in sync with shared/getComponentNameFromType
1399
1400
1401function getContextName$1(type) {
1402 return type.displayName || 'Context';
1403}
1404
1405function getComponentNameFromFiber(fiber) {
1406 var tag = fiber.tag,
1407 type = fiber.type;
1408
1409 switch (tag) {
1410 case CacheComponent:
1411 return 'Cache';
1412
1413 case ContextConsumer:
1414 var context = type;
1415 return getContextName$1(context) + '.Consumer';
1416
1417 case ContextProvider:
1418 var provider = type;
1419 return getContextName$1(provider._context) + '.Provider';
1420
1421 case DehydratedFragment:
1422 return 'DehydratedFragment';
1423
1424 case ForwardRef:
1425 return getWrappedName$1(type, type.render, 'ForwardRef');
1426
1427 case Fragment:
1428 return 'Fragment';
1429
1430 case HostComponent:
1431 // Host component type is the display name (e.g. "div", "View")
1432 return type;
1433
1434 case HostPortal:
1435 return 'Portal';
1436
1437 case HostRoot:
1438 return 'Root';
1439
1440 case HostText:
1441 return 'Text';
1442
1443 case LazyComponent:
1444 // Name comes from the type in this case; we don't have a tag.
1445 return getComponentNameFromType(type);
1446
1447 case Mode:
1448 if (type === REACT_STRICT_MODE_TYPE) {
1449 // Don't be less specific than shared/getComponentNameFromType
1450 return 'StrictMode';
1451 }
1452
1453 return 'Mode';
1454
1455 case OffscreenComponent:
1456 return 'Offscreen';
1457
1458 case Profiler:
1459 return 'Profiler';
1460
1461 case ScopeComponent:
1462 return 'Scope';
1463
1464 case SuspenseComponent:
1465 return 'Suspense';
1466
1467 case SuspenseListComponent:
1468 return 'SuspenseList';
1469
1470 case TracingMarkerComponent:
1471 return 'TracingMarker';
1472 // The display name for this tags come from the user-provided type:
1473
1474 case ClassComponent:
1475 case FunctionComponent:
1476 case IncompleteClassComponent:
1477 case IndeterminateComponent:
1478 case MemoComponent:
1479 case SimpleMemoComponent:
1480 if (typeof type === 'function') {
1481 return type.displayName || type.name || null;
1482 }
1483
1484 if (typeof type === 'string') {
1485 return type;
1486 }
1487
1488 break;
1489
1490 }
1491
1492 return null;
1493}
1494
1495var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1496var current = null;
1497var isRendering = false;
1498function getCurrentFiberOwnerNameInDevOrNull() {
1499 {
1500 if (current === null) {
1501 return null;
1502 }
1503
1504 var owner = current._debugOwner;
1505
1506 if (owner !== null && typeof owner !== 'undefined') {
1507 return getComponentNameFromFiber(owner);
1508 }
1509 }
1510
1511 return null;
1512}
1513
1514function getCurrentFiberStackInDev() {
1515 {
1516 if (current === null) {
1517 return '';
1518 } // Safe because if current fiber exists, we are reconciling,
1519 // and it is guaranteed to be the work-in-progress version.
1520
1521
1522 return getStackByFiberInDevAndProd(current);
1523 }
1524}
1525
1526function resetCurrentFiber() {
1527 {
1528 ReactDebugCurrentFrame.getCurrentStack = null;
1529 current = null;
1530 isRendering = false;
1531 }
1532}
1533function setCurrentFiber(fiber) {
1534 {
1535 ReactDebugCurrentFrame.getCurrentStack = fiber === null ? null : getCurrentFiberStackInDev;
1536 current = fiber;
1537 isRendering = false;
1538 }
1539}
1540function getCurrentFiber() {
1541 {
1542 return current;
1543 }
1544}
1545function setIsRendering(rendering) {
1546 {
1547 isRendering = rendering;
1548 }
1549}
1550
1551// Flow does not allow string concatenation of most non-string types. To work
1552// around this limitation, we use an opaque type that can only be obtained by
1553// passing the value through getToStringValue first.
1554function toString(value) {
1555 // The coercion safety check is performed in getToStringValue().
1556 // eslint-disable-next-line react-internal/safe-string-coercion
1557 return '' + value;
1558}
1559function getToStringValue(value) {
1560 switch (typeof value) {
1561 case 'boolean':
1562 case 'number':
1563 case 'string':
1564 case 'undefined':
1565 return value;
1566
1567 case 'object':
1568 {
1569 checkFormFieldValueStringCoercion(value);
1570 }
1571
1572 return value;
1573
1574 default:
1575 // function, symbol are assigned as empty strings
1576 return '';
1577 }
1578}
1579
1580var hasReadOnlyValue = {
1581 button: true,
1582 checkbox: true,
1583 image: true,
1584 hidden: true,
1585 radio: true,
1586 reset: true,
1587 submit: true
1588};
1589function checkControlledValueProps(tagName, props) {
1590 {
1591 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) {
1592 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`.');
1593 }
1594
1595 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) {
1596 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`.');
1597 }
1598 }
1599}
1600
1601function isCheckable(elem) {
1602 var type = elem.type;
1603 var nodeName = elem.nodeName;
1604 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
1605}
1606
1607function getTracker(node) {
1608 return node._valueTracker;
1609}
1610
1611function detachTracker(node) {
1612 node._valueTracker = null;
1613}
1614
1615function getValueFromNode(node) {
1616 var value = '';
1617
1618 if (!node) {
1619 return value;
1620 }
1621
1622 if (isCheckable(node)) {
1623 value = node.checked ? 'true' : 'false';
1624 } else {
1625 value = node.value;
1626 }
1627
1628 return value;
1629}
1630
1631function trackValueOnNode(node) {
1632 var valueField = isCheckable(node) ? 'checked' : 'value';
1633 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
1634
1635 {
1636 checkFormFieldValueStringCoercion(node[valueField]);
1637 }
1638
1639 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
1640 // and don't track value will cause over reporting of changes,
1641 // but it's better then a hard failure
1642 // (needed for certain tests that spyOn input values and Safari)
1643
1644 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
1645 return;
1646 }
1647
1648 var get = descriptor.get,
1649 set = descriptor.set;
1650 Object.defineProperty(node, valueField, {
1651 configurable: true,
1652 get: function () {
1653 return get.call(this);
1654 },
1655 set: function (value) {
1656 {
1657 checkFormFieldValueStringCoercion(value);
1658 }
1659
1660 currentValue = '' + value;
1661 set.call(this, value);
1662 }
1663 }); // We could've passed this the first time
1664 // but it triggers a bug in IE11 and Edge 14/15.
1665 // Calling defineProperty() again should be equivalent.
1666 // https://github.com/facebook/react/issues/11768
1667
1668 Object.defineProperty(node, valueField, {
1669 enumerable: descriptor.enumerable
1670 });
1671 var tracker = {
1672 getValue: function () {
1673 return currentValue;
1674 },
1675 setValue: function (value) {
1676 {
1677 checkFormFieldValueStringCoercion(value);
1678 }
1679
1680 currentValue = '' + value;
1681 },
1682 stopTracking: function () {
1683 detachTracker(node);
1684 delete node[valueField];
1685 }
1686 };
1687 return tracker;
1688}
1689
1690function track(node) {
1691 if (getTracker(node)) {
1692 return;
1693 } // TODO: Once it's just Fiber we can move this to node._wrapperState
1694
1695
1696 node._valueTracker = trackValueOnNode(node);
1697}
1698function updateValueIfChanged(node) {
1699 if (!node) {
1700 return false;
1701 }
1702
1703 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
1704 // that trying again will succeed
1705
1706 if (!tracker) {
1707 return true;
1708 }
1709
1710 var lastValue = tracker.getValue();
1711 var nextValue = getValueFromNode(node);
1712
1713 if (nextValue !== lastValue) {
1714 tracker.setValue(nextValue);
1715 return true;
1716 }
1717
1718 return false;
1719}
1720
1721function getActiveElement(doc) {
1722 doc = doc || (typeof document !== 'undefined' ? document : undefined);
1723
1724 if (typeof doc === 'undefined') {
1725 return null;
1726 }
1727
1728 try {
1729 return doc.activeElement || doc.body;
1730 } catch (e) {
1731 return doc.body;
1732 }
1733}
1734
1735var didWarnValueDefaultValue = false;
1736var didWarnCheckedDefaultChecked = false;
1737var didWarnControlledToUncontrolled = false;
1738var didWarnUncontrolledToControlled = false;
1739
1740function isControlled(props) {
1741 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
1742 return usesChecked ? props.checked != null : props.value != null;
1743}
1744/**
1745 * Implements an <input> host component that allows setting these optional
1746 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
1747 *
1748 * If `checked` or `value` are not supplied (or null/undefined), user actions
1749 * that affect the checked state or value will trigger updates to the element.
1750 *
1751 * If they are supplied (and not null/undefined), the rendered element will not
1752 * trigger updates to the element. Instead, the props must change in order for
1753 * the rendered element to be updated.
1754 *
1755 * The rendered element will be initialized as unchecked (or `defaultChecked`)
1756 * with an empty value (or `defaultValue`).
1757 *
1758 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
1759 */
1760
1761
1762function getHostProps(element, props) {
1763 var node = element;
1764 var checked = props.checked;
1765 var hostProps = assign({}, props, {
1766 defaultChecked: undefined,
1767 defaultValue: undefined,
1768 value: undefined,
1769 checked: checked != null ? checked : node._wrapperState.initialChecked
1770 });
1771 return hostProps;
1772}
1773function initWrapperState(element, props) {
1774 {
1775 checkControlledValueProps('input', props);
1776
1777 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
1778 error('%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://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
1779
1780 didWarnCheckedDefaultChecked = true;
1781 }
1782
1783 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
1784 error('%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://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component', props.type);
1785
1786 didWarnValueDefaultValue = true;
1787 }
1788 }
1789
1790 var node = element;
1791 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
1792 node._wrapperState = {
1793 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
1794 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
1795 controlled: isControlled(props)
1796 };
1797}
1798function updateChecked(element, props) {
1799 var node = element;
1800 var checked = props.checked;
1801
1802 if (checked != null) {
1803 setValueForProperty(node, 'checked', checked, false);
1804 }
1805}
1806function updateWrapper(element, props) {
1807 var node = element;
1808
1809 {
1810 var controlled = isControlled(props);
1811
1812 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
1813 error('A component is changing an uncontrolled input to be controlled. ' + 'This is likely caused by the value changing from undefined to ' + 'a defined value, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components');
1814
1815 didWarnUncontrolledToControlled = true;
1816 }
1817
1818 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
1819 error('A component is changing a controlled input to be uncontrolled. ' + 'This is likely caused by the value changing from a defined to ' + 'undefined, which should not happen. ' + 'Decide between using a controlled or uncontrolled input ' + 'element for the lifetime of the component. More info: https://reactjs.org/link/controlled-components');
1820
1821 didWarnControlledToUncontrolled = true;
1822 }
1823 }
1824
1825 updateChecked(element, props);
1826 var value = getToStringValue(props.value);
1827 var type = props.type;
1828
1829 if (value != null) {
1830 if (type === 'number') {
1831 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
1832 // eslint-disable-next-line
1833 node.value != value) {
1834 node.value = toString(value);
1835 }
1836 } else if (node.value !== toString(value)) {
1837 node.value = toString(value);
1838 }
1839 } else if (type === 'submit' || type === 'reset') {
1840 // Submit/reset inputs need the attribute removed completely to avoid
1841 // blank-text buttons.
1842 node.removeAttribute('value');
1843 return;
1844 }
1845
1846 {
1847 // When syncing the value attribute, the value comes from a cascade of
1848 // properties:
1849 // 1. The value React property
1850 // 2. The defaultValue React property
1851 // 3. Otherwise there should be no change
1852 if (props.hasOwnProperty('value')) {
1853 setDefaultValue(node, props.type, value);
1854 } else if (props.hasOwnProperty('defaultValue')) {
1855 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
1856 }
1857 }
1858
1859 {
1860 // When syncing the checked attribute, it only changes when it needs
1861 // to be removed, such as transitioning from a checkbox into a text input
1862 if (props.checked == null && props.defaultChecked != null) {
1863 node.defaultChecked = !!props.defaultChecked;
1864 }
1865 }
1866}
1867function postMountWrapper(element, props, isHydrating) {
1868 var node = element; // Do not assign value if it is already set. This prevents user text input
1869 // from being lost during SSR hydration.
1870
1871 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
1872 var type = props.type;
1873 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
1874 // default value provided by the browser. See: #12872
1875
1876 if (isButton && (props.value === undefined || props.value === null)) {
1877 return;
1878 }
1879
1880 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
1881 // from being lost during SSR hydration.
1882
1883 if (!isHydrating) {
1884 {
1885 // When syncing the value attribute, the value property should use
1886 // the wrapperState._initialValue property. This uses:
1887 //
1888 // 1. The value React property when present
1889 // 2. The defaultValue React property when present
1890 // 3. An empty string
1891 if (initialValue !== node.value) {
1892 node.value = initialValue;
1893 }
1894 }
1895 }
1896
1897 {
1898 // Otherwise, the value attribute is synchronized to the property,
1899 // so we assign defaultValue to the same thing as the value property
1900 // assignment step above.
1901 node.defaultValue = initialValue;
1902 }
1903 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
1904 // this is needed to work around a chrome bug where setting defaultChecked
1905 // will sometimes influence the value of checked (even after detachment).
1906 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
1907 // We need to temporarily unset name to avoid disrupting radio button groups.
1908
1909
1910 var name = node.name;
1911
1912 if (name !== '') {
1913 node.name = '';
1914 }
1915
1916 {
1917 // When syncing the checked attribute, both the checked property and
1918 // attribute are assigned at the same time using defaultChecked. This uses:
1919 //
1920 // 1. The checked React property when present
1921 // 2. The defaultChecked React property when present
1922 // 3. Otherwise, false
1923 node.defaultChecked = !node.defaultChecked;
1924 node.defaultChecked = !!node._wrapperState.initialChecked;
1925 }
1926
1927 if (name !== '') {
1928 node.name = name;
1929 }
1930}
1931function restoreControlledState(element, props) {
1932 var node = element;
1933 updateWrapper(node, props);
1934 updateNamedCousins(node, props);
1935}
1936
1937function updateNamedCousins(rootNode, props) {
1938 var name = props.name;
1939
1940 if (props.type === 'radio' && name != null) {
1941 var queryRoot = rootNode;
1942
1943 while (queryRoot.parentNode) {
1944 queryRoot = queryRoot.parentNode;
1945 } // If `rootNode.form` was non-null, then we could try `form.elements`,
1946 // but that sometimes behaves strangely in IE8. We could also try using
1947 // `form.getElementsByName`, but that will only return direct children
1948 // and won't include inputs that use the HTML5 `form=` attribute. Since
1949 // the input might not even be in a form. It might not even be in the
1950 // document. Let's just use the local `querySelectorAll` to ensure we don't
1951 // miss anything.
1952
1953
1954 {
1955 checkAttributeStringCoercion(name, 'name');
1956 }
1957
1958 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
1959
1960 for (var i = 0; i < group.length; i++) {
1961 var otherNode = group[i];
1962
1963 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
1964 continue;
1965 } // This will throw if radio buttons rendered by different copies of React
1966 // and the same name are rendered into the same form (same as #1939).
1967 // That's probably okay; we don't support it just as we don't support
1968 // mixing React radio buttons with non-React ones.
1969
1970
1971 var otherProps = getFiberCurrentPropsFromNode(otherNode);
1972
1973 if (!otherProps) {
1974 throw new Error('ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.');
1975 } // We need update the tracked value on the named cousin since the value
1976 // was changed but the input saw no event or value set
1977
1978
1979 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
1980 // was previously checked to update will cause it to be come re-checked
1981 // as appropriate.
1982
1983 updateWrapper(otherNode, otherProps);
1984 }
1985 }
1986} // In Chrome, assigning defaultValue to certain input types triggers input validation.
1987// For number inputs, the display value loses trailing decimal points. For email inputs,
1988// Chrome raises "The specified value <x> is not a valid email address".
1989//
1990// Here we check to see if the defaultValue has actually changed, avoiding these problems
1991// when the user is inputting text
1992//
1993// https://github.com/facebook/react/issues/7253
1994
1995
1996function setDefaultValue(node, type, value) {
1997 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
1998 type !== 'number' || getActiveElement(node.ownerDocument) !== node) {
1999 if (value == null) {
2000 node.defaultValue = toString(node._wrapperState.initialValue);
2001 } else if (node.defaultValue !== toString(value)) {
2002 node.defaultValue = toString(value);
2003 }
2004 }
2005}
2006
2007var didWarnSelectedSetOnOption = false;
2008var didWarnInvalidChild = false;
2009var didWarnInvalidInnerHTML = false;
2010/**
2011 * Implements an <option> host component that warns when `selected` is set.
2012 */
2013
2014function validateProps(element, props) {
2015 {
2016 // If a value is not provided, then the children must be simple.
2017 if (props.value == null) {
2018 if (typeof props.children === 'object' && props.children !== null) {
2019 React.Children.forEach(props.children, function (child) {
2020 if (child == null) {
2021 return;
2022 }
2023
2024 if (typeof child === 'string' || typeof child === 'number') {
2025 return;
2026 }
2027
2028 if (!didWarnInvalidChild) {
2029 didWarnInvalidChild = true;
2030
2031 error('Cannot infer the option value of complex children. ' + 'Pass a `value` prop or use a plain string as children to <option>.');
2032 }
2033 });
2034 } else if (props.dangerouslySetInnerHTML != null) {
2035 if (!didWarnInvalidInnerHTML) {
2036 didWarnInvalidInnerHTML = true;
2037
2038 error('Pass a `value` prop if you set dangerouslyInnerHTML so React knows ' + 'which value should be selected.');
2039 }
2040 }
2041 } // TODO: Remove support for `selected` in <option>.
2042
2043
2044 if (props.selected != null && !didWarnSelectedSetOnOption) {
2045 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
2046
2047 didWarnSelectedSetOnOption = true;
2048 }
2049 }
2050}
2051function postMountWrapper$1(element, props) {
2052 // value="" should make a value attribute (#6219)
2053 if (props.value != null) {
2054 element.setAttribute('value', toString(getToStringValue(props.value)));
2055 }
2056}
2057
2058var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
2059
2060function isArray(a) {
2061 return isArrayImpl(a);
2062}
2063
2064var didWarnValueDefaultValue$1;
2065
2066{
2067 didWarnValueDefaultValue$1 = false;
2068}
2069
2070function getDeclarationErrorAddendum() {
2071 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
2072
2073 if (ownerName) {
2074 return '\n\nCheck the render method of `' + ownerName + '`.';
2075 }
2076
2077 return '';
2078}
2079
2080var valuePropNames = ['value', 'defaultValue'];
2081/**
2082 * Validation function for `value` and `defaultValue`.
2083 */
2084
2085function checkSelectPropTypes(props) {
2086 {
2087 checkControlledValueProps('select', props);
2088
2089 for (var i = 0; i < valuePropNames.length; i++) {
2090 var propName = valuePropNames[i];
2091
2092 if (props[propName] == null) {
2093 continue;
2094 }
2095
2096 var propNameIsArray = isArray(props[propName]);
2097
2098 if (props.multiple && !propNameIsArray) {
2099 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
2100 } else if (!props.multiple && propNameIsArray) {
2101 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
2102 }
2103 }
2104 }
2105}
2106
2107function updateOptions(node, multiple, propValue, setDefaultSelected) {
2108 var options = node.options;
2109
2110 if (multiple) {
2111 var selectedValues = propValue;
2112 var selectedValue = {};
2113
2114 for (var i = 0; i < selectedValues.length; i++) {
2115 // Prefix to avoid chaos with special keys.
2116 selectedValue['$' + selectedValues[i]] = true;
2117 }
2118
2119 for (var _i = 0; _i < options.length; _i++) {
2120 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
2121
2122 if (options[_i].selected !== selected) {
2123 options[_i].selected = selected;
2124 }
2125
2126 if (selected && setDefaultSelected) {
2127 options[_i].defaultSelected = true;
2128 }
2129 }
2130 } else {
2131 // Do not set `select.value` as exact behavior isn't consistent across all
2132 // browsers for all cases.
2133 var _selectedValue = toString(getToStringValue(propValue));
2134
2135 var defaultSelected = null;
2136
2137 for (var _i2 = 0; _i2 < options.length; _i2++) {
2138 if (options[_i2].value === _selectedValue) {
2139 options[_i2].selected = true;
2140
2141 if (setDefaultSelected) {
2142 options[_i2].defaultSelected = true;
2143 }
2144
2145 return;
2146 }
2147
2148 if (defaultSelected === null && !options[_i2].disabled) {
2149 defaultSelected = options[_i2];
2150 }
2151 }
2152
2153 if (defaultSelected !== null) {
2154 defaultSelected.selected = true;
2155 }
2156 }
2157}
2158/**
2159 * Implements a <select> host component that allows optionally setting the
2160 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
2161 * stringable. If `multiple` is true, the prop must be an array of stringables.
2162 *
2163 * If `value` is not supplied (or null/undefined), user actions that change the
2164 * selected option will trigger updates to the rendered options.
2165 *
2166 * If it is supplied (and not null/undefined), the rendered options will not
2167 * update in response to user actions. Instead, the `value` prop must change in
2168 * order for the rendered options to update.
2169 *
2170 * If `defaultValue` is provided, any options with the supplied values will be
2171 * selected.
2172 */
2173
2174
2175function getHostProps$1(element, props) {
2176 return assign({}, props, {
2177 value: undefined
2178 });
2179}
2180function initWrapperState$1(element, props) {
2181 var node = element;
2182
2183 {
2184 checkSelectPropTypes(props);
2185 }
2186
2187 node._wrapperState = {
2188 wasMultiple: !!props.multiple
2189 };
2190
2191 {
2192 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
2193 error('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://reactjs.org/link/controlled-components');
2194
2195 didWarnValueDefaultValue$1 = true;
2196 }
2197 }
2198}
2199function postMountWrapper$2(element, props) {
2200 var node = element;
2201 node.multiple = !!props.multiple;
2202 var value = props.value;
2203
2204 if (value != null) {
2205 updateOptions(node, !!props.multiple, value, false);
2206 } else if (props.defaultValue != null) {
2207 updateOptions(node, !!props.multiple, props.defaultValue, true);
2208 }
2209}
2210function postUpdateWrapper(element, props) {
2211 var node = element;
2212 var wasMultiple = node._wrapperState.wasMultiple;
2213 node._wrapperState.wasMultiple = !!props.multiple;
2214 var value = props.value;
2215
2216 if (value != null) {
2217 updateOptions(node, !!props.multiple, value, false);
2218 } else if (wasMultiple !== !!props.multiple) {
2219 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
2220 if (props.defaultValue != null) {
2221 updateOptions(node, !!props.multiple, props.defaultValue, true);
2222 } else {
2223 // Revert the select back to its default unselected state.
2224 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
2225 }
2226 }
2227}
2228function restoreControlledState$1(element, props) {
2229 var node = element;
2230 var value = props.value;
2231
2232 if (value != null) {
2233 updateOptions(node, !!props.multiple, value, false);
2234 }
2235}
2236
2237var didWarnValDefaultVal = false;
2238
2239/**
2240 * Implements a <textarea> host component that allows setting `value`, and
2241 * `defaultValue`. This differs from the traditional DOM API because value is
2242 * usually set as PCDATA children.
2243 *
2244 * If `value` is not supplied (or null/undefined), user actions that affect the
2245 * value will trigger updates to the element.
2246 *
2247 * If `value` is supplied (and not null/undefined), the rendered element will
2248 * not trigger updates to the element. Instead, the `value` prop must change in
2249 * order for the rendered element to be updated.
2250 *
2251 * The rendered element will be initialized with an empty value, the prop
2252 * `defaultValue` if specified, or the children content (deprecated).
2253 */
2254function getHostProps$2(element, props) {
2255 var node = element;
2256
2257 if (props.dangerouslySetInnerHTML != null) {
2258 throw new Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.');
2259 } // Always set children to the same thing. In IE9, the selection range will
2260 // get reset if `textContent` is mutated. We could add a check in setTextContent
2261 // to only set the value if/when the value differs from the node value (which would
2262 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
2263 // solution. The value can be a boolean or object so that's why it's forced
2264 // to be a string.
2265
2266
2267 var hostProps = assign({}, props, {
2268 value: undefined,
2269 defaultValue: undefined,
2270 children: toString(node._wrapperState.initialValue)
2271 });
2272
2273 return hostProps;
2274}
2275function initWrapperState$2(element, props) {
2276 var node = element;
2277
2278 {
2279 checkControlledValueProps('textarea', props);
2280
2281 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
2282 error('%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://reactjs.org/link/controlled-components', getCurrentFiberOwnerNameInDevOrNull() || 'A component');
2283
2284 didWarnValDefaultVal = true;
2285 }
2286 }
2287
2288 var initialValue = props.value; // Only bother fetching default value if we're going to use it
2289
2290 if (initialValue == null) {
2291 var children = props.children,
2292 defaultValue = props.defaultValue;
2293
2294 if (children != null) {
2295 {
2296 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
2297 }
2298
2299 {
2300 if (defaultValue != null) {
2301 throw new Error('If you supply `defaultValue` on a <textarea>, do not pass children.');
2302 }
2303
2304 if (isArray(children)) {
2305 if (children.length > 1) {
2306 throw new Error('<textarea> can only have at most one child.');
2307 }
2308
2309 children = children[0];
2310 }
2311
2312 defaultValue = children;
2313 }
2314 }
2315
2316 if (defaultValue == null) {
2317 defaultValue = '';
2318 }
2319
2320 initialValue = defaultValue;
2321 }
2322
2323 node._wrapperState = {
2324 initialValue: getToStringValue(initialValue)
2325 };
2326}
2327function updateWrapper$1(element, props) {
2328 var node = element;
2329 var value = getToStringValue(props.value);
2330 var defaultValue = getToStringValue(props.defaultValue);
2331
2332 if (value != null) {
2333 // Cast `value` to a string to ensure the value is set correctly. While
2334 // browsers typically do this as necessary, jsdom doesn't.
2335 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
2336
2337 if (newValue !== node.value) {
2338 node.value = newValue;
2339 }
2340
2341 if (props.defaultValue == null && node.defaultValue !== newValue) {
2342 node.defaultValue = newValue;
2343 }
2344 }
2345
2346 if (defaultValue != null) {
2347 node.defaultValue = toString(defaultValue);
2348 }
2349}
2350function postMountWrapper$3(element, props) {
2351 var node = element; // This is in postMount because we need access to the DOM node, which is not
2352 // available until after the component has mounted.
2353
2354 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
2355 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
2356 // will populate textContent as well.
2357 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
2358
2359 if (textContent === node._wrapperState.initialValue) {
2360 if (textContent !== '' && textContent !== null) {
2361 node.value = textContent;
2362 }
2363 }
2364}
2365function restoreControlledState$2(element, props) {
2366 // DOM component is still mounted; update
2367 updateWrapper$1(element, props);
2368}
2369
2370var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2371var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2372var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; // Assumes there is no parent namespace.
2373
2374function getIntrinsicNamespace(type) {
2375 switch (type) {
2376 case 'svg':
2377 return SVG_NAMESPACE;
2378
2379 case 'math':
2380 return MATH_NAMESPACE;
2381
2382 default:
2383 return HTML_NAMESPACE;
2384 }
2385}
2386function getChildNamespace(parentNamespace, type) {
2387 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
2388 // No (or default) parent namespace: potential entry point.
2389 return getIntrinsicNamespace(type);
2390 }
2391
2392 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
2393 // We're leaving SVG.
2394 return HTML_NAMESPACE;
2395 } // By default, pass namespace below.
2396
2397
2398 return parentNamespace;
2399}
2400
2401/* globals MSApp */
2402
2403/**
2404 * Create a function which has 'unsafe' privileges (required by windows8 apps)
2405 */
2406var createMicrosoftUnsafeLocalFunction = function (func) {
2407 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
2408 return function (arg0, arg1, arg2, arg3) {
2409 MSApp.execUnsafeLocalFunction(function () {
2410 return func(arg0, arg1, arg2, arg3);
2411 });
2412 };
2413 } else {
2414 return func;
2415 }
2416};
2417
2418var reusableSVGContainer;
2419/**
2420 * Set the innerHTML property of a node
2421 *
2422 * @param {DOMElement} node
2423 * @param {string} html
2424 * @internal
2425 */
2426
2427var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
2428 if (node.namespaceURI === SVG_NAMESPACE) {
2429
2430 if (!('innerHTML' in node)) {
2431 // IE does not have innerHTML for SVG nodes, so instead we inject the
2432 // new markup in a temp node and then move the child nodes across into
2433 // the target node
2434 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
2435 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
2436 var svgNode = reusableSVGContainer.firstChild;
2437
2438 while (node.firstChild) {
2439 node.removeChild(node.firstChild);
2440 }
2441
2442 while (svgNode.firstChild) {
2443 node.appendChild(svgNode.firstChild);
2444 }
2445
2446 return;
2447 }
2448 }
2449
2450 node.innerHTML = html;
2451});
2452
2453/**
2454 * HTML nodeType values that represent the type of the node
2455 */
2456var ELEMENT_NODE = 1;
2457var TEXT_NODE = 3;
2458var COMMENT_NODE = 8;
2459var DOCUMENT_NODE = 9;
2460var DOCUMENT_FRAGMENT_NODE = 11;
2461
2462/**
2463 * Set the textContent property of a node. For text updates, it's faster
2464 * to set the `nodeValue` of the Text node directly instead of using
2465 * `.textContent` which will remove the existing node and create a new one.
2466 *
2467 * @param {DOMElement} node
2468 * @param {string} text
2469 * @internal
2470 */
2471
2472var setTextContent = function (node, text) {
2473 if (text) {
2474 var firstChild = node.firstChild;
2475
2476 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
2477 firstChild.nodeValue = text;
2478 return;
2479 }
2480 }
2481
2482 node.textContent = text;
2483};
2484
2485// List derived from Gecko source code:
2486// https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
2487var shorthandToLonghand = {
2488 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
2489 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
2490 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
2491 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2492 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
2493 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
2494 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
2495 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
2496 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
2497 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
2498 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
2499 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
2500 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
2501 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
2502 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
2503 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2504 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
2505 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
2506 columns: ['columnCount', 'columnWidth'],
2507 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
2508 flexFlow: ['flexDirection', 'flexWrap'],
2509 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
2510 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
2511 gap: ['columnGap', 'rowGap'],
2512 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2513 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
2514 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
2515 gridColumnGap: ['columnGap'],
2516 gridGap: ['columnGap', 'rowGap'],
2517 gridRow: ['gridRowEnd', 'gridRowStart'],
2518 gridRowGap: ['rowGap'],
2519 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2520 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
2521 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
2522 marker: ['markerEnd', 'markerMid', 'markerStart'],
2523 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
2524 maskPosition: ['maskPositionX', 'maskPositionY'],
2525 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
2526 overflow: ['overflowX', 'overflowY'],
2527 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
2528 placeContent: ['alignContent', 'justifyContent'],
2529 placeItems: ['alignItems', 'justifyItems'],
2530 placeSelf: ['alignSelf', 'justifySelf'],
2531 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
2532 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
2533 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
2534 wordWrap: ['overflowWrap']
2535};
2536
2537/**
2538 * CSS properties which accept numbers but are not in units of "px".
2539 */
2540var isUnitlessNumber = {
2541 animationIterationCount: true,
2542 aspectRatio: true,
2543 borderImageOutset: true,
2544 borderImageSlice: true,
2545 borderImageWidth: true,
2546 boxFlex: true,
2547 boxFlexGroup: true,
2548 boxOrdinalGroup: true,
2549 columnCount: true,
2550 columns: true,
2551 flex: true,
2552 flexGrow: true,
2553 flexPositive: true,
2554 flexShrink: true,
2555 flexNegative: true,
2556 flexOrder: true,
2557 gridArea: true,
2558 gridRow: true,
2559 gridRowEnd: true,
2560 gridRowSpan: true,
2561 gridRowStart: true,
2562 gridColumn: true,
2563 gridColumnEnd: true,
2564 gridColumnSpan: true,
2565 gridColumnStart: true,
2566 fontWeight: true,
2567 lineClamp: true,
2568 lineHeight: true,
2569 opacity: true,
2570 order: true,
2571 orphans: true,
2572 tabSize: true,
2573 widows: true,
2574 zIndex: true,
2575 zoom: true,
2576 // SVG-related properties
2577 fillOpacity: true,
2578 floodOpacity: true,
2579 stopOpacity: true,
2580 strokeDasharray: true,
2581 strokeDashoffset: true,
2582 strokeMiterlimit: true,
2583 strokeOpacity: true,
2584 strokeWidth: true
2585};
2586/**
2587 * @param {string} prefix vendor-specific prefix, eg: Webkit
2588 * @param {string} key style name, eg: transitionDuration
2589 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
2590 * WebkitTransitionDuration
2591 */
2592
2593function prefixKey(prefix, key) {
2594 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
2595}
2596/**
2597 * Support style names that may come passed in prefixed by adding permutations
2598 * of vendor prefixes.
2599 */
2600
2601
2602var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
2603// infinite loop, because it iterates over the newly added props too.
2604
2605Object.keys(isUnitlessNumber).forEach(function (prop) {
2606 prefixes.forEach(function (prefix) {
2607 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
2608 });
2609});
2610
2611/**
2612 * Convert a value into the proper css writable value. The style name `name`
2613 * should be logical (no hyphens), as specified
2614 * in `CSSProperty.isUnitlessNumber`.
2615 *
2616 * @param {string} name CSS property name such as `topMargin`.
2617 * @param {*} value CSS property value such as `10px`.
2618 * @return {string} Normalized style value with dimensions applied.
2619 */
2620
2621function dangerousStyleValue(name, value, isCustomProperty) {
2622 // Note that we've removed escapeTextForBrowser() calls here since the
2623 // whole string will be escaped when the attribute is injected into
2624 // the markup. If you provide unsafe user data here they can inject
2625 // arbitrary CSS which may be problematic (I couldn't repro this):
2626 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
2627 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
2628 // This is not an XSS hole but instead a potential CSS injection issue
2629 // which has lead to a greater discussion about how we're going to
2630 // trust URLs moving forward. See #2115901
2631 var isEmpty = value == null || typeof value === 'boolean' || value === '';
2632
2633 if (isEmpty) {
2634 return '';
2635 }
2636
2637 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
2638 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
2639 }
2640
2641 {
2642 checkCSSPropertyStringCoercion(value, name);
2643 }
2644
2645 return ('' + value).trim();
2646}
2647
2648var uppercasePattern = /([A-Z])/g;
2649var msPattern = /^ms-/;
2650/**
2651 * Hyphenates a camelcased CSS property name, for example:
2652 *
2653 * > hyphenateStyleName('backgroundColor')
2654 * < "background-color"
2655 * > hyphenateStyleName('MozTransition')
2656 * < "-moz-transition"
2657 * > hyphenateStyleName('msTransition')
2658 * < "-ms-transition"
2659 *
2660 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
2661 * is converted to `-ms-`.
2662 */
2663
2664function hyphenateStyleName(name) {
2665 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
2666}
2667
2668var warnValidStyle = function () {};
2669
2670{
2671 // 'msTransform' is correct, but the other prefixes should be capitalized
2672 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
2673 var msPattern$1 = /^-ms-/;
2674 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
2675
2676 var badStyleValueWithSemicolonPattern = /;\s*$/;
2677 var warnedStyleNames = {};
2678 var warnedStyleValues = {};
2679 var warnedForNaNValue = false;
2680 var warnedForInfinityValue = false;
2681
2682 var camelize = function (string) {
2683 return string.replace(hyphenPattern, function (_, character) {
2684 return character.toUpperCase();
2685 });
2686 };
2687
2688 var warnHyphenatedStyleName = function (name) {
2689 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2690 return;
2691 }
2692
2693 warnedStyleNames[name] = true;
2694
2695 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
2696 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
2697 // is converted to lowercase `ms`.
2698 camelize(name.replace(msPattern$1, 'ms-')));
2699 };
2700
2701 var warnBadVendoredStyleName = function (name) {
2702 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2703 return;
2704 }
2705
2706 warnedStyleNames[name] = true;
2707
2708 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
2709 };
2710
2711 var warnStyleValueWithSemicolon = function (name, value) {
2712 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
2713 return;
2714 }
2715
2716 warnedStyleValues[value] = true;
2717
2718 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
2719 };
2720
2721 var warnStyleValueIsNaN = function (name, value) {
2722 if (warnedForNaNValue) {
2723 return;
2724 }
2725
2726 warnedForNaNValue = true;
2727
2728 error('`NaN` is an invalid value for the `%s` css style property.', name);
2729 };
2730
2731 var warnStyleValueIsInfinity = function (name, value) {
2732 if (warnedForInfinityValue) {
2733 return;
2734 }
2735
2736 warnedForInfinityValue = true;
2737
2738 error('`Infinity` is an invalid value for the `%s` css style property.', name);
2739 };
2740
2741 warnValidStyle = function (name, value) {
2742 if (name.indexOf('-') > -1) {
2743 warnHyphenatedStyleName(name);
2744 } else if (badVendoredStyleNamePattern.test(name)) {
2745 warnBadVendoredStyleName(name);
2746 } else if (badStyleValueWithSemicolonPattern.test(value)) {
2747 warnStyleValueWithSemicolon(name, value);
2748 }
2749
2750 if (typeof value === 'number') {
2751 if (isNaN(value)) {
2752 warnStyleValueIsNaN(name, value);
2753 } else if (!isFinite(value)) {
2754 warnStyleValueIsInfinity(name, value);
2755 }
2756 }
2757 };
2758}
2759
2760var warnValidStyle$1 = warnValidStyle;
2761
2762/**
2763 * Operations for dealing with CSS properties.
2764 */
2765
2766/**
2767 * This creates a string that is expected to be equivalent to the style
2768 * attribute generated by server-side rendering. It by-passes warnings and
2769 * security checks so it's not safe to use this value for anything other than
2770 * comparison. It is only used in DEV for SSR validation.
2771 */
2772
2773function createDangerousStringForStyles(styles) {
2774 {
2775 var serialized = '';
2776 var delimiter = '';
2777
2778 for (var styleName in styles) {
2779 if (!styles.hasOwnProperty(styleName)) {
2780 continue;
2781 }
2782
2783 var styleValue = styles[styleName];
2784
2785 if (styleValue != null) {
2786 var isCustomProperty = styleName.indexOf('--') === 0;
2787 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
2788 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
2789 delimiter = ';';
2790 }
2791 }
2792
2793 return serialized || null;
2794 }
2795}
2796/**
2797 * Sets the value for multiple styles on a node. If a value is specified as
2798 * '' (empty string), the corresponding style property will be unset.
2799 *
2800 * @param {DOMElement} node
2801 * @param {object} styles
2802 */
2803
2804function setValueForStyles(node, styles) {
2805 var style = node.style;
2806
2807 for (var styleName in styles) {
2808 if (!styles.hasOwnProperty(styleName)) {
2809 continue;
2810 }
2811
2812 var isCustomProperty = styleName.indexOf('--') === 0;
2813
2814 {
2815 if (!isCustomProperty) {
2816 warnValidStyle$1(styleName, styles[styleName]);
2817 }
2818 }
2819
2820 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
2821
2822 if (styleName === 'float') {
2823 styleName = 'cssFloat';
2824 }
2825
2826 if (isCustomProperty) {
2827 style.setProperty(styleName, styleValue);
2828 } else {
2829 style[styleName] = styleValue;
2830 }
2831 }
2832}
2833
2834function isValueEmpty(value) {
2835 return value == null || typeof value === 'boolean' || value === '';
2836}
2837/**
2838 * Given {color: 'red', overflow: 'hidden'} returns {
2839 * color: 'color',
2840 * overflowX: 'overflow',
2841 * overflowY: 'overflow',
2842 * }. This can be read as "the overflowY property was set by the overflow
2843 * shorthand". That is, the values are the property that each was derived from.
2844 */
2845
2846
2847function expandShorthandMap(styles) {
2848 var expanded = {};
2849
2850 for (var key in styles) {
2851 var longhands = shorthandToLonghand[key] || [key];
2852
2853 for (var i = 0; i < longhands.length; i++) {
2854 expanded[longhands[i]] = key;
2855 }
2856 }
2857
2858 return expanded;
2859}
2860/**
2861 * When mixing shorthand and longhand property names, we warn during updates if
2862 * we expect an incorrect result to occur. In particular, we warn for:
2863 *
2864 * Updating a shorthand property (longhand gets overwritten):
2865 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
2866 * becomes .style.font = 'baz'
2867 * Removing a shorthand property (longhand gets lost too):
2868 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
2869 * becomes .style.font = ''
2870 * Removing a longhand property (should revert to shorthand; doesn't):
2871 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
2872 * becomes .style.fontVariant = ''
2873 */
2874
2875
2876function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
2877 {
2878 if (!nextStyles) {
2879 return;
2880 }
2881
2882 var expandedUpdates = expandShorthandMap(styleUpdates);
2883 var expandedStyles = expandShorthandMap(nextStyles);
2884 var warnedAbout = {};
2885
2886 for (var key in expandedUpdates) {
2887 var originalKey = expandedUpdates[key];
2888 var correctOriginalKey = expandedStyles[key];
2889
2890 if (correctOriginalKey && originalKey !== correctOriginalKey) {
2891 var warningKey = originalKey + ',' + correctOriginalKey;
2892
2893 if (warnedAbout[warningKey]) {
2894 continue;
2895 }
2896
2897 warnedAbout[warningKey] = true;
2898
2899 error('%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);
2900 }
2901 }
2902 }
2903}
2904
2905// For HTML, certain tags should omit their close tag. We keep a list for
2906// those special-case tags.
2907var omittedCloseTags = {
2908 area: true,
2909 base: true,
2910 br: true,
2911 col: true,
2912 embed: true,
2913 hr: true,
2914 img: true,
2915 input: true,
2916 keygen: true,
2917 link: true,
2918 meta: true,
2919 param: true,
2920 source: true,
2921 track: true,
2922 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
2923
2924};
2925
2926// `omittedCloseTags` except that `menuitem` should still have its closing tag.
2927
2928var voidElementTags = assign({
2929 menuitem: true
2930}, omittedCloseTags);
2931
2932var HTML = '__html';
2933
2934function assertValidProps(tag, props) {
2935 if (!props) {
2936 return;
2937 } // Note the use of `==` which checks for null or undefined.
2938
2939
2940 if (voidElementTags[tag]) {
2941 if (props.children != null || props.dangerouslySetInnerHTML != null) {
2942 throw new Error(tag + " is a void element tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.');
2943 }
2944 }
2945
2946 if (props.dangerouslySetInnerHTML != null) {
2947 if (props.children != null) {
2948 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.');
2949 }
2950
2951 if (typeof props.dangerouslySetInnerHTML !== 'object' || !(HTML in props.dangerouslySetInnerHTML)) {
2952 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://reactjs.org/link/dangerously-set-inner-html ' + 'for more information.');
2953 }
2954 }
2955
2956 {
2957 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
2958 error('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.');
2959 }
2960 }
2961
2962 if (props.style != null && typeof props.style !== 'object') {
2963 throw new Error('The `style` prop expects a mapping from style properties to values, ' + "not a string. For example, style={{marginRight: spacing + 'em'}} when " + 'using JSX.');
2964 }
2965}
2966
2967function isCustomComponent(tagName, props) {
2968 if (tagName.indexOf('-') === -1) {
2969 return typeof props.is === 'string';
2970 }
2971
2972 switch (tagName) {
2973 // These are reserved SVG and MathML elements.
2974 // We don't mind this list too much because we expect it to never grow.
2975 // The alternative is to track the namespace in a few places which is convoluted.
2976 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
2977 case 'annotation-xml':
2978 case 'color-profile':
2979 case 'font-face':
2980 case 'font-face-src':
2981 case 'font-face-uri':
2982 case 'font-face-format':
2983 case 'font-face-name':
2984 case 'missing-glyph':
2985 return false;
2986
2987 default:
2988 return true;
2989 }
2990}
2991
2992// When adding attributes to the HTML or SVG allowed attribute list, be sure to
2993// also add them to this module to ensure casing and incorrect name
2994// warnings.
2995var possibleStandardNames = {
2996 // HTML
2997 accept: 'accept',
2998 acceptcharset: 'acceptCharset',
2999 'accept-charset': 'acceptCharset',
3000 accesskey: 'accessKey',
3001 action: 'action',
3002 allowfullscreen: 'allowFullScreen',
3003 alt: 'alt',
3004 as: 'as',
3005 async: 'async',
3006 autocapitalize: 'autoCapitalize',
3007 autocomplete: 'autoComplete',
3008 autocorrect: 'autoCorrect',
3009 autofocus: 'autoFocus',
3010 autoplay: 'autoPlay',
3011 autosave: 'autoSave',
3012 capture: 'capture',
3013 cellpadding: 'cellPadding',
3014 cellspacing: 'cellSpacing',
3015 challenge: 'challenge',
3016 charset: 'charSet',
3017 checked: 'checked',
3018 children: 'children',
3019 cite: 'cite',
3020 class: 'className',
3021 classid: 'classID',
3022 classname: 'className',
3023 cols: 'cols',
3024 colspan: 'colSpan',
3025 content: 'content',
3026 contenteditable: 'contentEditable',
3027 contextmenu: 'contextMenu',
3028 controls: 'controls',
3029 controlslist: 'controlsList',
3030 coords: 'coords',
3031 crossorigin: 'crossOrigin',
3032 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
3033 data: 'data',
3034 datetime: 'dateTime',
3035 default: 'default',
3036 defaultchecked: 'defaultChecked',
3037 defaultvalue: 'defaultValue',
3038 defer: 'defer',
3039 dir: 'dir',
3040 disabled: 'disabled',
3041 disablepictureinpicture: 'disablePictureInPicture',
3042 disableremoteplayback: 'disableRemotePlayback',
3043 download: 'download',
3044 draggable: 'draggable',
3045 enctype: 'encType',
3046 enterkeyhint: 'enterKeyHint',
3047 for: 'htmlFor',
3048 form: 'form',
3049 formmethod: 'formMethod',
3050 formaction: 'formAction',
3051 formenctype: 'formEncType',
3052 formnovalidate: 'formNoValidate',
3053 formtarget: 'formTarget',
3054 frameborder: 'frameBorder',
3055 headers: 'headers',
3056 height: 'height',
3057 hidden: 'hidden',
3058 high: 'high',
3059 href: 'href',
3060 hreflang: 'hrefLang',
3061 htmlfor: 'htmlFor',
3062 httpequiv: 'httpEquiv',
3063 'http-equiv': 'httpEquiv',
3064 icon: 'icon',
3065 id: 'id',
3066 imagesizes: 'imageSizes',
3067 imagesrcset: 'imageSrcSet',
3068 innerhtml: 'innerHTML',
3069 inputmode: 'inputMode',
3070 integrity: 'integrity',
3071 is: 'is',
3072 itemid: 'itemID',
3073 itemprop: 'itemProp',
3074 itemref: 'itemRef',
3075 itemscope: 'itemScope',
3076 itemtype: 'itemType',
3077 keyparams: 'keyParams',
3078 keytype: 'keyType',
3079 kind: 'kind',
3080 label: 'label',
3081 lang: 'lang',
3082 list: 'list',
3083 loop: 'loop',
3084 low: 'low',
3085 manifest: 'manifest',
3086 marginwidth: 'marginWidth',
3087 marginheight: 'marginHeight',
3088 max: 'max',
3089 maxlength: 'maxLength',
3090 media: 'media',
3091 mediagroup: 'mediaGroup',
3092 method: 'method',
3093 min: 'min',
3094 minlength: 'minLength',
3095 multiple: 'multiple',
3096 muted: 'muted',
3097 name: 'name',
3098 nomodule: 'noModule',
3099 nonce: 'nonce',
3100 novalidate: 'noValidate',
3101 open: 'open',
3102 optimum: 'optimum',
3103 pattern: 'pattern',
3104 placeholder: 'placeholder',
3105 playsinline: 'playsInline',
3106 poster: 'poster',
3107 preload: 'preload',
3108 profile: 'profile',
3109 radiogroup: 'radioGroup',
3110 readonly: 'readOnly',
3111 referrerpolicy: 'referrerPolicy',
3112 rel: 'rel',
3113 required: 'required',
3114 reversed: 'reversed',
3115 role: 'role',
3116 rows: 'rows',
3117 rowspan: 'rowSpan',
3118 sandbox: 'sandbox',
3119 scope: 'scope',
3120 scoped: 'scoped',
3121 scrolling: 'scrolling',
3122 seamless: 'seamless',
3123 selected: 'selected',
3124 shape: 'shape',
3125 size: 'size',
3126 sizes: 'sizes',
3127 span: 'span',
3128 spellcheck: 'spellCheck',
3129 src: 'src',
3130 srcdoc: 'srcDoc',
3131 srclang: 'srcLang',
3132 srcset: 'srcSet',
3133 start: 'start',
3134 step: 'step',
3135 style: 'style',
3136 summary: 'summary',
3137 tabindex: 'tabIndex',
3138 target: 'target',
3139 title: 'title',
3140 type: 'type',
3141 usemap: 'useMap',
3142 value: 'value',
3143 width: 'width',
3144 wmode: 'wmode',
3145 wrap: 'wrap',
3146 // SVG
3147 about: 'about',
3148 accentheight: 'accentHeight',
3149 'accent-height': 'accentHeight',
3150 accumulate: 'accumulate',
3151 additive: 'additive',
3152 alignmentbaseline: 'alignmentBaseline',
3153 'alignment-baseline': 'alignmentBaseline',
3154 allowreorder: 'allowReorder',
3155 alphabetic: 'alphabetic',
3156 amplitude: 'amplitude',
3157 arabicform: 'arabicForm',
3158 'arabic-form': 'arabicForm',
3159 ascent: 'ascent',
3160 attributename: 'attributeName',
3161 attributetype: 'attributeType',
3162 autoreverse: 'autoReverse',
3163 azimuth: 'azimuth',
3164 basefrequency: 'baseFrequency',
3165 baselineshift: 'baselineShift',
3166 'baseline-shift': 'baselineShift',
3167 baseprofile: 'baseProfile',
3168 bbox: 'bbox',
3169 begin: 'begin',
3170 bias: 'bias',
3171 by: 'by',
3172 calcmode: 'calcMode',
3173 capheight: 'capHeight',
3174 'cap-height': 'capHeight',
3175 clip: 'clip',
3176 clippath: 'clipPath',
3177 'clip-path': 'clipPath',
3178 clippathunits: 'clipPathUnits',
3179 cliprule: 'clipRule',
3180 'clip-rule': 'clipRule',
3181 color: 'color',
3182 colorinterpolation: 'colorInterpolation',
3183 'color-interpolation': 'colorInterpolation',
3184 colorinterpolationfilters: 'colorInterpolationFilters',
3185 'color-interpolation-filters': 'colorInterpolationFilters',
3186 colorprofile: 'colorProfile',
3187 'color-profile': 'colorProfile',
3188 colorrendering: 'colorRendering',
3189 'color-rendering': 'colorRendering',
3190 contentscripttype: 'contentScriptType',
3191 contentstyletype: 'contentStyleType',
3192 cursor: 'cursor',
3193 cx: 'cx',
3194 cy: 'cy',
3195 d: 'd',
3196 datatype: 'datatype',
3197 decelerate: 'decelerate',
3198 descent: 'descent',
3199 diffuseconstant: 'diffuseConstant',
3200 direction: 'direction',
3201 display: 'display',
3202 divisor: 'divisor',
3203 dominantbaseline: 'dominantBaseline',
3204 'dominant-baseline': 'dominantBaseline',
3205 dur: 'dur',
3206 dx: 'dx',
3207 dy: 'dy',
3208 edgemode: 'edgeMode',
3209 elevation: 'elevation',
3210 enablebackground: 'enableBackground',
3211 'enable-background': 'enableBackground',
3212 end: 'end',
3213 exponent: 'exponent',
3214 externalresourcesrequired: 'externalResourcesRequired',
3215 fill: 'fill',
3216 fillopacity: 'fillOpacity',
3217 'fill-opacity': 'fillOpacity',
3218 fillrule: 'fillRule',
3219 'fill-rule': 'fillRule',
3220 filter: 'filter',
3221 filterres: 'filterRes',
3222 filterunits: 'filterUnits',
3223 floodopacity: 'floodOpacity',
3224 'flood-opacity': 'floodOpacity',
3225 floodcolor: 'floodColor',
3226 'flood-color': 'floodColor',
3227 focusable: 'focusable',
3228 fontfamily: 'fontFamily',
3229 'font-family': 'fontFamily',
3230 fontsize: 'fontSize',
3231 'font-size': 'fontSize',
3232 fontsizeadjust: 'fontSizeAdjust',
3233 'font-size-adjust': 'fontSizeAdjust',
3234 fontstretch: 'fontStretch',
3235 'font-stretch': 'fontStretch',
3236 fontstyle: 'fontStyle',
3237 'font-style': 'fontStyle',
3238 fontvariant: 'fontVariant',
3239 'font-variant': 'fontVariant',
3240 fontweight: 'fontWeight',
3241 'font-weight': 'fontWeight',
3242 format: 'format',
3243 from: 'from',
3244 fx: 'fx',
3245 fy: 'fy',
3246 g1: 'g1',
3247 g2: 'g2',
3248 glyphname: 'glyphName',
3249 'glyph-name': 'glyphName',
3250 glyphorientationhorizontal: 'glyphOrientationHorizontal',
3251 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
3252 glyphorientationvertical: 'glyphOrientationVertical',
3253 'glyph-orientation-vertical': 'glyphOrientationVertical',
3254 glyphref: 'glyphRef',
3255 gradienttransform: 'gradientTransform',
3256 gradientunits: 'gradientUnits',
3257 hanging: 'hanging',
3258 horizadvx: 'horizAdvX',
3259 'horiz-adv-x': 'horizAdvX',
3260 horizoriginx: 'horizOriginX',
3261 'horiz-origin-x': 'horizOriginX',
3262 ideographic: 'ideographic',
3263 imagerendering: 'imageRendering',
3264 'image-rendering': 'imageRendering',
3265 in2: 'in2',
3266 in: 'in',
3267 inlist: 'inlist',
3268 intercept: 'intercept',
3269 k1: 'k1',
3270 k2: 'k2',
3271 k3: 'k3',
3272 k4: 'k4',
3273 k: 'k',
3274 kernelmatrix: 'kernelMatrix',
3275 kernelunitlength: 'kernelUnitLength',
3276 kerning: 'kerning',
3277 keypoints: 'keyPoints',
3278 keysplines: 'keySplines',
3279 keytimes: 'keyTimes',
3280 lengthadjust: 'lengthAdjust',
3281 letterspacing: 'letterSpacing',
3282 'letter-spacing': 'letterSpacing',
3283 lightingcolor: 'lightingColor',
3284 'lighting-color': 'lightingColor',
3285 limitingconeangle: 'limitingConeAngle',
3286 local: 'local',
3287 markerend: 'markerEnd',
3288 'marker-end': 'markerEnd',
3289 markerheight: 'markerHeight',
3290 markermid: 'markerMid',
3291 'marker-mid': 'markerMid',
3292 markerstart: 'markerStart',
3293 'marker-start': 'markerStart',
3294 markerunits: 'markerUnits',
3295 markerwidth: 'markerWidth',
3296 mask: 'mask',
3297 maskcontentunits: 'maskContentUnits',
3298 maskunits: 'maskUnits',
3299 mathematical: 'mathematical',
3300 mode: 'mode',
3301 numoctaves: 'numOctaves',
3302 offset: 'offset',
3303 opacity: 'opacity',
3304 operator: 'operator',
3305 order: 'order',
3306 orient: 'orient',
3307 orientation: 'orientation',
3308 origin: 'origin',
3309 overflow: 'overflow',
3310 overlineposition: 'overlinePosition',
3311 'overline-position': 'overlinePosition',
3312 overlinethickness: 'overlineThickness',
3313 'overline-thickness': 'overlineThickness',
3314 paintorder: 'paintOrder',
3315 'paint-order': 'paintOrder',
3316 panose1: 'panose1',
3317 'panose-1': 'panose1',
3318 pathlength: 'pathLength',
3319 patterncontentunits: 'patternContentUnits',
3320 patterntransform: 'patternTransform',
3321 patternunits: 'patternUnits',
3322 pointerevents: 'pointerEvents',
3323 'pointer-events': 'pointerEvents',
3324 points: 'points',
3325 pointsatx: 'pointsAtX',
3326 pointsaty: 'pointsAtY',
3327 pointsatz: 'pointsAtZ',
3328 prefix: 'prefix',
3329 preservealpha: 'preserveAlpha',
3330 preserveaspectratio: 'preserveAspectRatio',
3331 primitiveunits: 'primitiveUnits',
3332 property: 'property',
3333 r: 'r',
3334 radius: 'radius',
3335 refx: 'refX',
3336 refy: 'refY',
3337 renderingintent: 'renderingIntent',
3338 'rendering-intent': 'renderingIntent',
3339 repeatcount: 'repeatCount',
3340 repeatdur: 'repeatDur',
3341 requiredextensions: 'requiredExtensions',
3342 requiredfeatures: 'requiredFeatures',
3343 resource: 'resource',
3344 restart: 'restart',
3345 result: 'result',
3346 results: 'results',
3347 rotate: 'rotate',
3348 rx: 'rx',
3349 ry: 'ry',
3350 scale: 'scale',
3351 security: 'security',
3352 seed: 'seed',
3353 shaperendering: 'shapeRendering',
3354 'shape-rendering': 'shapeRendering',
3355 slope: 'slope',
3356 spacing: 'spacing',
3357 specularconstant: 'specularConstant',
3358 specularexponent: 'specularExponent',
3359 speed: 'speed',
3360 spreadmethod: 'spreadMethod',
3361 startoffset: 'startOffset',
3362 stddeviation: 'stdDeviation',
3363 stemh: 'stemh',
3364 stemv: 'stemv',
3365 stitchtiles: 'stitchTiles',
3366 stopcolor: 'stopColor',
3367 'stop-color': 'stopColor',
3368 stopopacity: 'stopOpacity',
3369 'stop-opacity': 'stopOpacity',
3370 strikethroughposition: 'strikethroughPosition',
3371 'strikethrough-position': 'strikethroughPosition',
3372 strikethroughthickness: 'strikethroughThickness',
3373 'strikethrough-thickness': 'strikethroughThickness',
3374 string: 'string',
3375 stroke: 'stroke',
3376 strokedasharray: 'strokeDasharray',
3377 'stroke-dasharray': 'strokeDasharray',
3378 strokedashoffset: 'strokeDashoffset',
3379 'stroke-dashoffset': 'strokeDashoffset',
3380 strokelinecap: 'strokeLinecap',
3381 'stroke-linecap': 'strokeLinecap',
3382 strokelinejoin: 'strokeLinejoin',
3383 'stroke-linejoin': 'strokeLinejoin',
3384 strokemiterlimit: 'strokeMiterlimit',
3385 'stroke-miterlimit': 'strokeMiterlimit',
3386 strokewidth: 'strokeWidth',
3387 'stroke-width': 'strokeWidth',
3388 strokeopacity: 'strokeOpacity',
3389 'stroke-opacity': 'strokeOpacity',
3390 suppresscontenteditablewarning: 'suppressContentEditableWarning',
3391 suppresshydrationwarning: 'suppressHydrationWarning',
3392 surfacescale: 'surfaceScale',
3393 systemlanguage: 'systemLanguage',
3394 tablevalues: 'tableValues',
3395 targetx: 'targetX',
3396 targety: 'targetY',
3397 textanchor: 'textAnchor',
3398 'text-anchor': 'textAnchor',
3399 textdecoration: 'textDecoration',
3400 'text-decoration': 'textDecoration',
3401 textlength: 'textLength',
3402 textrendering: 'textRendering',
3403 'text-rendering': 'textRendering',
3404 to: 'to',
3405 transform: 'transform',
3406 typeof: 'typeof',
3407 u1: 'u1',
3408 u2: 'u2',
3409 underlineposition: 'underlinePosition',
3410 'underline-position': 'underlinePosition',
3411 underlinethickness: 'underlineThickness',
3412 'underline-thickness': 'underlineThickness',
3413 unicode: 'unicode',
3414 unicodebidi: 'unicodeBidi',
3415 'unicode-bidi': 'unicodeBidi',
3416 unicoderange: 'unicodeRange',
3417 'unicode-range': 'unicodeRange',
3418 unitsperem: 'unitsPerEm',
3419 'units-per-em': 'unitsPerEm',
3420 unselectable: 'unselectable',
3421 valphabetic: 'vAlphabetic',
3422 'v-alphabetic': 'vAlphabetic',
3423 values: 'values',
3424 vectoreffect: 'vectorEffect',
3425 'vector-effect': 'vectorEffect',
3426 version: 'version',
3427 vertadvy: 'vertAdvY',
3428 'vert-adv-y': 'vertAdvY',
3429 vertoriginx: 'vertOriginX',
3430 'vert-origin-x': 'vertOriginX',
3431 vertoriginy: 'vertOriginY',
3432 'vert-origin-y': 'vertOriginY',
3433 vhanging: 'vHanging',
3434 'v-hanging': 'vHanging',
3435 videographic: 'vIdeographic',
3436 'v-ideographic': 'vIdeographic',
3437 viewbox: 'viewBox',
3438 viewtarget: 'viewTarget',
3439 visibility: 'visibility',
3440 vmathematical: 'vMathematical',
3441 'v-mathematical': 'vMathematical',
3442 vocab: 'vocab',
3443 widths: 'widths',
3444 wordspacing: 'wordSpacing',
3445 'word-spacing': 'wordSpacing',
3446 writingmode: 'writingMode',
3447 'writing-mode': 'writingMode',
3448 x1: 'x1',
3449 x2: 'x2',
3450 x: 'x',
3451 xchannelselector: 'xChannelSelector',
3452 xheight: 'xHeight',
3453 'x-height': 'xHeight',
3454 xlinkactuate: 'xlinkActuate',
3455 'xlink:actuate': 'xlinkActuate',
3456 xlinkarcrole: 'xlinkArcrole',
3457 'xlink:arcrole': 'xlinkArcrole',
3458 xlinkhref: 'xlinkHref',
3459 'xlink:href': 'xlinkHref',
3460 xlinkrole: 'xlinkRole',
3461 'xlink:role': 'xlinkRole',
3462 xlinkshow: 'xlinkShow',
3463 'xlink:show': 'xlinkShow',
3464 xlinktitle: 'xlinkTitle',
3465 'xlink:title': 'xlinkTitle',
3466 xlinktype: 'xlinkType',
3467 'xlink:type': 'xlinkType',
3468 xmlbase: 'xmlBase',
3469 'xml:base': 'xmlBase',
3470 xmllang: 'xmlLang',
3471 'xml:lang': 'xmlLang',
3472 xmlns: 'xmlns',
3473 'xml:space': 'xmlSpace',
3474 xmlnsxlink: 'xmlnsXlink',
3475 'xmlns:xlink': 'xmlnsXlink',
3476 xmlspace: 'xmlSpace',
3477 y1: 'y1',
3478 y2: 'y2',
3479 y: 'y',
3480 ychannelselector: 'yChannelSelector',
3481 z: 'z',
3482 zoomandpan: 'zoomAndPan'
3483};
3484
3485var ariaProperties = {
3486 'aria-current': 0,
3487 // state
3488 'aria-description': 0,
3489 'aria-details': 0,
3490 'aria-disabled': 0,
3491 // state
3492 'aria-hidden': 0,
3493 // state
3494 'aria-invalid': 0,
3495 // state
3496 'aria-keyshortcuts': 0,
3497 'aria-label': 0,
3498 'aria-roledescription': 0,
3499 // Widget Attributes
3500 'aria-autocomplete': 0,
3501 'aria-checked': 0,
3502 'aria-expanded': 0,
3503 'aria-haspopup': 0,
3504 'aria-level': 0,
3505 'aria-modal': 0,
3506 'aria-multiline': 0,
3507 'aria-multiselectable': 0,
3508 'aria-orientation': 0,
3509 'aria-placeholder': 0,
3510 'aria-pressed': 0,
3511 'aria-readonly': 0,
3512 'aria-required': 0,
3513 'aria-selected': 0,
3514 'aria-sort': 0,
3515 'aria-valuemax': 0,
3516 'aria-valuemin': 0,
3517 'aria-valuenow': 0,
3518 'aria-valuetext': 0,
3519 // Live Region Attributes
3520 'aria-atomic': 0,
3521 'aria-busy': 0,
3522 'aria-live': 0,
3523 'aria-relevant': 0,
3524 // Drag-and-Drop Attributes
3525 'aria-dropeffect': 0,
3526 'aria-grabbed': 0,
3527 // Relationship Attributes
3528 'aria-activedescendant': 0,
3529 'aria-colcount': 0,
3530 'aria-colindex': 0,
3531 'aria-colspan': 0,
3532 'aria-controls': 0,
3533 'aria-describedby': 0,
3534 'aria-errormessage': 0,
3535 'aria-flowto': 0,
3536 'aria-labelledby': 0,
3537 'aria-owns': 0,
3538 'aria-posinset': 0,
3539 'aria-rowcount': 0,
3540 'aria-rowindex': 0,
3541 'aria-rowspan': 0,
3542 'aria-setsize': 0
3543};
3544
3545var warnedProperties = {};
3546var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3547var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3548
3549function validateProperty(tagName, name) {
3550 {
3551 if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
3552 return true;
3553 }
3554
3555 if (rARIACamel.test(name)) {
3556 var ariaName = 'aria-' + name.slice(4).toLowerCase();
3557 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3558 // DOM properties, then it is an invalid aria-* attribute.
3559
3560 if (correctName == null) {
3561 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
3562
3563 warnedProperties[name] = true;
3564 return true;
3565 } // aria-* attributes should be lowercase; suggest the lowercase version.
3566
3567
3568 if (name !== correctName) {
3569 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
3570
3571 warnedProperties[name] = true;
3572 return true;
3573 }
3574 }
3575
3576 if (rARIA.test(name)) {
3577 var lowerCasedName = name.toLowerCase();
3578 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3579 // DOM properties, then it is an invalid aria-* attribute.
3580
3581 if (standardName == null) {
3582 warnedProperties[name] = true;
3583 return false;
3584 } // aria-* attributes should be lowercase; suggest the lowercase version.
3585
3586
3587 if (name !== standardName) {
3588 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
3589
3590 warnedProperties[name] = true;
3591 return true;
3592 }
3593 }
3594 }
3595
3596 return true;
3597}
3598
3599function warnInvalidARIAProps(type, props) {
3600 {
3601 var invalidProps = [];
3602
3603 for (var key in props) {
3604 var isValid = validateProperty(type, key);
3605
3606 if (!isValid) {
3607 invalidProps.push(key);
3608 }
3609 }
3610
3611 var unknownPropString = invalidProps.map(function (prop) {
3612 return '`' + prop + '`';
3613 }).join(', ');
3614
3615 if (invalidProps.length === 1) {
3616 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3617 } else if (invalidProps.length > 1) {
3618 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3619 }
3620 }
3621}
3622
3623function validateProperties(type, props) {
3624 if (isCustomComponent(type, props)) {
3625 return;
3626 }
3627
3628 warnInvalidARIAProps(type, props);
3629}
3630
3631var didWarnValueNull = false;
3632function validateProperties$1(type, props) {
3633 {
3634 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
3635 return;
3636 }
3637
3638 if (props != null && props.value === null && !didWarnValueNull) {
3639 didWarnValueNull = true;
3640
3641 if (type === 'select' && props.multiple) {
3642 error('`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);
3643 } else {
3644 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
3645 }
3646 }
3647 }
3648}
3649
3650var validateProperty$1 = function () {};
3651
3652{
3653 var warnedProperties$1 = {};
3654 var EVENT_NAME_REGEX = /^on./;
3655 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
3656 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3657 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3658
3659 validateProperty$1 = function (tagName, name, value, eventRegistry) {
3660 if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
3661 return true;
3662 }
3663
3664 var lowerCasedName = name.toLowerCase();
3665
3666 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
3667 error('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.');
3668
3669 warnedProperties$1[name] = true;
3670 return true;
3671 } // We can't rely on the event system being injected on the server.
3672
3673
3674 if (eventRegistry != null) {
3675 var registrationNameDependencies = eventRegistry.registrationNameDependencies,
3676 possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
3677
3678 if (registrationNameDependencies.hasOwnProperty(name)) {
3679 return true;
3680 }
3681
3682 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
3683
3684 if (registrationName != null) {
3685 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
3686
3687 warnedProperties$1[name] = true;
3688 return true;
3689 }
3690
3691 if (EVENT_NAME_REGEX.test(name)) {
3692 error('Unknown event handler property `%s`. It will be ignored.', name);
3693
3694 warnedProperties$1[name] = true;
3695 return true;
3696 }
3697 } else if (EVENT_NAME_REGEX.test(name)) {
3698 // If no event plugins have been injected, we are in a server environment.
3699 // So we can't tell if the event name is correct for sure, but we can filter
3700 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
3701 if (INVALID_EVENT_NAME_REGEX.test(name)) {
3702 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
3703 }
3704
3705 warnedProperties$1[name] = true;
3706 return true;
3707 } // Let the ARIA attribute hook validate ARIA attributes
3708
3709
3710 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
3711 return true;
3712 }
3713
3714 if (lowerCasedName === 'innerhtml') {
3715 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
3716
3717 warnedProperties$1[name] = true;
3718 return true;
3719 }
3720
3721 if (lowerCasedName === 'aria') {
3722 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
3723
3724 warnedProperties$1[name] = true;
3725 return true;
3726 }
3727
3728 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
3729 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
3730
3731 warnedProperties$1[name] = true;
3732 return true;
3733 }
3734
3735 if (typeof value === 'number' && isNaN(value)) {
3736 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
3737
3738 warnedProperties$1[name] = true;
3739 return true;
3740 }
3741
3742 var propertyInfo = getPropertyInfo(name);
3743 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
3744
3745 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
3746 var standardName = possibleStandardNames[lowerCasedName];
3747
3748 if (standardName !== name) {
3749 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
3750
3751 warnedProperties$1[name] = true;
3752 return true;
3753 }
3754 } else if (!isReserved && name !== lowerCasedName) {
3755 // Unknown attributes should have lowercase casing since that's how they
3756 // will be cased anyway with server rendering.
3757 error('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);
3758
3759 warnedProperties$1[name] = true;
3760 return true;
3761 }
3762
3763 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3764 if (value) {
3765 error('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);
3766 } else {
3767 error('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);
3768 }
3769
3770 warnedProperties$1[name] = true;
3771 return true;
3772 } // Now that we've validated casing, do not validate
3773 // data types for reserved props
3774
3775
3776 if (isReserved) {
3777 return true;
3778 } // Warn when a known attribute is a bad type
3779
3780
3781 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3782 warnedProperties$1[name] = true;
3783 return false;
3784 } // Warn when passing the strings 'false' or 'true' into a boolean prop
3785
3786
3787 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
3788 error('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);
3789
3790 warnedProperties$1[name] = true;
3791 return true;
3792 }
3793
3794 return true;
3795 };
3796}
3797
3798var warnUnknownProperties = function (type, props, eventRegistry) {
3799 {
3800 var unknownProps = [];
3801
3802 for (var key in props) {
3803 var isValid = validateProperty$1(type, key, props[key], eventRegistry);
3804
3805 if (!isValid) {
3806 unknownProps.push(key);
3807 }
3808 }
3809
3810 var unknownPropString = unknownProps.map(function (prop) {
3811 return '`' + prop + '`';
3812 }).join(', ');
3813
3814 if (unknownProps.length === 1) {
3815 error('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://reactjs.org/link/attribute-behavior ', unknownPropString, type);
3816 } else if (unknownProps.length > 1) {
3817 error('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://reactjs.org/link/attribute-behavior ', unknownPropString, type);
3818 }
3819 }
3820};
3821
3822function validateProperties$2(type, props, eventRegistry) {
3823 if (isCustomComponent(type, props)) {
3824 return;
3825 }
3826
3827 warnUnknownProperties(type, props, eventRegistry);
3828}
3829
3830var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1;
3831var IS_NON_DELEGATED = 1 << 1;
3832var IS_CAPTURE_PHASE = 1 << 2;
3833// set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when
3834// we call willDeferLaterForLegacyFBSupport, thus not bailing out
3835// will result in endless cycles like an infinite loop.
3836// We also don't want to defer during event replaying.
3837
3838var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE;
3839
3840// This exists to avoid circular dependency between ReactDOMEventReplaying
3841// and DOMPluginEventSystem.
3842var currentReplayingEvent = null;
3843function setReplayingEvent(event) {
3844 {
3845 if (currentReplayingEvent !== null) {
3846 error('Expected currently replaying event to be null. This error ' + 'is likely caused by a bug in React. Please file an issue.');
3847 }
3848 }
3849
3850 currentReplayingEvent = event;
3851}
3852function resetReplayingEvent() {
3853 {
3854 if (currentReplayingEvent === null) {
3855 error('Expected currently replaying event to not be null. This error ' + 'is likely caused by a bug in React. Please file an issue.');
3856 }
3857 }
3858
3859 currentReplayingEvent = null;
3860}
3861function isReplayingEvent(event) {
3862 return event === currentReplayingEvent;
3863}
3864
3865/**
3866 * Gets the target node from a native browser event by accounting for
3867 * inconsistencies in browser DOM APIs.
3868 *
3869 * @param {object} nativeEvent Native browser event.
3870 * @return {DOMEventTarget} Target node.
3871 */
3872
3873function getEventTarget(nativeEvent) {
3874 // Fallback to nativeEvent.srcElement for IE9
3875 // https://github.com/facebook/react/issues/12506
3876 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
3877
3878 if (target.correspondingUseElement) {
3879 target = target.correspondingUseElement;
3880 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
3881 // @see http://www.quirksmode.org/js/events_properties.html
3882
3883
3884 return target.nodeType === TEXT_NODE ? target.parentNode : target;
3885}
3886
3887var restoreImpl = null;
3888var restoreTarget = null;
3889var restoreQueue = null;
3890
3891function restoreStateOfTarget(target) {
3892 // We perform this translation at the end of the event loop so that we
3893 // always receive the correct fiber here
3894 var internalInstance = getInstanceFromNode(target);
3895
3896 if (!internalInstance) {
3897 // Unmounted
3898 return;
3899 }
3900
3901 if (typeof restoreImpl !== 'function') {
3902 throw new 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.');
3903 }
3904
3905 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
3906
3907 if (stateNode) {
3908 var _props = getFiberCurrentPropsFromNode(stateNode);
3909
3910 restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
3911 }
3912}
3913
3914function setRestoreImplementation(impl) {
3915 restoreImpl = impl;
3916}
3917function enqueueStateRestore(target) {
3918 if (restoreTarget) {
3919 if (restoreQueue) {
3920 restoreQueue.push(target);
3921 } else {
3922 restoreQueue = [target];
3923 }
3924 } else {
3925 restoreTarget = target;
3926 }
3927}
3928function needsStateRestore() {
3929 return restoreTarget !== null || restoreQueue !== null;
3930}
3931function restoreStateIfNeeded() {
3932 if (!restoreTarget) {
3933 return;
3934 }
3935
3936 var target = restoreTarget;
3937 var queuedTargets = restoreQueue;
3938 restoreTarget = null;
3939 restoreQueue = null;
3940 restoreStateOfTarget(target);
3941
3942 if (queuedTargets) {
3943 for (var i = 0; i < queuedTargets.length; i++) {
3944 restoreStateOfTarget(queuedTargets[i]);
3945 }
3946 }
3947}
3948
3949// the renderer. Such as when we're dispatching events or if third party
3950// libraries need to call batchedUpdates. Eventually, this API will go away when
3951// everything is batched by default. We'll then have a similar API to opt-out of
3952// scheduled work and instead do synchronous work.
3953// Defaults
3954
3955var batchedUpdatesImpl = function (fn, bookkeeping) {
3956 return fn(bookkeeping);
3957};
3958
3959var flushSyncImpl = function () {};
3960
3961var isInsideEventHandler = false;
3962
3963function finishEventHandler() {
3964 // Here we wait until all updates have propagated, which is important
3965 // when using controlled components within layers:
3966 // https://github.com/facebook/react/issues/1698
3967 // Then we restore state of any controlled component.
3968 var controlledComponentsHavePendingUpdates = needsStateRestore();
3969
3970 if (controlledComponentsHavePendingUpdates) {
3971 // If a controlled event was fired, we may need to restore the state of
3972 // the DOM node back to the controlled value. This is necessary when React
3973 // bails out of the update without touching the DOM.
3974 // TODO: Restore state in the microtask, after the discrete updates flush,
3975 // instead of early flushing them here.
3976 flushSyncImpl();
3977 restoreStateIfNeeded();
3978 }
3979}
3980
3981function batchedUpdates(fn, a, b) {
3982 if (isInsideEventHandler) {
3983 // If we are currently inside another batch, we need to wait until it
3984 // fully completes before restoring state.
3985 return fn(a, b);
3986 }
3987
3988 isInsideEventHandler = true;
3989
3990 try {
3991 return batchedUpdatesImpl(fn, a, b);
3992 } finally {
3993 isInsideEventHandler = false;
3994 finishEventHandler();
3995 }
3996} // TODO: Replace with flushSync
3997function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushSyncImpl) {
3998 batchedUpdatesImpl = _batchedUpdatesImpl;
3999 flushSyncImpl = _flushSyncImpl;
4000}
4001
4002function isInteractive(tag) {
4003 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
4004}
4005
4006function shouldPreventMouseEvent(name, type, props) {
4007 switch (name) {
4008 case 'onClick':
4009 case 'onClickCapture':
4010 case 'onDoubleClick':
4011 case 'onDoubleClickCapture':
4012 case 'onMouseDown':
4013 case 'onMouseDownCapture':
4014 case 'onMouseMove':
4015 case 'onMouseMoveCapture':
4016 case 'onMouseUp':
4017 case 'onMouseUpCapture':
4018 case 'onMouseEnter':
4019 return !!(props.disabled && isInteractive(type));
4020
4021 default:
4022 return false;
4023 }
4024}
4025/**
4026 * @param {object} inst The instance, which is the source of events.
4027 * @param {string} registrationName Name of listener (e.g. `onClick`).
4028 * @return {?function} The stored callback.
4029 */
4030
4031
4032function getListener(inst, registrationName) {
4033 var stateNode = inst.stateNode;
4034
4035 if (stateNode === null) {
4036 // Work in progress (ex: onload events in incremental mode).
4037 return null;
4038 }
4039
4040 var props = getFiberCurrentPropsFromNode(stateNode);
4041
4042 if (props === null) {
4043 // Work in progress.
4044 return null;
4045 }
4046
4047 var listener = props[registrationName];
4048
4049 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
4050 return null;
4051 }
4052
4053 if (listener && typeof listener !== 'function') {
4054 throw new Error("Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type.");
4055 }
4056
4057 return listener;
4058}
4059
4060var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners
4061// https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
4062
4063if (canUseDOM) {
4064 try {
4065 var options = {}; // $FlowFixMe: Ignore Flow complaining about needing a value
4066
4067 Object.defineProperty(options, 'passive', {
4068 get: function () {
4069 passiveBrowserEventsSupported = true;
4070 }
4071 });
4072 window.addEventListener('test', options, options);
4073 window.removeEventListener('test', options, options);
4074 } catch (e) {
4075 passiveBrowserEventsSupported = false;
4076 }
4077}
4078
4079function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) {
4080 var funcArgs = Array.prototype.slice.call(arguments, 3);
4081
4082 try {
4083 func.apply(context, funcArgs);
4084 } catch (error) {
4085 this.onError(error);
4086 }
4087}
4088
4089var invokeGuardedCallbackImpl = invokeGuardedCallbackProd;
4090
4091{
4092 // In DEV mode, we swap out invokeGuardedCallback for a special version
4093 // that plays more nicely with the browser's DevTools. The idea is to preserve
4094 // "Pause on exceptions" behavior. Because React wraps all user-provided
4095 // functions in invokeGuardedCallback, and the production version of
4096 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
4097 // like caught exceptions, and the DevTools won't pause unless the developer
4098 // takes the extra step of enabling pause on caught exceptions. This is
4099 // unintuitive, though, because even though React has caught the error, from
4100 // the developer's perspective, the error is uncaught.
4101 //
4102 // To preserve the expected "Pause on exceptions" behavior, we don't use a
4103 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
4104 // DOM node, and call the user-provided callback from inside an event handler
4105 // for that fake event. If the callback throws, the error is "captured" using
4106 // a global event handler. But because the error happens in a different
4107 // event loop context, it does not interrupt the normal program flow.
4108 // Effectively, this gives us try-catch behavior without actually using
4109 // try-catch. Neat!
4110 // Check that the browser supports the APIs we need to implement our special
4111 // DEV version of invokeGuardedCallback
4112 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
4113 var fakeNode = document.createElement('react');
4114
4115 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) {
4116 // If document doesn't exist we know for sure we will crash in this method
4117 // when we call document.createEvent(). However this can cause confusing
4118 // errors: https://github.com/facebook/create-react-app/issues/3482
4119 // So we preemptively throw with a better message instead.
4120 if (typeof document === 'undefined' || document === null) {
4121 throw new 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.');
4122 }
4123
4124 var evt = document.createEvent('Event');
4125 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We
4126 // set this to true at the beginning, then set it to false right after
4127 // calling the function. If the function errors, `didError` will never be
4128 // set to false. This strategy works even if the browser is flaky and
4129 // fails to call our global error handler, because it doesn't rely on
4130 // the error event at all.
4131
4132 var didError = true; // Keeps track of the value of window.event so that we can reset it
4133 // during the callback to let user code access window.event in the
4134 // browsers that support it.
4135
4136 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
4137 // dispatching: https://github.com/facebook/react/issues/13688
4138
4139 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
4140
4141 function restoreAfterDispatch() {
4142 // We immediately remove the callback from event listeners so that
4143 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
4144 // nested call would trigger the fake event handlers of any call higher
4145 // in the stack.
4146 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
4147 // window.event assignment in both IE <= 10 as they throw an error
4148 // "Member not found" in strict mode, and in Firefox which does not
4149 // support window.event.
4150
4151 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
4152 window.event = windowEvent;
4153 }
4154 } // Create an event handler for our fake event. We will synchronously
4155 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
4156 // call the user-provided callback.
4157
4158
4159 var funcArgs = Array.prototype.slice.call(arguments, 3);
4160
4161 function callCallback() {
4162 didCall = true;
4163 restoreAfterDispatch();
4164 func.apply(context, funcArgs);
4165 didError = false;
4166 } // Create a global error event handler. We use this to capture the value
4167 // that was thrown. It's possible that this error handler will fire more
4168 // than once; for example, if non-React code also calls `dispatchEvent`
4169 // and a handler for that event throws. We should be resilient to most of
4170 // those cases. Even if our error event handler fires more than once, the
4171 // last error event is always used. If the callback actually does error,
4172 // we know that the last error event is the correct one, because it's not
4173 // possible for anything else to have happened in between our callback
4174 // erroring and the code that follows the `dispatchEvent` call below. If
4175 // the callback doesn't error, but the error event was fired, we know to
4176 // ignore it because `didError` will be false, as described above.
4177
4178
4179 var error; // Use this to track whether the error event is ever called.
4180
4181 var didSetError = false;
4182 var isCrossOriginError = false;
4183
4184 function handleWindowError(event) {
4185 error = event.error;
4186 didSetError = true;
4187
4188 if (error === null && event.colno === 0 && event.lineno === 0) {
4189 isCrossOriginError = true;
4190 }
4191
4192 if (event.defaultPrevented) {
4193 // Some other error handler has prevented default.
4194 // Browsers silence the error report if this happens.
4195 // We'll remember this to later decide whether to log it or not.
4196 if (error != null && typeof error === 'object') {
4197 try {
4198 error._suppressLogging = true;
4199 } catch (inner) {// Ignore.
4200 }
4201 }
4202 }
4203 } // Create a fake event type.
4204
4205
4206 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
4207
4208 window.addEventListener('error', handleWindowError);
4209 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
4210 // errors, it will trigger our global error handler.
4211
4212 evt.initEvent(evtType, false, false);
4213 fakeNode.dispatchEvent(evt);
4214
4215 if (windowEventDescriptor) {
4216 Object.defineProperty(window, 'event', windowEventDescriptor);
4217 }
4218
4219 if (didCall && didError) {
4220 if (!didSetError) {
4221 // The callback errored, but the error event never fired.
4222 // eslint-disable-next-line react-internal/prod-error-codes
4223 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.');
4224 } else if (isCrossOriginError) {
4225 // eslint-disable-next-line react-internal/prod-error-codes
4226 error = new Error("A cross-origin error was thrown. React doesn't have access to " + 'the actual error object in development. ' + 'See https://reactjs.org/link/crossorigin-error for more information.');
4227 }
4228
4229 this.onError(error);
4230 } // Remove our event listeners
4231
4232
4233 window.removeEventListener('error', handleWindowError);
4234
4235 if (!didCall) {
4236 // Something went really wrong, and our event was not dispatched.
4237 // https://github.com/facebook/react/issues/16734
4238 // https://github.com/facebook/react/issues/16585
4239 // Fall back to the production implementation.
4240 restoreAfterDispatch();
4241 return invokeGuardedCallbackProd.apply(this, arguments);
4242 }
4243 };
4244 }
4245}
4246
4247var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
4248
4249var hasError = false;
4250var caughtError = null; // Used by event system to capture/rethrow the first error.
4251
4252var hasRethrowError = false;
4253var rethrowError = null;
4254var reporter = {
4255 onError: function (error) {
4256 hasError = true;
4257 caughtError = error;
4258 }
4259};
4260/**
4261 * Call a function while guarding against errors that happens within it.
4262 * Returns an error if it throws, otherwise null.
4263 *
4264 * In production, this is implemented using a try-catch. The reason we don't
4265 * use a try-catch directly is so that we can swap out a different
4266 * implementation in DEV mode.
4267 *
4268 * @param {String} name of the guard to use for logging or debugging
4269 * @param {Function} func The function to invoke
4270 * @param {*} context The context to use when calling the function
4271 * @param {...*} args Arguments for function
4272 */
4273
4274function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
4275 hasError = false;
4276 caughtError = null;
4277 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
4278}
4279/**
4280 * Same as invokeGuardedCallback, but instead of returning an error, it stores
4281 * it in a global so it can be rethrown by `rethrowCaughtError` later.
4282 * TODO: See if caughtError and rethrowError can be unified.
4283 *
4284 * @param {String} name of the guard to use for logging or debugging
4285 * @param {Function} func The function to invoke
4286 * @param {*} context The context to use when calling the function
4287 * @param {...*} args Arguments for function
4288 */
4289
4290function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
4291 invokeGuardedCallback.apply(this, arguments);
4292
4293 if (hasError) {
4294 var error = clearCaughtError();
4295
4296 if (!hasRethrowError) {
4297 hasRethrowError = true;
4298 rethrowError = error;
4299 }
4300 }
4301}
4302/**
4303 * During execution of guarded functions we will capture the first error which
4304 * we will rethrow to be handled by the top level error handler.
4305 */
4306
4307function rethrowCaughtError() {
4308 if (hasRethrowError) {
4309 var error = rethrowError;
4310 hasRethrowError = false;
4311 rethrowError = null;
4312 throw error;
4313 }
4314}
4315function hasCaughtError() {
4316 return hasError;
4317}
4318function clearCaughtError() {
4319 if (hasError) {
4320 var error = caughtError;
4321 hasError = false;
4322 caughtError = null;
4323 return error;
4324 } else {
4325 throw new Error('clearCaughtError was called but no error was captured. This error ' + 'is likely caused by a bug in React. Please file an issue.');
4326 }
4327}
4328
4329/**
4330 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4331 * instance (key) and the internal representation (value). This allows public
4332 * methods to accept the user facing instance as an argument and map them back
4333 * to internal methods.
4334 *
4335 * Note that this module is currently shared and assumed to be stateless.
4336 * If this becomes an actual Map, that will break.
4337 */
4338function get(key) {
4339 return key._reactInternals;
4340}
4341function has(key) {
4342 return key._reactInternals !== undefined;
4343}
4344function set(key, value) {
4345 key._reactInternals = value;
4346}
4347
4348// Don't change these two values. They're used by React Dev Tools.
4349var NoFlags =
4350/* */
43510;
4352var PerformedWork =
4353/* */
43541; // You can change the rest (and add more).
4355
4356var Placement =
4357/* */
43582;
4359var Update =
4360/* */
43614;
4362var ChildDeletion =
4363/* */
436416;
4365var ContentReset =
4366/* */
436732;
4368var Callback =
4369/* */
437064;
4371var DidCapture =
4372/* */
4373128;
4374var ForceClientRender =
4375/* */
4376256;
4377var Ref =
4378/* */
4379512;
4380var Snapshot =
4381/* */
43821024;
4383var Passive =
4384/* */
43852048;
4386var Hydrating =
4387/* */
43884096;
4389var Visibility =
4390/* */
43918192;
4392var StoreConsistency =
4393/* */
439416384;
4395var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit)
4396
4397var HostEffectMask =
4398/* */
439932767; // These are not really side effects, but we still reuse this field.
4400
4401var Incomplete =
4402/* */
440332768;
4404var ShouldCapture =
4405/* */
440665536;
4407var ForceUpdateForLegacySuspense =
4408/* */
4409131072;
4410var Forked =
4411/* */
44121048576; // Static tags describe aspects of a fiber that are not specific to a render,
4413// e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
4414// This enables us to defer more work in the unmount case,
4415// since we can defer traversing the tree during layout to look for Passive effects,
4416// and instead rely on the static flag as a signal that there may be cleanup work.
4417
4418var RefStatic =
4419/* */
44202097152;
4421var LayoutStatic =
4422/* */
44234194304;
4424var PassiveStatic =
4425/* */
44268388608; // These flags allow us to traverse to fibers that have effects on mount
4427// without traversing the entire tree after every commit for
4428// double invoking
4429
4430var MountLayoutDev =
4431/* */
443216777216;
4433var MountPassiveDev =
4434/* */
443533554432; // Groups of flags that are used in the commit phase to skip over trees that
4436// don't contain effects, by checking subtreeFlags.
4437
4438var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
4439// flag logic (see #20043)
4440Update | Snapshot | ( 0);
4441var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility;
4442var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask
4443
4444var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones.
4445// This allows certain concepts to persist without recalculating them,
4446// e.g. whether a subtree contains passive effects or portals.
4447
4448var StaticMask = LayoutStatic | PassiveStatic | RefStatic;
4449
4450var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
4451function getNearestMountedFiber(fiber) {
4452 var node = fiber;
4453 var nearestMounted = fiber;
4454
4455 if (!fiber.alternate) {
4456 // If there is no alternate, this might be a new tree that isn't inserted
4457 // yet. If it is, then it will have a pending insertion effect on it.
4458 var nextNode = node;
4459
4460 do {
4461 node = nextNode;
4462
4463 if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
4464 // This is an insertion or in-progress hydration. The nearest possible
4465 // mounted fiber is the parent but we need to continue to figure out
4466 // if that one is still mounted.
4467 nearestMounted = node.return;
4468 }
4469
4470 nextNode = node.return;
4471 } while (nextNode);
4472 } else {
4473 while (node.return) {
4474 node = node.return;
4475 }
4476 }
4477
4478 if (node.tag === HostRoot) {
4479 // TODO: Check if this was a nested HostRoot when used with
4480 // renderContainerIntoSubtree.
4481 return nearestMounted;
4482 } // If we didn't hit the root, that means that we're in an disconnected tree
4483 // that has been unmounted.
4484
4485
4486 return null;
4487}
4488function getSuspenseInstanceFromFiber(fiber) {
4489 if (fiber.tag === SuspenseComponent) {
4490 var suspenseState = fiber.memoizedState;
4491
4492 if (suspenseState === null) {
4493 var current = fiber.alternate;
4494
4495 if (current !== null) {
4496 suspenseState = current.memoizedState;
4497 }
4498 }
4499
4500 if (suspenseState !== null) {
4501 return suspenseState.dehydrated;
4502 }
4503 }
4504
4505 return null;
4506}
4507function getContainerFromFiber(fiber) {
4508 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
4509}
4510function isFiberMounted(fiber) {
4511 return getNearestMountedFiber(fiber) === fiber;
4512}
4513function isMounted(component) {
4514 {
4515 var owner = ReactCurrentOwner.current;
4516
4517 if (owner !== null && owner.tag === ClassComponent) {
4518 var ownerFiber = owner;
4519 var instance = ownerFiber.stateNode;
4520
4521 if (!instance._warnedAboutRefsInRender) {
4522 error('%s is accessing isMounted inside its render() function. ' + 'render() should be a pure function of props and state. It should ' + 'never access something that requires stale data from the previous ' + 'render, such as refs. Move this logic to componentDidMount and ' + 'componentDidUpdate instead.', getComponentNameFromFiber(ownerFiber) || 'A component');
4523 }
4524
4525 instance._warnedAboutRefsInRender = true;
4526 }
4527 }
4528
4529 var fiber = get(component);
4530
4531 if (!fiber) {
4532 return false;
4533 }
4534
4535 return getNearestMountedFiber(fiber) === fiber;
4536}
4537
4538function assertIsMounted(fiber) {
4539 if (getNearestMountedFiber(fiber) !== fiber) {
4540 throw new Error('Unable to find node on an unmounted component.');
4541 }
4542}
4543
4544function findCurrentFiberUsingSlowPath(fiber) {
4545 var alternate = fiber.alternate;
4546
4547 if (!alternate) {
4548 // If there is no alternate, then we only need to check if it is mounted.
4549 var nearestMounted = getNearestMountedFiber(fiber);
4550
4551 if (nearestMounted === null) {
4552 throw new Error('Unable to find node on an unmounted component.');
4553 }
4554
4555 if (nearestMounted !== fiber) {
4556 return null;
4557 }
4558
4559 return fiber;
4560 } // If we have two possible branches, we'll walk backwards up to the root
4561 // to see what path the root points to. On the way we may hit one of the
4562 // special cases and we'll deal with them.
4563
4564
4565 var a = fiber;
4566 var b = alternate;
4567
4568 while (true) {
4569 var parentA = a.return;
4570
4571 if (parentA === null) {
4572 // We're at the root.
4573 break;
4574 }
4575
4576 var parentB = parentA.alternate;
4577
4578 if (parentB === null) {
4579 // There is no alternate. This is an unusual case. Currently, it only
4580 // happens when a Suspense component is hidden. An extra fragment fiber
4581 // is inserted in between the Suspense fiber and its children. Skip
4582 // over this extra fragment fiber and proceed to the next parent.
4583 var nextParent = parentA.return;
4584
4585 if (nextParent !== null) {
4586 a = b = nextParent;
4587 continue;
4588 } // If there's no parent, we're at the root.
4589
4590
4591 break;
4592 } // If both copies of the parent fiber point to the same child, we can
4593 // assume that the child is current. This happens when we bailout on low
4594 // priority: the bailed out fiber's child reuses the current child.
4595
4596
4597 if (parentA.child === parentB.child) {
4598 var child = parentA.child;
4599
4600 while (child) {
4601 if (child === a) {
4602 // We've determined that A is the current branch.
4603 assertIsMounted(parentA);
4604 return fiber;
4605 }
4606
4607 if (child === b) {
4608 // We've determined that B is the current branch.
4609 assertIsMounted(parentA);
4610 return alternate;
4611 }
4612
4613 child = child.sibling;
4614 } // We should never have an alternate for any mounting node. So the only
4615 // way this could possibly happen is if this was unmounted, if at all.
4616
4617
4618 throw new Error('Unable to find node on an unmounted component.');
4619 }
4620
4621 if (a.return !== b.return) {
4622 // The return pointer of A and the return pointer of B point to different
4623 // fibers. We assume that return pointers never criss-cross, so A must
4624 // belong to the child set of A.return, and B must belong to the child
4625 // set of B.return.
4626 a = parentA;
4627 b = parentB;
4628 } else {
4629 // The return pointers point to the same fiber. We'll have to use the
4630 // default, slow path: scan the child sets of each parent alternate to see
4631 // which child belongs to which set.
4632 //
4633 // Search parent A's child set
4634 var didFindChild = false;
4635 var _child = parentA.child;
4636
4637 while (_child) {
4638 if (_child === a) {
4639 didFindChild = true;
4640 a = parentA;
4641 b = parentB;
4642 break;
4643 }
4644
4645 if (_child === b) {
4646 didFindChild = true;
4647 b = parentA;
4648 a = parentB;
4649 break;
4650 }
4651
4652 _child = _child.sibling;
4653 }
4654
4655 if (!didFindChild) {
4656 // Search parent B's child set
4657 _child = parentB.child;
4658
4659 while (_child) {
4660 if (_child === a) {
4661 didFindChild = true;
4662 a = parentB;
4663 b = parentA;
4664 break;
4665 }
4666
4667 if (_child === b) {
4668 didFindChild = true;
4669 b = parentB;
4670 a = parentA;
4671 break;
4672 }
4673
4674 _child = _child.sibling;
4675 }
4676
4677 if (!didFindChild) {
4678 throw new Error('Child was not found in either parent set. This indicates a bug ' + 'in React related to the return pointer. Please file an issue.');
4679 }
4680 }
4681 }
4682
4683 if (a.alternate !== b) {
4684 throw new Error("Return fibers should always be each others' alternates. " + 'This error is likely caused by a bug in React. Please file an issue.');
4685 }
4686 } // If the root is not a host container, we're in a disconnected tree. I.e.
4687 // unmounted.
4688
4689
4690 if (a.tag !== HostRoot) {
4691 throw new Error('Unable to find node on an unmounted component.');
4692 }
4693
4694 if (a.stateNode.current === a) {
4695 // We've determined that A is the current branch.
4696 return fiber;
4697 } // Otherwise B has to be current branch.
4698
4699
4700 return alternate;
4701}
4702function findCurrentHostFiber(parent) {
4703 var currentParent = findCurrentFiberUsingSlowPath(parent);
4704 return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null;
4705}
4706
4707function findCurrentHostFiberImpl(node) {
4708 // Next we'll drill down this component to find the first HostComponent/Text.
4709 if (node.tag === HostComponent || node.tag === HostText) {
4710 return node;
4711 }
4712
4713 var child = node.child;
4714
4715 while (child !== null) {
4716 var match = findCurrentHostFiberImpl(child);
4717
4718 if (match !== null) {
4719 return match;
4720 }
4721
4722 child = child.sibling;
4723 }
4724
4725 return null;
4726}
4727
4728function findCurrentHostFiberWithNoPortals(parent) {
4729 var currentParent = findCurrentFiberUsingSlowPath(parent);
4730 return currentParent !== null ? findCurrentHostFiberWithNoPortalsImpl(currentParent) : null;
4731}
4732
4733function findCurrentHostFiberWithNoPortalsImpl(node) {
4734 // Next we'll drill down this component to find the first HostComponent/Text.
4735 if (node.tag === HostComponent || node.tag === HostText) {
4736 return node;
4737 }
4738
4739 var child = node.child;
4740
4741 while (child !== null) {
4742 if (child.tag !== HostPortal) {
4743 var match = findCurrentHostFiberWithNoPortalsImpl(child);
4744
4745 if (match !== null) {
4746 return match;
4747 }
4748 }
4749
4750 child = child.sibling;
4751 }
4752
4753 return null;
4754}
4755
4756// This module only exists as an ESM wrapper around the external CommonJS
4757var scheduleCallback = Scheduler.unstable_scheduleCallback;
4758var cancelCallback = Scheduler.unstable_cancelCallback;
4759var shouldYield = Scheduler.unstable_shouldYield;
4760var requestPaint = Scheduler.unstable_requestPaint;
4761var now = Scheduler.unstable_now;
4762var getCurrentPriorityLevel = Scheduler.unstable_getCurrentPriorityLevel;
4763var ImmediatePriority = Scheduler.unstable_ImmediatePriority;
4764var UserBlockingPriority = Scheduler.unstable_UserBlockingPriority;
4765var NormalPriority = Scheduler.unstable_NormalPriority;
4766var LowPriority = Scheduler.unstable_LowPriority;
4767var IdlePriority = Scheduler.unstable_IdlePriority;
4768// this doesn't actually exist on the scheduler, but it *does*
4769// on scheduler/unstable_mock, which we'll need for internal testing
4770var unstable_yieldValue = Scheduler.unstable_yieldValue;
4771var unstable_setDisableYieldValue = Scheduler.unstable_setDisableYieldValue;
4772
4773var rendererID = null;
4774var injectedHook = null;
4775var injectedProfilingHooks = null;
4776var hasLoggedError = false;
4777var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
4778function injectInternals(internals) {
4779 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
4780 // No DevTools
4781 return false;
4782 }
4783
4784 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
4785
4786 if (hook.isDisabled) {
4787 // This isn't a real property on the hook, but it can be set to opt out
4788 // of DevTools integration and associated warnings and logs.
4789 // https://github.com/facebook/react/issues/3877
4790 return true;
4791 }
4792
4793 if (!hook.supportsFiber) {
4794 {
4795 error('The installed version of React DevTools is too old and will not work ' + 'with the current version of React. Please update React DevTools. ' + 'https://reactjs.org/link/react-devtools');
4796 } // DevTools exists, even though it doesn't support Fiber.
4797
4798
4799 return true;
4800 }
4801
4802 try {
4803 if (enableSchedulingProfiler) {
4804 // Conditionally inject these hooks only if Timeline profiler is supported by this build.
4805 // This gives DevTools a way to feature detect that isn't tied to version number
4806 // (since profiling and timeline are controlled by different feature flags).
4807 internals = assign({}, internals, {
4808 getLaneLabelMap: getLaneLabelMap,
4809 injectProfilingHooks: injectProfilingHooks
4810 });
4811 }
4812
4813 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
4814
4815 injectedHook = hook;
4816 } catch (err) {
4817 // Catch all errors because it is unsafe to throw during initialization.
4818 {
4819 error('React instrumentation encountered an error: %s.', err);
4820 }
4821 }
4822
4823 if (hook.checkDCE) {
4824 // This is the real DevTools.
4825 return true;
4826 } else {
4827 // This is likely a hook installed by Fast Refresh runtime.
4828 return false;
4829 }
4830}
4831function onScheduleRoot(root, children) {
4832 {
4833 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
4834 try {
4835 injectedHook.onScheduleFiberRoot(rendererID, root, children);
4836 } catch (err) {
4837 if ( !hasLoggedError) {
4838 hasLoggedError = true;
4839
4840 error('React instrumentation encountered an error: %s', err);
4841 }
4842 }
4843 }
4844 }
4845}
4846function onCommitRoot(root, eventPriority) {
4847 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
4848 try {
4849 var didError = (root.current.flags & DidCapture) === DidCapture;
4850
4851 if (enableProfilerTimer) {
4852 var schedulerPriority;
4853
4854 switch (eventPriority) {
4855 case DiscreteEventPriority:
4856 schedulerPriority = ImmediatePriority;
4857 break;
4858
4859 case ContinuousEventPriority:
4860 schedulerPriority = UserBlockingPriority;
4861 break;
4862
4863 case DefaultEventPriority:
4864 schedulerPriority = NormalPriority;
4865 break;
4866
4867 case IdleEventPriority:
4868 schedulerPriority = IdlePriority;
4869 break;
4870
4871 default:
4872 schedulerPriority = NormalPriority;
4873 break;
4874 }
4875
4876 injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError);
4877 } else {
4878 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError);
4879 }
4880 } catch (err) {
4881 {
4882 if (!hasLoggedError) {
4883 hasLoggedError = true;
4884
4885 error('React instrumentation encountered an error: %s', err);
4886 }
4887 }
4888 }
4889 }
4890}
4891function onPostCommitRoot(root) {
4892 if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') {
4893 try {
4894 injectedHook.onPostCommitFiberRoot(rendererID, root);
4895 } catch (err) {
4896 {
4897 if (!hasLoggedError) {
4898 hasLoggedError = true;
4899
4900 error('React instrumentation encountered an error: %s', err);
4901 }
4902 }
4903 }
4904 }
4905}
4906function onCommitUnmount(fiber) {
4907 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
4908 try {
4909 injectedHook.onCommitFiberUnmount(rendererID, fiber);
4910 } catch (err) {
4911 {
4912 if (!hasLoggedError) {
4913 hasLoggedError = true;
4914
4915 error('React instrumentation encountered an error: %s', err);
4916 }
4917 }
4918 }
4919 }
4920}
4921function setIsStrictModeForDevtools(newIsStrictMode) {
4922 {
4923 if (typeof unstable_yieldValue === 'function') {
4924 // We're in a test because Scheduler.unstable_yieldValue only exists
4925 // in SchedulerMock. To reduce the noise in strict mode tests,
4926 // suppress warnings and disable scheduler yielding during the double render
4927 unstable_setDisableYieldValue(newIsStrictMode);
4928 setSuppressWarning(newIsStrictMode);
4929 }
4930
4931 if (injectedHook && typeof injectedHook.setStrictMode === 'function') {
4932 try {
4933 injectedHook.setStrictMode(rendererID, newIsStrictMode);
4934 } catch (err) {
4935 {
4936 if (!hasLoggedError) {
4937 hasLoggedError = true;
4938
4939 error('React instrumentation encountered an error: %s', err);
4940 }
4941 }
4942 }
4943 }
4944 }
4945} // Profiler API hooks
4946
4947function injectProfilingHooks(profilingHooks) {
4948 injectedProfilingHooks = profilingHooks;
4949}
4950
4951function getLaneLabelMap() {
4952 {
4953 var map = new Map();
4954 var lane = 1;
4955
4956 for (var index = 0; index < TotalLanes; index++) {
4957 var label = getLabelForLane(lane);
4958 map.set(lane, label);
4959 lane *= 2;
4960 }
4961
4962 return map;
4963 }
4964}
4965
4966function markCommitStarted(lanes) {
4967 {
4968 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStarted === 'function') {
4969 injectedProfilingHooks.markCommitStarted(lanes);
4970 }
4971 }
4972}
4973function markCommitStopped() {
4974 {
4975 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStopped === 'function') {
4976 injectedProfilingHooks.markCommitStopped();
4977 }
4978 }
4979}
4980function markComponentRenderStarted(fiber) {
4981 {
4982 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStarted === 'function') {
4983 injectedProfilingHooks.markComponentRenderStarted(fiber);
4984 }
4985 }
4986}
4987function markComponentRenderStopped() {
4988 {
4989 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStopped === 'function') {
4990 injectedProfilingHooks.markComponentRenderStopped();
4991 }
4992 }
4993}
4994function markComponentPassiveEffectMountStarted(fiber) {
4995 {
4996 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted === 'function') {
4997 injectedProfilingHooks.markComponentPassiveEffectMountStarted(fiber);
4998 }
4999 }
5000}
5001function markComponentPassiveEffectMountStopped() {
5002 {
5003 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped === 'function') {
5004 injectedProfilingHooks.markComponentPassiveEffectMountStopped();
5005 }
5006 }
5007}
5008function markComponentPassiveEffectUnmountStarted(fiber) {
5009 {
5010 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted === 'function') {
5011 injectedProfilingHooks.markComponentPassiveEffectUnmountStarted(fiber);
5012 }
5013 }
5014}
5015function markComponentPassiveEffectUnmountStopped() {
5016 {
5017 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped === 'function') {
5018 injectedProfilingHooks.markComponentPassiveEffectUnmountStopped();
5019 }
5020 }
5021}
5022function markComponentLayoutEffectMountStarted(fiber) {
5023 {
5024 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted === 'function') {
5025 injectedProfilingHooks.markComponentLayoutEffectMountStarted(fiber);
5026 }
5027 }
5028}
5029function markComponentLayoutEffectMountStopped() {
5030 {
5031 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped === 'function') {
5032 injectedProfilingHooks.markComponentLayoutEffectMountStopped();
5033 }
5034 }
5035}
5036function markComponentLayoutEffectUnmountStarted(fiber) {
5037 {
5038 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted === 'function') {
5039 injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber);
5040 }
5041 }
5042}
5043function markComponentLayoutEffectUnmountStopped() {
5044 {
5045 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped === 'function') {
5046 injectedProfilingHooks.markComponentLayoutEffectUnmountStopped();
5047 }
5048 }
5049}
5050function markComponentErrored(fiber, thrownValue, lanes) {
5051 {
5052 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentErrored === 'function') {
5053 injectedProfilingHooks.markComponentErrored(fiber, thrownValue, lanes);
5054 }
5055 }
5056}
5057function markComponentSuspended(fiber, wakeable, lanes) {
5058 {
5059 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentSuspended === 'function') {
5060 injectedProfilingHooks.markComponentSuspended(fiber, wakeable, lanes);
5061 }
5062 }
5063}
5064function markLayoutEffectsStarted(lanes) {
5065 {
5066 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStarted === 'function') {
5067 injectedProfilingHooks.markLayoutEffectsStarted(lanes);
5068 }
5069 }
5070}
5071function markLayoutEffectsStopped() {
5072 {
5073 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStopped === 'function') {
5074 injectedProfilingHooks.markLayoutEffectsStopped();
5075 }
5076 }
5077}
5078function markPassiveEffectsStarted(lanes) {
5079 {
5080 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStarted === 'function') {
5081 injectedProfilingHooks.markPassiveEffectsStarted(lanes);
5082 }
5083 }
5084}
5085function markPassiveEffectsStopped() {
5086 {
5087 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStopped === 'function') {
5088 injectedProfilingHooks.markPassiveEffectsStopped();
5089 }
5090 }
5091}
5092function markRenderStarted(lanes) {
5093 {
5094 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStarted === 'function') {
5095 injectedProfilingHooks.markRenderStarted(lanes);
5096 }
5097 }
5098}
5099function markRenderYielded() {
5100 {
5101 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderYielded === 'function') {
5102 injectedProfilingHooks.markRenderYielded();
5103 }
5104 }
5105}
5106function markRenderStopped() {
5107 {
5108 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStopped === 'function') {
5109 injectedProfilingHooks.markRenderStopped();
5110 }
5111 }
5112}
5113function markRenderScheduled(lane) {
5114 {
5115 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderScheduled === 'function') {
5116 injectedProfilingHooks.markRenderScheduled(lane);
5117 }
5118 }
5119}
5120function markForceUpdateScheduled(fiber, lane) {
5121 {
5122 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markForceUpdateScheduled === 'function') {
5123 injectedProfilingHooks.markForceUpdateScheduled(fiber, lane);
5124 }
5125 }
5126}
5127function markStateUpdateScheduled(fiber, lane) {
5128 {
5129 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markStateUpdateScheduled === 'function') {
5130 injectedProfilingHooks.markStateUpdateScheduled(fiber, lane);
5131 }
5132 }
5133}
5134
5135var NoMode =
5136/* */
51370; // TODO: Remove ConcurrentMode by reading from the root tag instead
5138
5139var ConcurrentMode =
5140/* */
51411;
5142var ProfileMode =
5143/* */
51442;
5145var StrictLegacyMode =
5146/* */
51478;
5148var StrictEffectsMode =
5149/* */
515016;
5151
5152// TODO: This is pretty well supported by browsers. Maybe we can drop it.
5153var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros.
5154// Based on:
5155// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
5156
5157var log = Math.log;
5158var LN2 = Math.LN2;
5159
5160function clz32Fallback(x) {
5161 var asUint = x >>> 0;
5162
5163 if (asUint === 0) {
5164 return 32;
5165 }
5166
5167 return 31 - (log(asUint) / LN2 | 0) | 0;
5168}
5169
5170// If those values are changed that package should be rebuilt and redeployed.
5171
5172var TotalLanes = 31;
5173var NoLanes =
5174/* */
51750;
5176var NoLane =
5177/* */
51780;
5179var SyncLane =
5180/* */
51811;
5182var InputContinuousHydrationLane =
5183/* */
51842;
5185var InputContinuousLane =
5186/* */
51874;
5188var DefaultHydrationLane =
5189/* */
51908;
5191var DefaultLane =
5192/* */
519316;
5194var TransitionHydrationLane =
5195/* */
519632;
5197var TransitionLanes =
5198/* */
51994194240;
5200var TransitionLane1 =
5201/* */
520264;
5203var TransitionLane2 =
5204/* */
5205128;
5206var TransitionLane3 =
5207/* */
5208256;
5209var TransitionLane4 =
5210/* */
5211512;
5212var TransitionLane5 =
5213/* */
52141024;
5215var TransitionLane6 =
5216/* */
52172048;
5218var TransitionLane7 =
5219/* */
52204096;
5221var TransitionLane8 =
5222/* */
52238192;
5224var TransitionLane9 =
5225/* */
522616384;
5227var TransitionLane10 =
5228/* */
522932768;
5230var TransitionLane11 =
5231/* */
523265536;
5233var TransitionLane12 =
5234/* */
5235131072;
5236var TransitionLane13 =
5237/* */
5238262144;
5239var TransitionLane14 =
5240/* */
5241524288;
5242var TransitionLane15 =
5243/* */
52441048576;
5245var TransitionLane16 =
5246/* */
52472097152;
5248var RetryLanes =
5249/* */
5250130023424;
5251var RetryLane1 =
5252/* */
52534194304;
5254var RetryLane2 =
5255/* */
52568388608;
5257var RetryLane3 =
5258/* */
525916777216;
5260var RetryLane4 =
5261/* */
526233554432;
5263var RetryLane5 =
5264/* */
526567108864;
5266var SomeRetryLane = RetryLane1;
5267var SelectiveHydrationLane =
5268/* */
5269134217728;
5270var NonIdleLanes =
5271/* */
5272268435455;
5273var IdleHydrationLane =
5274/* */
5275268435456;
5276var IdleLane =
5277/* */
5278536870912;
5279var OffscreenLane =
5280/* */
52811073741824; // This function is used for the experimental timeline (react-devtools-timeline)
5282// It should be kept in sync with the Lanes values above.
5283
5284function getLabelForLane(lane) {
5285 {
5286 if (lane & SyncLane) {
5287 return 'Sync';
5288 }
5289
5290 if (lane & InputContinuousHydrationLane) {
5291 return 'InputContinuousHydration';
5292 }
5293
5294 if (lane & InputContinuousLane) {
5295 return 'InputContinuous';
5296 }
5297
5298 if (lane & DefaultHydrationLane) {
5299 return 'DefaultHydration';
5300 }
5301
5302 if (lane & DefaultLane) {
5303 return 'Default';
5304 }
5305
5306 if (lane & TransitionHydrationLane) {
5307 return 'TransitionHydration';
5308 }
5309
5310 if (lane & TransitionLanes) {
5311 return 'Transition';
5312 }
5313
5314 if (lane & RetryLanes) {
5315 return 'Retry';
5316 }
5317
5318 if (lane & SelectiveHydrationLane) {
5319 return 'SelectiveHydration';
5320 }
5321
5322 if (lane & IdleHydrationLane) {
5323 return 'IdleHydration';
5324 }
5325
5326 if (lane & IdleLane) {
5327 return 'Idle';
5328 }
5329
5330 if (lane & OffscreenLane) {
5331 return 'Offscreen';
5332 }
5333 }
5334}
5335var NoTimestamp = -1;
5336var nextTransitionLane = TransitionLane1;
5337var nextRetryLane = RetryLane1;
5338
5339function getHighestPriorityLanes(lanes) {
5340 switch (getHighestPriorityLane(lanes)) {
5341 case SyncLane:
5342 return SyncLane;
5343
5344 case InputContinuousHydrationLane:
5345 return InputContinuousHydrationLane;
5346
5347 case InputContinuousLane:
5348 return InputContinuousLane;
5349
5350 case DefaultHydrationLane:
5351 return DefaultHydrationLane;
5352
5353 case DefaultLane:
5354 return DefaultLane;
5355
5356 case TransitionHydrationLane:
5357 return TransitionHydrationLane;
5358
5359 case TransitionLane1:
5360 case TransitionLane2:
5361 case TransitionLane3:
5362 case TransitionLane4:
5363 case TransitionLane5:
5364 case TransitionLane6:
5365 case TransitionLane7:
5366 case TransitionLane8:
5367 case TransitionLane9:
5368 case TransitionLane10:
5369 case TransitionLane11:
5370 case TransitionLane12:
5371 case TransitionLane13:
5372 case TransitionLane14:
5373 case TransitionLane15:
5374 case TransitionLane16:
5375 return lanes & TransitionLanes;
5376
5377 case RetryLane1:
5378 case RetryLane2:
5379 case RetryLane3:
5380 case RetryLane4:
5381 case RetryLane5:
5382 return lanes & RetryLanes;
5383
5384 case SelectiveHydrationLane:
5385 return SelectiveHydrationLane;
5386
5387 case IdleHydrationLane:
5388 return IdleHydrationLane;
5389
5390 case IdleLane:
5391 return IdleLane;
5392
5393 case OffscreenLane:
5394 return OffscreenLane;
5395
5396 default:
5397 {
5398 error('Should have found matching lanes. This is a bug in React.');
5399 } // This shouldn't be reachable, but as a fallback, return the entire bitmask.
5400
5401
5402 return lanes;
5403 }
5404}
5405
5406function getNextLanes(root, wipLanes) {
5407 // Early bailout if there's no pending work left.
5408 var pendingLanes = root.pendingLanes;
5409
5410 if (pendingLanes === NoLanes) {
5411 return NoLanes;
5412 }
5413
5414 var nextLanes = NoLanes;
5415 var suspendedLanes = root.suspendedLanes;
5416 var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished,
5417 // even if the work is suspended.
5418
5419 var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
5420
5421 if (nonIdlePendingLanes !== NoLanes) {
5422 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
5423
5424 if (nonIdleUnblockedLanes !== NoLanes) {
5425 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
5426 } else {
5427 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
5428
5429 if (nonIdlePingedLanes !== NoLanes) {
5430 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
5431 }
5432 }
5433 } else {
5434 // The only remaining work is Idle.
5435 var unblockedLanes = pendingLanes & ~suspendedLanes;
5436
5437 if (unblockedLanes !== NoLanes) {
5438 nextLanes = getHighestPriorityLanes(unblockedLanes);
5439 } else {
5440 if (pingedLanes !== NoLanes) {
5441 nextLanes = getHighestPriorityLanes(pingedLanes);
5442 }
5443 }
5444 }
5445
5446 if (nextLanes === NoLanes) {
5447 // This should only be reachable if we're suspended
5448 // TODO: Consider warning in this path if a fallback timer is not scheduled.
5449 return NoLanes;
5450 } // If we're already in the middle of a render, switching lanes will interrupt
5451 // it and we'll lose our progress. We should only do this if the new lanes are
5452 // higher priority.
5453
5454
5455 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
5456 // bother waiting until the root is complete.
5457 (wipLanes & suspendedLanes) === NoLanes) {
5458 var nextLane = getHighestPriorityLane(nextLanes);
5459 var wipLane = getHighestPriorityLane(wipLanes);
5460
5461 if ( // Tests whether the next lane is equal or lower priority than the wip
5462 // one. This works because the bits decrease in priority as you go left.
5463 nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The
5464 // only difference between default updates and transition updates is that
5465 // default updates do not support refresh transitions.
5466 nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) {
5467 // Keep working on the existing in-progress tree. Do not interrupt.
5468 return wipLanes;
5469 }
5470 }
5471
5472 if ((nextLanes & InputContinuousLane) !== NoLanes) {
5473 // When updates are sync by default, we entangle continuous priority updates
5474 // and default updates, so they render in the same batch. The only reason
5475 // they use separate lanes is because continuous updates should interrupt
5476 // transitions, but default updates should not.
5477 nextLanes |= pendingLanes & DefaultLane;
5478 } // Check for entangled lanes and add them to the batch.
5479 //
5480 // A lane is said to be entangled with another when it's not allowed to render
5481 // in a batch that does not also include the other lane. Typically we do this
5482 // when multiple updates have the same source, and we only want to respond to
5483 // the most recent event from that source.
5484 //
5485 // Note that we apply entanglements *after* checking for partial work above.
5486 // This means that if a lane is entangled during an interleaved event while
5487 // it's already rendering, we won't interrupt it. This is intentional, since
5488 // entanglement is usually "best effort": we'll try our best to render the
5489 // lanes in the same batch, but it's not worth throwing out partially
5490 // completed work in order to do it.
5491 // TODO: Reconsider this. The counter-argument is that the partial work
5492 // represents an intermediate state, which we don't want to show to the user.
5493 // And by spending extra time finishing it, we're increasing the amount of
5494 // time it takes to show the final state, which is what they are actually
5495 // waiting for.
5496 //
5497 // For those exceptions where entanglement is semantically important, like
5498 // useMutableSource, we should ensure that there is no partial work at the
5499 // time we apply the entanglement.
5500
5501
5502 var entangledLanes = root.entangledLanes;
5503
5504 if (entangledLanes !== NoLanes) {
5505 var entanglements = root.entanglements;
5506 var lanes = nextLanes & entangledLanes;
5507
5508 while (lanes > 0) {
5509 var index = pickArbitraryLaneIndex(lanes);
5510 var lane = 1 << index;
5511 nextLanes |= entanglements[index];
5512 lanes &= ~lane;
5513 }
5514 }
5515
5516 return nextLanes;
5517}
5518function getMostRecentEventTime(root, lanes) {
5519 var eventTimes = root.eventTimes;
5520 var mostRecentEventTime = NoTimestamp;
5521
5522 while (lanes > 0) {
5523 var index = pickArbitraryLaneIndex(lanes);
5524 var lane = 1 << index;
5525 var eventTime = eventTimes[index];
5526
5527 if (eventTime > mostRecentEventTime) {
5528 mostRecentEventTime = eventTime;
5529 }
5530
5531 lanes &= ~lane;
5532 }
5533
5534 return mostRecentEventTime;
5535}
5536
5537function computeExpirationTime(lane, currentTime) {
5538 switch (lane) {
5539 case SyncLane:
5540 case InputContinuousHydrationLane:
5541 case InputContinuousLane:
5542 // User interactions should expire slightly more quickly.
5543 //
5544 // NOTE: This is set to the corresponding constant as in Scheduler.js.
5545 // When we made it larger, a product metric in www regressed, suggesting
5546 // there's a user interaction that's being starved by a series of
5547 // synchronous updates. If that theory is correct, the proper solution is
5548 // to fix the starvation. However, this scenario supports the idea that
5549 // expiration times are an important safeguard when starvation
5550 // does happen.
5551 return currentTime + 250;
5552
5553 case DefaultHydrationLane:
5554 case DefaultLane:
5555 case TransitionHydrationLane:
5556 case TransitionLane1:
5557 case TransitionLane2:
5558 case TransitionLane3:
5559 case TransitionLane4:
5560 case TransitionLane5:
5561 case TransitionLane6:
5562 case TransitionLane7:
5563 case TransitionLane8:
5564 case TransitionLane9:
5565 case TransitionLane10:
5566 case TransitionLane11:
5567 case TransitionLane12:
5568 case TransitionLane13:
5569 case TransitionLane14:
5570 case TransitionLane15:
5571 case TransitionLane16:
5572 return currentTime + 5000;
5573
5574 case RetryLane1:
5575 case RetryLane2:
5576 case RetryLane3:
5577 case RetryLane4:
5578 case RetryLane5:
5579 // TODO: Retries should be allowed to expire if they are CPU bound for
5580 // too long, but when I made this change it caused a spike in browser
5581 // crashes. There must be some other underlying bug; not super urgent but
5582 // ideally should figure out why and fix it. Unfortunately we don't have
5583 // a repro for the crashes, only detected via production metrics.
5584 return NoTimestamp;
5585
5586 case SelectiveHydrationLane:
5587 case IdleHydrationLane:
5588 case IdleLane:
5589 case OffscreenLane:
5590 // Anything idle priority or lower should never expire.
5591 return NoTimestamp;
5592
5593 default:
5594 {
5595 error('Should have found matching lanes. This is a bug in React.');
5596 }
5597
5598 return NoTimestamp;
5599 }
5600}
5601
5602function markStarvedLanesAsExpired(root, currentTime) {
5603 // TODO: This gets called every time we yield. We can optimize by storing
5604 // the earliest expiration time on the root. Then use that to quickly bail out
5605 // of this function.
5606 var pendingLanes = root.pendingLanes;
5607 var suspendedLanes = root.suspendedLanes;
5608 var pingedLanes = root.pingedLanes;
5609 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
5610 // expiration time. If so, we'll assume the update is being starved and mark
5611 // it as expired to force it to finish.
5612
5613 var lanes = pendingLanes;
5614
5615 while (lanes > 0) {
5616 var index = pickArbitraryLaneIndex(lanes);
5617 var lane = 1 << index;
5618 var expirationTime = expirationTimes[index];
5619
5620 if (expirationTime === NoTimestamp) {
5621 // Found a pending lane with no expiration time. If it's not suspended, or
5622 // if it's pinged, assume it's CPU-bound. Compute a new expiration time
5623 // using the current time.
5624 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
5625 // Assumes timestamps are monotonically increasing.
5626 expirationTimes[index] = computeExpirationTime(lane, currentTime);
5627 }
5628 } else if (expirationTime <= currentTime) {
5629 // This lane expired
5630 root.expiredLanes |= lane;
5631 }
5632
5633 lanes &= ~lane;
5634 }
5635} // This returns the highest priority pending lanes regardless of whether they
5636// are suspended.
5637
5638function getHighestPriorityPendingLanes(root) {
5639 return getHighestPriorityLanes(root.pendingLanes);
5640}
5641function getLanesToRetrySynchronouslyOnError(root) {
5642 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
5643
5644 if (everythingButOffscreen !== NoLanes) {
5645 return everythingButOffscreen;
5646 }
5647
5648 if (everythingButOffscreen & OffscreenLane) {
5649 return OffscreenLane;
5650 }
5651
5652 return NoLanes;
5653}
5654function includesSyncLane(lanes) {
5655 return (lanes & SyncLane) !== NoLanes;
5656}
5657function includesNonIdleWork(lanes) {
5658 return (lanes & NonIdleLanes) !== NoLanes;
5659}
5660function includesOnlyRetries(lanes) {
5661 return (lanes & RetryLanes) === lanes;
5662}
5663function includesOnlyNonUrgentLanes(lanes) {
5664 var UrgentLanes = SyncLane | InputContinuousLane | DefaultLane;
5665 return (lanes & UrgentLanes) === NoLanes;
5666}
5667function includesOnlyTransitions(lanes) {
5668 return (lanes & TransitionLanes) === lanes;
5669}
5670function includesBlockingLane(root, lanes) {
5671
5672 var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane;
5673 return (lanes & SyncDefaultLanes) !== NoLanes;
5674}
5675function includesExpiredLane(root, lanes) {
5676 // This is a separate check from includesBlockingLane because a lane can
5677 // expire after a render has already started.
5678 return (lanes & root.expiredLanes) !== NoLanes;
5679}
5680function isTransitionLane(lane) {
5681 return (lane & TransitionLanes) !== NoLanes;
5682}
5683function claimNextTransitionLane() {
5684 // Cycle through the lanes, assigning each new transition to the next lane.
5685 // In most cases, this means every transition gets its own lane, until we
5686 // run out of lanes and cycle back to the beginning.
5687 var lane = nextTransitionLane;
5688 nextTransitionLane <<= 1;
5689
5690 if ((nextTransitionLane & TransitionLanes) === NoLanes) {
5691 nextTransitionLane = TransitionLane1;
5692 }
5693
5694 return lane;
5695}
5696function claimNextRetryLane() {
5697 var lane = nextRetryLane;
5698 nextRetryLane <<= 1;
5699
5700 if ((nextRetryLane & RetryLanes) === NoLanes) {
5701 nextRetryLane = RetryLane1;
5702 }
5703
5704 return lane;
5705}
5706function getHighestPriorityLane(lanes) {
5707 return lanes & -lanes;
5708}
5709function pickArbitraryLane(lanes) {
5710 // This wrapper function gets inlined. Only exists so to communicate that it
5711 // doesn't matter which bit is selected; you can pick any bit without
5712 // affecting the algorithms where its used. Here I'm using
5713 // getHighestPriorityLane because it requires the fewest operations.
5714 return getHighestPriorityLane(lanes);
5715}
5716
5717function pickArbitraryLaneIndex(lanes) {
5718 return 31 - clz32(lanes);
5719}
5720
5721function laneToIndex(lane) {
5722 return pickArbitraryLaneIndex(lane);
5723}
5724
5725function includesSomeLane(a, b) {
5726 return (a & b) !== NoLanes;
5727}
5728function isSubsetOfLanes(set, subset) {
5729 return (set & subset) === subset;
5730}
5731function mergeLanes(a, b) {
5732 return a | b;
5733}
5734function removeLanes(set, subset) {
5735 return set & ~subset;
5736}
5737function intersectLanes(a, b) {
5738 return a & b;
5739} // Seems redundant, but it changes the type from a single lane (used for
5740// updates) to a group of lanes (used for flushing work).
5741
5742function laneToLanes(lane) {
5743 return lane;
5744}
5745function higherPriorityLane(a, b) {
5746 // This works because the bit ranges decrease in priority as you go left.
5747 return a !== NoLane && a < b ? a : b;
5748}
5749function createLaneMap(initial) {
5750 // Intentionally pushing one by one.
5751 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
5752 var laneMap = [];
5753
5754 for (var i = 0; i < TotalLanes; i++) {
5755 laneMap.push(initial);
5756 }
5757
5758 return laneMap;
5759}
5760function markRootUpdated(root, updateLane, eventTime) {
5761 root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update
5762 // could unblock them. Clear the suspended lanes so that we can try rendering
5763 // them again.
5764 //
5765 // TODO: We really only need to unsuspend only lanes that are in the
5766 // `subtreeLanes` of the updated fiber, or the update lanes of the return
5767 // path. This would exclude suspended updates in an unrelated sibling tree,
5768 // since there's no way for this update to unblock it.
5769 //
5770 // We don't do this if the incoming update is idle, because we never process
5771 // idle updates until after all the regular updates have finished; there's no
5772 // way it could unblock a transition.
5773
5774 if (updateLane !== IdleLane) {
5775 root.suspendedLanes = NoLanes;
5776 root.pingedLanes = NoLanes;
5777 }
5778
5779 var eventTimes = root.eventTimes;
5780 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most
5781 // recent event, and we assume time is monotonically increasing.
5782
5783 eventTimes[index] = eventTime;
5784}
5785function markRootSuspended(root, suspendedLanes) {
5786 root.suspendedLanes |= suspendedLanes;
5787 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times.
5788
5789 var expirationTimes = root.expirationTimes;
5790 var lanes = suspendedLanes;
5791
5792 while (lanes > 0) {
5793 var index = pickArbitraryLaneIndex(lanes);
5794 var lane = 1 << index;
5795 expirationTimes[index] = NoTimestamp;
5796 lanes &= ~lane;
5797 }
5798}
5799function markRootPinged(root, pingedLanes, eventTime) {
5800 root.pingedLanes |= root.suspendedLanes & pingedLanes;
5801}
5802function markRootFinished(root, remainingLanes) {
5803 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes;
5804 root.pendingLanes = remainingLanes; // Let's try everything again
5805
5806 root.suspendedLanes = NoLanes;
5807 root.pingedLanes = NoLanes;
5808 root.expiredLanes &= remainingLanes;
5809 root.mutableReadLanes &= remainingLanes;
5810 root.entangledLanes &= remainingLanes;
5811 var entanglements = root.entanglements;
5812 var eventTimes = root.eventTimes;
5813 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work
5814
5815 var lanes = noLongerPendingLanes;
5816
5817 while (lanes > 0) {
5818 var index = pickArbitraryLaneIndex(lanes);
5819 var lane = 1 << index;
5820 entanglements[index] = NoLanes;
5821 eventTimes[index] = NoTimestamp;
5822 expirationTimes[index] = NoTimestamp;
5823 lanes &= ~lane;
5824 }
5825}
5826function markRootEntangled(root, entangledLanes) {
5827 // In addition to entangling each of the given lanes with each other, we also
5828 // have to consider _transitive_ entanglements. For each lane that is already
5829 // entangled with *any* of the given lanes, that lane is now transitively
5830 // entangled with *all* the given lanes.
5831 //
5832 // Translated: If C is entangled with A, then entangling A with B also
5833 // entangles C with B.
5834 //
5835 // If this is hard to grasp, it might help to intentionally break this
5836 // function and look at the tests that fail in ReactTransition-test.js. Try
5837 // commenting out one of the conditions below.
5838 var rootEntangledLanes = root.entangledLanes |= entangledLanes;
5839 var entanglements = root.entanglements;
5840 var lanes = rootEntangledLanes;
5841
5842 while (lanes) {
5843 var index = pickArbitraryLaneIndex(lanes);
5844 var lane = 1 << index;
5845
5846 if ( // Is this one of the newly entangled lanes?
5847 lane & entangledLanes | // Is this lane transitively entangled with the newly entangled lanes?
5848 entanglements[index] & entangledLanes) {
5849 entanglements[index] |= entangledLanes;
5850 }
5851
5852 lanes &= ~lane;
5853 }
5854}
5855function getBumpedLaneForHydration(root, renderLanes) {
5856 var renderLane = getHighestPriorityLane(renderLanes);
5857 var lane;
5858
5859 switch (renderLane) {
5860 case InputContinuousLane:
5861 lane = InputContinuousHydrationLane;
5862 break;
5863
5864 case DefaultLane:
5865 lane = DefaultHydrationLane;
5866 break;
5867
5868 case TransitionLane1:
5869 case TransitionLane2:
5870 case TransitionLane3:
5871 case TransitionLane4:
5872 case TransitionLane5:
5873 case TransitionLane6:
5874 case TransitionLane7:
5875 case TransitionLane8:
5876 case TransitionLane9:
5877 case TransitionLane10:
5878 case TransitionLane11:
5879 case TransitionLane12:
5880 case TransitionLane13:
5881 case TransitionLane14:
5882 case TransitionLane15:
5883 case TransitionLane16:
5884 case RetryLane1:
5885 case RetryLane2:
5886 case RetryLane3:
5887 case RetryLane4:
5888 case RetryLane5:
5889 lane = TransitionHydrationLane;
5890 break;
5891
5892 case IdleLane:
5893 lane = IdleHydrationLane;
5894 break;
5895
5896 default:
5897 // Everything else is already either a hydration lane, or shouldn't
5898 // be retried at a hydration lane.
5899 lane = NoLane;
5900 break;
5901 } // Check if the lane we chose is suspended. If so, that indicates that we
5902 // already attempted and failed to hydrate at that level. Also check if we're
5903 // already rendering that lane, which is rare but could happen.
5904
5905
5906 if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) {
5907 // Give up trying to hydrate and fall back to client render.
5908 return NoLane;
5909 }
5910
5911 return lane;
5912}
5913function addFiberToLanesMap(root, fiber, lanes) {
5914
5915 if (!isDevToolsPresent) {
5916 return;
5917 }
5918
5919 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap;
5920
5921 while (lanes > 0) {
5922 var index = laneToIndex(lanes);
5923 var lane = 1 << index;
5924 var updaters = pendingUpdatersLaneMap[index];
5925 updaters.add(fiber);
5926 lanes &= ~lane;
5927 }
5928}
5929function movePendingFibersToMemoized(root, lanes) {
5930
5931 if (!isDevToolsPresent) {
5932 return;
5933 }
5934
5935 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap;
5936 var memoizedUpdaters = root.memoizedUpdaters;
5937
5938 while (lanes > 0) {
5939 var index = laneToIndex(lanes);
5940 var lane = 1 << index;
5941 var updaters = pendingUpdatersLaneMap[index];
5942
5943 if (updaters.size > 0) {
5944 updaters.forEach(function (fiber) {
5945 var alternate = fiber.alternate;
5946
5947 if (alternate === null || !memoizedUpdaters.has(alternate)) {
5948 memoizedUpdaters.add(fiber);
5949 }
5950 });
5951 updaters.clear();
5952 }
5953
5954 lanes &= ~lane;
5955 }
5956}
5957function getTransitionsForLanes(root, lanes) {
5958 {
5959 return null;
5960 }
5961}
5962
5963var DiscreteEventPriority = SyncLane;
5964var ContinuousEventPriority = InputContinuousLane;
5965var DefaultEventPriority = DefaultLane;
5966var IdleEventPriority = IdleLane;
5967var currentUpdatePriority = NoLane;
5968function getCurrentUpdatePriority() {
5969 return currentUpdatePriority;
5970}
5971function setCurrentUpdatePriority(newPriority) {
5972 currentUpdatePriority = newPriority;
5973}
5974function runWithPriority(priority, fn) {
5975 var previousPriority = currentUpdatePriority;
5976
5977 try {
5978 currentUpdatePriority = priority;
5979 return fn();
5980 } finally {
5981 currentUpdatePriority = previousPriority;
5982 }
5983}
5984function higherEventPriority(a, b) {
5985 return a !== 0 && a < b ? a : b;
5986}
5987function lowerEventPriority(a, b) {
5988 return a === 0 || a > b ? a : b;
5989}
5990function isHigherEventPriority(a, b) {
5991 return a !== 0 && a < b;
5992}
5993function lanesToEventPriority(lanes) {
5994 var lane = getHighestPriorityLane(lanes);
5995
5996 if (!isHigherEventPriority(DiscreteEventPriority, lane)) {
5997 return DiscreteEventPriority;
5998 }
5999
6000 if (!isHigherEventPriority(ContinuousEventPriority, lane)) {
6001 return ContinuousEventPriority;
6002 }
6003
6004 if (includesNonIdleWork(lane)) {
6005 return DefaultEventPriority;
6006 }
6007
6008 return IdleEventPriority;
6009}
6010
6011// This is imported by the event replaying implementation in React DOM. It's
6012// in a separate file to break a circular dependency between the renderer and
6013// the reconciler.
6014function isRootDehydrated(root) {
6015 var currentState = root.current.memoizedState;
6016 return currentState.isDehydrated;
6017}
6018
6019var _attemptSynchronousHydration;
6020
6021function setAttemptSynchronousHydration(fn) {
6022 _attemptSynchronousHydration = fn;
6023}
6024function attemptSynchronousHydration(fiber) {
6025 _attemptSynchronousHydration(fiber);
6026}
6027var attemptContinuousHydration;
6028function setAttemptContinuousHydration(fn) {
6029 attemptContinuousHydration = fn;
6030}
6031var attemptHydrationAtCurrentPriority;
6032function setAttemptHydrationAtCurrentPriority(fn) {
6033 attemptHydrationAtCurrentPriority = fn;
6034}
6035var getCurrentUpdatePriority$1;
6036function setGetCurrentUpdatePriority(fn) {
6037 getCurrentUpdatePriority$1 = fn;
6038}
6039var attemptHydrationAtPriority;
6040function setAttemptHydrationAtPriority(fn) {
6041 attemptHydrationAtPriority = fn;
6042} // TODO: Upgrade this definition once we're on a newer version of Flow that
6043// has this definition built-in.
6044
6045var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
6046
6047var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
6048// if the last target was dehydrated.
6049
6050var queuedFocus = null;
6051var queuedDrag = null;
6052var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
6053
6054var queuedPointers = new Map();
6055var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
6056
6057var queuedExplicitHydrationTargets = [];
6058var discreteReplayableEvents = ['mousedown', 'mouseup', 'touchcancel', 'touchend', 'touchstart', 'auxclick', 'dblclick', 'pointercancel', 'pointerdown', 'pointerup', 'dragend', 'dragstart', 'drop', 'compositionend', 'compositionstart', 'keydown', 'keypress', 'keyup', 'input', 'textInput', // Intentionally camelCase
6059'copy', 'cut', 'paste', 'click', 'change', 'contextmenu', 'reset', 'submit'];
6060function isDiscreteEventThatRequiresHydration(eventType) {
6061 return discreteReplayableEvents.indexOf(eventType) > -1;
6062}
6063
6064function createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6065 return {
6066 blockedOn: blockedOn,
6067 domEventName: domEventName,
6068 eventSystemFlags: eventSystemFlags,
6069 nativeEvent: nativeEvent,
6070 targetContainers: [targetContainer]
6071 };
6072}
6073
6074function clearIfContinuousEvent(domEventName, nativeEvent) {
6075 switch (domEventName) {
6076 case 'focusin':
6077 case 'focusout':
6078 queuedFocus = null;
6079 break;
6080
6081 case 'dragenter':
6082 case 'dragleave':
6083 queuedDrag = null;
6084 break;
6085
6086 case 'mouseover':
6087 case 'mouseout':
6088 queuedMouse = null;
6089 break;
6090
6091 case 'pointerover':
6092 case 'pointerout':
6093 {
6094 var pointerId = nativeEvent.pointerId;
6095 queuedPointers.delete(pointerId);
6096 break;
6097 }
6098
6099 case 'gotpointercapture':
6100 case 'lostpointercapture':
6101 {
6102 var _pointerId = nativeEvent.pointerId;
6103 queuedPointerCaptures.delete(_pointerId);
6104 break;
6105 }
6106 }
6107}
6108
6109function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6110 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
6111 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
6112
6113 if (blockedOn !== null) {
6114 var _fiber2 = getInstanceFromNode(blockedOn);
6115
6116 if (_fiber2 !== null) {
6117 // Attempt to increase the priority of this target.
6118 attemptContinuousHydration(_fiber2);
6119 }
6120 }
6121
6122 return queuedEvent;
6123 } // If we have already queued this exact event, then it's because
6124 // the different event systems have different DOM event listeners.
6125 // We can accumulate the flags, and the targetContainers, and
6126 // store a single event to be replayed.
6127
6128
6129 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
6130 var targetContainers = existingQueuedEvent.targetContainers;
6131
6132 if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) {
6133 targetContainers.push(targetContainer);
6134 }
6135
6136 return existingQueuedEvent;
6137}
6138
6139function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6140 // These set relatedTarget to null because the replayed event will be treated as if we
6141 // moved from outside the window (no target) onto the target once it hydrates.
6142 // Instead of mutating we could clone the event.
6143 switch (domEventName) {
6144 case 'focusin':
6145 {
6146 var focusEvent = nativeEvent;
6147 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent);
6148 return true;
6149 }
6150
6151 case 'dragenter':
6152 {
6153 var dragEvent = nativeEvent;
6154 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent);
6155 return true;
6156 }
6157
6158 case 'mouseover':
6159 {
6160 var mouseEvent = nativeEvent;
6161 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent);
6162 return true;
6163 }
6164
6165 case 'pointerover':
6166 {
6167 var pointerEvent = nativeEvent;
6168 var pointerId = pointerEvent.pointerId;
6169 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent));
6170 return true;
6171 }
6172
6173 case 'gotpointercapture':
6174 {
6175 var _pointerEvent = nativeEvent;
6176 var _pointerId2 = _pointerEvent.pointerId;
6177 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent));
6178 return true;
6179 }
6180 }
6181
6182 return false;
6183} // Check if this target is unblocked. Returns true if it's unblocked.
6184
6185function attemptExplicitHydrationTarget(queuedTarget) {
6186 // TODO: This function shares a lot of logic with findInstanceBlockingEvent.
6187 // Try to unify them. It's a bit tricky since it would require two return
6188 // values.
6189 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
6190
6191 if (targetInst !== null) {
6192 var nearestMounted = getNearestMountedFiber(targetInst);
6193
6194 if (nearestMounted !== null) {
6195 var tag = nearestMounted.tag;
6196
6197 if (tag === SuspenseComponent) {
6198 var instance = getSuspenseInstanceFromFiber(nearestMounted);
6199
6200 if (instance !== null) {
6201 // We're blocked on hydrating this boundary.
6202 // Increase its priority.
6203 queuedTarget.blockedOn = instance;
6204 attemptHydrationAtPriority(queuedTarget.priority, function () {
6205 attemptHydrationAtCurrentPriority(nearestMounted);
6206 });
6207 return;
6208 }
6209 } else if (tag === HostRoot) {
6210 var root = nearestMounted.stateNode;
6211
6212 if (isRootDehydrated(root)) {
6213 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
6214 // a root other than sync.
6215
6216 return;
6217 }
6218 }
6219 }
6220 }
6221
6222 queuedTarget.blockedOn = null;
6223}
6224
6225function queueExplicitHydrationTarget(target) {
6226 // TODO: This will read the priority if it's dispatched by the React
6227 // event system but not native events. Should read window.event.type, like
6228 // we do for updates (getCurrentEventPriority).
6229 var updatePriority = getCurrentUpdatePriority$1();
6230 var queuedTarget = {
6231 blockedOn: null,
6232 target: target,
6233 priority: updatePriority
6234 };
6235 var i = 0;
6236
6237 for (; i < queuedExplicitHydrationTargets.length; i++) {
6238 // Stop once we hit the first target with lower priority than
6239 if (!isHigherEventPriority(updatePriority, queuedExplicitHydrationTargets[i].priority)) {
6240 break;
6241 }
6242 }
6243
6244 queuedExplicitHydrationTargets.splice(i, 0, queuedTarget);
6245
6246 if (i === 0) {
6247 attemptExplicitHydrationTarget(queuedTarget);
6248 }
6249}
6250
6251function attemptReplayContinuousQueuedEvent(queuedEvent) {
6252 if (queuedEvent.blockedOn !== null) {
6253 return false;
6254 }
6255
6256 var targetContainers = queuedEvent.targetContainers;
6257
6258 while (targetContainers.length > 0) {
6259 var targetContainer = targetContainers[0];
6260 var nextBlockedOn = findInstanceBlockingEvent(queuedEvent.domEventName, queuedEvent.eventSystemFlags, targetContainer, queuedEvent.nativeEvent);
6261
6262 if (nextBlockedOn === null) {
6263 {
6264 var nativeEvent = queuedEvent.nativeEvent;
6265 var nativeEventClone = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
6266 setReplayingEvent(nativeEventClone);
6267 nativeEvent.target.dispatchEvent(nativeEventClone);
6268 resetReplayingEvent();
6269 }
6270 } else {
6271 // We're still blocked. Try again later.
6272 var _fiber3 = getInstanceFromNode(nextBlockedOn);
6273
6274 if (_fiber3 !== null) {
6275 attemptContinuousHydration(_fiber3);
6276 }
6277
6278 queuedEvent.blockedOn = nextBlockedOn;
6279 return false;
6280 } // This target container was successfully dispatched. Try the next.
6281
6282
6283 targetContainers.shift();
6284 }
6285
6286 return true;
6287}
6288
6289function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
6290 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
6291 map.delete(key);
6292 }
6293}
6294
6295function replayUnblockedEvents() {
6296 hasScheduledReplayAttempt = false;
6297
6298
6299 if (queuedFocus !== null && attemptReplayContinuousQueuedEvent(queuedFocus)) {
6300 queuedFocus = null;
6301 }
6302
6303 if (queuedDrag !== null && attemptReplayContinuousQueuedEvent(queuedDrag)) {
6304 queuedDrag = null;
6305 }
6306
6307 if (queuedMouse !== null && attemptReplayContinuousQueuedEvent(queuedMouse)) {
6308 queuedMouse = null;
6309 }
6310
6311 queuedPointers.forEach(attemptReplayContinuousQueuedEventInMap);
6312 queuedPointerCaptures.forEach(attemptReplayContinuousQueuedEventInMap);
6313}
6314
6315function scheduleCallbackIfUnblocked(queuedEvent, unblocked) {
6316 if (queuedEvent.blockedOn === unblocked) {
6317 queuedEvent.blockedOn = null;
6318
6319 if (!hasScheduledReplayAttempt) {
6320 hasScheduledReplayAttempt = true; // Schedule a callback to attempt replaying as many events as are
6321 // now unblocked. This first might not actually be unblocked yet.
6322 // We could check it early to avoid scheduling an unnecessary callback.
6323
6324 Scheduler.unstable_scheduleCallback(Scheduler.unstable_NormalPriority, replayUnblockedEvents);
6325 }
6326 }
6327}
6328
6329function retryIfBlockedOn(unblocked) {
6330 // Mark anything that was blocked on this as no longer blocked
6331 // and eligible for a replay.
6332 if (queuedDiscreteEvents.length > 0) {
6333 scheduleCallbackIfUnblocked(queuedDiscreteEvents[0], unblocked); // This is a exponential search for each boundary that commits. I think it's
6334 // worth it because we expect very few discrete events to queue up and once
6335 // we are actually fully unblocked it will be fast to replay them.
6336
6337 for (var i = 1; i < queuedDiscreteEvents.length; i++) {
6338 var queuedEvent = queuedDiscreteEvents[i];
6339
6340 if (queuedEvent.blockedOn === unblocked) {
6341 queuedEvent.blockedOn = null;
6342 }
6343 }
6344 }
6345
6346 if (queuedFocus !== null) {
6347 scheduleCallbackIfUnblocked(queuedFocus, unblocked);
6348 }
6349
6350 if (queuedDrag !== null) {
6351 scheduleCallbackIfUnblocked(queuedDrag, unblocked);
6352 }
6353
6354 if (queuedMouse !== null) {
6355 scheduleCallbackIfUnblocked(queuedMouse, unblocked);
6356 }
6357
6358 var unblock = function (queuedEvent) {
6359 return scheduleCallbackIfUnblocked(queuedEvent, unblocked);
6360 };
6361
6362 queuedPointers.forEach(unblock);
6363 queuedPointerCaptures.forEach(unblock);
6364
6365 for (var _i = 0; _i < queuedExplicitHydrationTargets.length; _i++) {
6366 var queuedTarget = queuedExplicitHydrationTargets[_i];
6367
6368 if (queuedTarget.blockedOn === unblocked) {
6369 queuedTarget.blockedOn = null;
6370 }
6371 }
6372
6373 while (queuedExplicitHydrationTargets.length > 0) {
6374 var nextExplicitTarget = queuedExplicitHydrationTargets[0];
6375
6376 if (nextExplicitTarget.blockedOn !== null) {
6377 // We're still blocked.
6378 break;
6379 } else {
6380 attemptExplicitHydrationTarget(nextExplicitTarget);
6381
6382 if (nextExplicitTarget.blockedOn === null) {
6383 // We're unblocked.
6384 queuedExplicitHydrationTargets.shift();
6385 }
6386 }
6387 }
6388}
6389
6390var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; // TODO: can we stop exporting these?
6391
6392var _enabled = true; // This is exported in FB builds for use by legacy FB layer infra.
6393// We'd like to remove this but it's not clear if this is safe.
6394
6395function setEnabled(enabled) {
6396 _enabled = !!enabled;
6397}
6398function isEnabled() {
6399 return _enabled;
6400}
6401function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) {
6402 var eventPriority = getEventPriority(domEventName);
6403 var listenerWrapper;
6404
6405 switch (eventPriority) {
6406 case DiscreteEventPriority:
6407 listenerWrapper = dispatchDiscreteEvent;
6408 break;
6409
6410 case ContinuousEventPriority:
6411 listenerWrapper = dispatchContinuousEvent;
6412 break;
6413
6414 case DefaultEventPriority:
6415 default:
6416 listenerWrapper = dispatchEvent;
6417 break;
6418 }
6419
6420 return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
6421}
6422
6423function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) {
6424 var previousPriority = getCurrentUpdatePriority();
6425 var prevTransition = ReactCurrentBatchConfig.transition;
6426 ReactCurrentBatchConfig.transition = null;
6427
6428 try {
6429 setCurrentUpdatePriority(DiscreteEventPriority);
6430 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
6431 } finally {
6432 setCurrentUpdatePriority(previousPriority);
6433 ReactCurrentBatchConfig.transition = prevTransition;
6434 }
6435}
6436
6437function dispatchContinuousEvent(domEventName, eventSystemFlags, container, nativeEvent) {
6438 var previousPriority = getCurrentUpdatePriority();
6439 var prevTransition = ReactCurrentBatchConfig.transition;
6440 ReactCurrentBatchConfig.transition = null;
6441
6442 try {
6443 setCurrentUpdatePriority(ContinuousEventPriority);
6444 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
6445 } finally {
6446 setCurrentUpdatePriority(previousPriority);
6447 ReactCurrentBatchConfig.transition = prevTransition;
6448 }
6449}
6450
6451function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6452 if (!_enabled) {
6453 return;
6454 }
6455
6456 {
6457 dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(domEventName, eventSystemFlags, targetContainer, nativeEvent);
6458 }
6459}
6460
6461function dispatchEventWithEnableCapturePhaseSelectiveHydrationWithoutDiscreteEventReplay(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6462 var blockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
6463
6464 if (blockedOn === null) {
6465 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
6466 clearIfContinuousEvent(domEventName, nativeEvent);
6467 return;
6468 }
6469
6470 if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) {
6471 nativeEvent.stopPropagation();
6472 return;
6473 } // We need to clear only if we didn't queue because
6474 // queueing is accumulative.
6475
6476
6477 clearIfContinuousEvent(domEventName, nativeEvent);
6478
6479 if (eventSystemFlags & IS_CAPTURE_PHASE && isDiscreteEventThatRequiresHydration(domEventName)) {
6480 while (blockedOn !== null) {
6481 var fiber = getInstanceFromNode(blockedOn);
6482
6483 if (fiber !== null) {
6484 attemptSynchronousHydration(fiber);
6485 }
6486
6487 var nextBlockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
6488
6489 if (nextBlockedOn === null) {
6490 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
6491 }
6492
6493 if (nextBlockedOn === blockedOn) {
6494 break;
6495 }
6496
6497 blockedOn = nextBlockedOn;
6498 }
6499
6500 if (blockedOn !== null) {
6501 nativeEvent.stopPropagation();
6502 }
6503
6504 return;
6505 } // This is not replayable so we'll invoke it but without a target,
6506 // in case the event system needs to trace it.
6507
6508
6509 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer);
6510}
6511
6512var return_targetInst = null; // Returns a SuspenseInstance or Container if it's blocked.
6513// The return_targetInst field above is conceptually part of the return value.
6514
6515function findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6516 // TODO: Warn if _enabled is false.
6517 return_targetInst = null;
6518 var nativeEventTarget = getEventTarget(nativeEvent);
6519 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
6520
6521 if (targetInst !== null) {
6522 var nearestMounted = getNearestMountedFiber(targetInst);
6523
6524 if (nearestMounted === null) {
6525 // This tree has been unmounted already. Dispatch without a target.
6526 targetInst = null;
6527 } else {
6528 var tag = nearestMounted.tag;
6529
6530 if (tag === SuspenseComponent) {
6531 var instance = getSuspenseInstanceFromFiber(nearestMounted);
6532
6533 if (instance !== null) {
6534 // Queue the event to be replayed later. Abort dispatching since we
6535 // don't want this event dispatched twice through the event system.
6536 // TODO: If this is the first discrete event in the queue. Schedule an increased
6537 // priority for this boundary.
6538 return instance;
6539 } // This shouldn't happen, something went wrong but to avoid blocking
6540 // the whole system, dispatch the event without a target.
6541 // TODO: Warn.
6542
6543
6544 targetInst = null;
6545 } else if (tag === HostRoot) {
6546 var root = nearestMounted.stateNode;
6547
6548 if (isRootDehydrated(root)) {
6549 // If this happens during a replay something went wrong and it might block
6550 // the whole system.
6551 return getContainerFromFiber(nearestMounted);
6552 }
6553
6554 targetInst = null;
6555 } else if (nearestMounted !== targetInst) {
6556 // If we get an event (ex: img onload) before committing that
6557 // component's mount, ignore it for now (that is, treat it as if it was an
6558 // event on a non-React tree). We might also consider queueing events and
6559 // dispatching them after the mount.
6560 targetInst = null;
6561 }
6562 }
6563 }
6564
6565 return_targetInst = targetInst; // We're not blocked on anything.
6566
6567 return null;
6568}
6569function getEventPriority(domEventName) {
6570 switch (domEventName) {
6571 // Used by SimpleEventPlugin:
6572 case 'cancel':
6573 case 'click':
6574 case 'close':
6575 case 'contextmenu':
6576 case 'copy':
6577 case 'cut':
6578 case 'auxclick':
6579 case 'dblclick':
6580 case 'dragend':
6581 case 'dragstart':
6582 case 'drop':
6583 case 'focusin':
6584 case 'focusout':
6585 case 'input':
6586 case 'invalid':
6587 case 'keydown':
6588 case 'keypress':
6589 case 'keyup':
6590 case 'mousedown':
6591 case 'mouseup':
6592 case 'paste':
6593 case 'pause':
6594 case 'play':
6595 case 'pointercancel':
6596 case 'pointerdown':
6597 case 'pointerup':
6598 case 'ratechange':
6599 case 'reset':
6600 case 'resize':
6601 case 'seeked':
6602 case 'submit':
6603 case 'touchcancel':
6604 case 'touchend':
6605 case 'touchstart':
6606 case 'volumechange': // Used by polyfills:
6607 // eslint-disable-next-line no-fallthrough
6608
6609 case 'change':
6610 case 'selectionchange':
6611 case 'textInput':
6612 case 'compositionstart':
6613 case 'compositionend':
6614 case 'compositionupdate': // Only enableCreateEventHandleAPI:
6615 // eslint-disable-next-line no-fallthrough
6616
6617 case 'beforeblur':
6618 case 'afterblur': // Not used by React but could be by user code:
6619 // eslint-disable-next-line no-fallthrough
6620
6621 case 'beforeinput':
6622 case 'blur':
6623 case 'fullscreenchange':
6624 case 'focus':
6625 case 'hashchange':
6626 case 'popstate':
6627 case 'select':
6628 case 'selectstart':
6629 return DiscreteEventPriority;
6630
6631 case 'drag':
6632 case 'dragenter':
6633 case 'dragexit':
6634 case 'dragleave':
6635 case 'dragover':
6636 case 'mousemove':
6637 case 'mouseout':
6638 case 'mouseover':
6639 case 'pointermove':
6640 case 'pointerout':
6641 case 'pointerover':
6642 case 'scroll':
6643 case 'toggle':
6644 case 'touchmove':
6645 case 'wheel': // Not used by React but could be by user code:
6646 // eslint-disable-next-line no-fallthrough
6647
6648 case 'mouseenter':
6649 case 'mouseleave':
6650 case 'pointerenter':
6651 case 'pointerleave':
6652 return ContinuousEventPriority;
6653
6654 case 'message':
6655 {
6656 // We might be in the Scheduler callback.
6657 // Eventually this mechanism will be replaced by a check
6658 // of the current priority on the native scheduler.
6659 var schedulerPriority = getCurrentPriorityLevel();
6660
6661 switch (schedulerPriority) {
6662 case ImmediatePriority:
6663 return DiscreteEventPriority;
6664
6665 case UserBlockingPriority:
6666 return ContinuousEventPriority;
6667
6668 case NormalPriority:
6669 case LowPriority:
6670 // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration.
6671 return DefaultEventPriority;
6672
6673 case IdlePriority:
6674 return IdleEventPriority;
6675
6676 default:
6677 return DefaultEventPriority;
6678 }
6679 }
6680
6681 default:
6682 return DefaultEventPriority;
6683 }
6684}
6685
6686function addEventBubbleListener(target, eventType, listener) {
6687 target.addEventListener(eventType, listener, false);
6688 return listener;
6689}
6690function addEventCaptureListener(target, eventType, listener) {
6691 target.addEventListener(eventType, listener, true);
6692 return listener;
6693}
6694function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) {
6695 target.addEventListener(eventType, listener, {
6696 capture: true,
6697 passive: passive
6698 });
6699 return listener;
6700}
6701function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) {
6702 target.addEventListener(eventType, listener, {
6703 passive: passive
6704 });
6705 return listener;
6706}
6707
6708/**
6709 * These variables store information about text content of a target node,
6710 * allowing comparison of content before and after a given event.
6711 *
6712 * Identify the node where selection currently begins, then observe
6713 * both its text content and its current position in the DOM. Since the
6714 * browser may natively replace the target node during composition, we can
6715 * use its position to find its replacement.
6716 *
6717 *
6718 */
6719var root = null;
6720var startText = null;
6721var fallbackText = null;
6722function initialize(nativeEventTarget) {
6723 root = nativeEventTarget;
6724 startText = getText();
6725 return true;
6726}
6727function reset() {
6728 root = null;
6729 startText = null;
6730 fallbackText = null;
6731}
6732function getData() {
6733 if (fallbackText) {
6734 return fallbackText;
6735 }
6736
6737 var start;
6738 var startValue = startText;
6739 var startLength = startValue.length;
6740 var end;
6741 var endValue = getText();
6742 var endLength = endValue.length;
6743
6744 for (start = 0; start < startLength; start++) {
6745 if (startValue[start] !== endValue[start]) {
6746 break;
6747 }
6748 }
6749
6750 var minEnd = startLength - start;
6751
6752 for (end = 1; end <= minEnd; end++) {
6753 if (startValue[startLength - end] !== endValue[endLength - end]) {
6754 break;
6755 }
6756 }
6757
6758 var sliceTail = end > 1 ? 1 - end : undefined;
6759 fallbackText = endValue.slice(start, sliceTail);
6760 return fallbackText;
6761}
6762function getText() {
6763 if ('value' in root) {
6764 return root.value;
6765 }
6766
6767 return root.textContent;
6768}
6769
6770/**
6771 * `charCode` represents the actual "character code" and is safe to use with
6772 * `String.fromCharCode`. As such, only keys that correspond to printable
6773 * characters produce a valid `charCode`, the only exception to this is Enter.
6774 * The Tab-key is considered non-printable and does not have a `charCode`,
6775 * presumably because it does not produce a tab-character in browsers.
6776 *
6777 * @param {object} nativeEvent Native browser event.
6778 * @return {number} Normalized `charCode` property.
6779 */
6780function getEventCharCode(nativeEvent) {
6781 var charCode;
6782 var keyCode = nativeEvent.keyCode;
6783
6784 if ('charCode' in nativeEvent) {
6785 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
6786
6787 if (charCode === 0 && keyCode === 13) {
6788 charCode = 13;
6789 }
6790 } else {
6791 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
6792 charCode = keyCode;
6793 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
6794 // report Enter as charCode 10 when ctrl is pressed.
6795
6796
6797 if (charCode === 10) {
6798 charCode = 13;
6799 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
6800 // Must not discard the (non-)printable Enter-key.
6801
6802
6803 if (charCode >= 32 || charCode === 13) {
6804 return charCode;
6805 }
6806
6807 return 0;
6808}
6809
6810function functionThatReturnsTrue() {
6811 return true;
6812}
6813
6814function functionThatReturnsFalse() {
6815 return false;
6816} // This is intentionally a factory so that we have different returned constructors.
6817// If we had a single constructor, it would be megamorphic and engines would deopt.
6818
6819
6820function createSyntheticEvent(Interface) {
6821 /**
6822 * Synthetic events are dispatched by event plugins, typically in response to a
6823 * top-level event delegation handler.
6824 *
6825 * These systems should generally use pooling to reduce the frequency of garbage
6826 * collection. The system should check `isPersistent` to determine whether the
6827 * event should be released into the pool after being dispatched. Users that
6828 * need a persisted event should invoke `persist`.
6829 *
6830 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
6831 * normalizing browser quirks. Subclasses do not necessarily have to implement a
6832 * DOM interface; custom application-specific events can also subclass this.
6833 */
6834 function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
6835 this._reactName = reactName;
6836 this._targetInst = targetInst;
6837 this.type = reactEventType;
6838 this.nativeEvent = nativeEvent;
6839 this.target = nativeEventTarget;
6840 this.currentTarget = null;
6841
6842 for (var _propName in Interface) {
6843 if (!Interface.hasOwnProperty(_propName)) {
6844 continue;
6845 }
6846
6847 var normalize = Interface[_propName];
6848
6849 if (normalize) {
6850 this[_propName] = normalize(nativeEvent);
6851 } else {
6852 this[_propName] = nativeEvent[_propName];
6853 }
6854 }
6855
6856 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
6857
6858 if (defaultPrevented) {
6859 this.isDefaultPrevented = functionThatReturnsTrue;
6860 } else {
6861 this.isDefaultPrevented = functionThatReturnsFalse;
6862 }
6863
6864 this.isPropagationStopped = functionThatReturnsFalse;
6865 return this;
6866 }
6867
6868 assign(SyntheticBaseEvent.prototype, {
6869 preventDefault: function () {
6870 this.defaultPrevented = true;
6871 var event = this.nativeEvent;
6872
6873 if (!event) {
6874 return;
6875 }
6876
6877 if (event.preventDefault) {
6878 event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE
6879 } else if (typeof event.returnValue !== 'unknown') {
6880 event.returnValue = false;
6881 }
6882
6883 this.isDefaultPrevented = functionThatReturnsTrue;
6884 },
6885 stopPropagation: function () {
6886 var event = this.nativeEvent;
6887
6888 if (!event) {
6889 return;
6890 }
6891
6892 if (event.stopPropagation) {
6893 event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE
6894 } else if (typeof event.cancelBubble !== 'unknown') {
6895 // The ChangeEventPlugin registers a "propertychange" event for
6896 // IE. This event does not support bubbling or cancelling, and
6897 // any references to cancelBubble throw "Member not found". A
6898 // typeof check of "unknown" circumvents this issue (and is also
6899 // IE specific).
6900 event.cancelBubble = true;
6901 }
6902
6903 this.isPropagationStopped = functionThatReturnsTrue;
6904 },
6905
6906 /**
6907 * We release all dispatched `SyntheticEvent`s after each event loop, adding
6908 * them back into the pool. This allows a way to hold onto a reference that
6909 * won't be added back into the pool.
6910 */
6911 persist: function () {// Modern event system doesn't use pooling.
6912 },
6913
6914 /**
6915 * Checks if this event should be released back into the pool.
6916 *
6917 * @return {boolean} True if this should not be released, false otherwise.
6918 */
6919 isPersistent: functionThatReturnsTrue
6920 });
6921 return SyntheticBaseEvent;
6922}
6923/**
6924 * @interface Event
6925 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6926 */
6927
6928
6929var EventInterface = {
6930 eventPhase: 0,
6931 bubbles: 0,
6932 cancelable: 0,
6933 timeStamp: function (event) {
6934 return event.timeStamp || Date.now();
6935 },
6936 defaultPrevented: 0,
6937 isTrusted: 0
6938};
6939var SyntheticEvent = createSyntheticEvent(EventInterface);
6940
6941var UIEventInterface = assign({}, EventInterface, {
6942 view: 0,
6943 detail: 0
6944});
6945
6946var SyntheticUIEvent = createSyntheticEvent(UIEventInterface);
6947var lastMovementX;
6948var lastMovementY;
6949var lastMouseEvent;
6950
6951function updateMouseMovementPolyfillState(event) {
6952 if (event !== lastMouseEvent) {
6953 if (lastMouseEvent && event.type === 'mousemove') {
6954 lastMovementX = event.screenX - lastMouseEvent.screenX;
6955 lastMovementY = event.screenY - lastMouseEvent.screenY;
6956 } else {
6957 lastMovementX = 0;
6958 lastMovementY = 0;
6959 }
6960
6961 lastMouseEvent = event;
6962 }
6963}
6964/**
6965 * @interface MouseEvent
6966 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6967 */
6968
6969
6970var MouseEventInterface = assign({}, UIEventInterface, {
6971 screenX: 0,
6972 screenY: 0,
6973 clientX: 0,
6974 clientY: 0,
6975 pageX: 0,
6976 pageY: 0,
6977 ctrlKey: 0,
6978 shiftKey: 0,
6979 altKey: 0,
6980 metaKey: 0,
6981 getModifierState: getEventModifierState,
6982 button: 0,
6983 buttons: 0,
6984 relatedTarget: function (event) {
6985 if (event.relatedTarget === undefined) return event.fromElement === event.srcElement ? event.toElement : event.fromElement;
6986 return event.relatedTarget;
6987 },
6988 movementX: function (event) {
6989 if ('movementX' in event) {
6990 return event.movementX;
6991 }
6992
6993 updateMouseMovementPolyfillState(event);
6994 return lastMovementX;
6995 },
6996 movementY: function (event) {
6997 if ('movementY' in event) {
6998 return event.movementY;
6999 } // Don't need to call updateMouseMovementPolyfillState() here
7000 // because it's guaranteed to have already run when movementX
7001 // was copied.
7002
7003
7004 return lastMovementY;
7005 }
7006});
7007
7008var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface);
7009/**
7010 * @interface DragEvent
7011 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7012 */
7013
7014var DragEventInterface = assign({}, MouseEventInterface, {
7015 dataTransfer: 0
7016});
7017
7018var SyntheticDragEvent = createSyntheticEvent(DragEventInterface);
7019/**
7020 * @interface FocusEvent
7021 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7022 */
7023
7024var FocusEventInterface = assign({}, UIEventInterface, {
7025 relatedTarget: 0
7026});
7027
7028var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface);
7029/**
7030 * @interface Event
7031 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
7032 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
7033 */
7034
7035var AnimationEventInterface = assign({}, EventInterface, {
7036 animationName: 0,
7037 elapsedTime: 0,
7038 pseudoElement: 0
7039});
7040
7041var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface);
7042/**
7043 * @interface Event
7044 * @see http://www.w3.org/TR/clipboard-apis/
7045 */
7046
7047var ClipboardEventInterface = assign({}, EventInterface, {
7048 clipboardData: function (event) {
7049 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
7050 }
7051});
7052
7053var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface);
7054/**
7055 * @interface Event
7056 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
7057 */
7058
7059var CompositionEventInterface = assign({}, EventInterface, {
7060 data: 0
7061});
7062
7063var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface);
7064/**
7065 * @interface Event
7066 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
7067 * /#events-inputevents
7068 */
7069// Happens to share the same list for now.
7070
7071var SyntheticInputEvent = SyntheticCompositionEvent;
7072/**
7073 * Normalization of deprecated HTML5 `key` values
7074 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
7075 */
7076
7077var normalizeKey = {
7078 Esc: 'Escape',
7079 Spacebar: ' ',
7080 Left: 'ArrowLeft',
7081 Up: 'ArrowUp',
7082 Right: 'ArrowRight',
7083 Down: 'ArrowDown',
7084 Del: 'Delete',
7085 Win: 'OS',
7086 Menu: 'ContextMenu',
7087 Apps: 'ContextMenu',
7088 Scroll: 'ScrollLock',
7089 MozPrintableKey: 'Unidentified'
7090};
7091/**
7092 * Translation from legacy `keyCode` to HTML5 `key`
7093 * Only special keys supported, all others depend on keyboard layout or browser
7094 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
7095 */
7096
7097var translateToKey = {
7098 '8': 'Backspace',
7099 '9': 'Tab',
7100 '12': 'Clear',
7101 '13': 'Enter',
7102 '16': 'Shift',
7103 '17': 'Control',
7104 '18': 'Alt',
7105 '19': 'Pause',
7106 '20': 'CapsLock',
7107 '27': 'Escape',
7108 '32': ' ',
7109 '33': 'PageUp',
7110 '34': 'PageDown',
7111 '35': 'End',
7112 '36': 'Home',
7113 '37': 'ArrowLeft',
7114 '38': 'ArrowUp',
7115 '39': 'ArrowRight',
7116 '40': 'ArrowDown',
7117 '45': 'Insert',
7118 '46': 'Delete',
7119 '112': 'F1',
7120 '113': 'F2',
7121 '114': 'F3',
7122 '115': 'F4',
7123 '116': 'F5',
7124 '117': 'F6',
7125 '118': 'F7',
7126 '119': 'F8',
7127 '120': 'F9',
7128 '121': 'F10',
7129 '122': 'F11',
7130 '123': 'F12',
7131 '144': 'NumLock',
7132 '145': 'ScrollLock',
7133 '224': 'Meta'
7134};
7135/**
7136 * @param {object} nativeEvent Native browser event.
7137 * @return {string} Normalized `key` property.
7138 */
7139
7140function getEventKey(nativeEvent) {
7141 if (nativeEvent.key) {
7142 // Normalize inconsistent values reported by browsers due to
7143 // implementations of a working draft specification.
7144 // FireFox implements `key` but returns `MozPrintableKey` for all
7145 // printable characters (normalized to `Unidentified`), ignore it.
7146 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
7147
7148 if (key !== 'Unidentified') {
7149 return key;
7150 }
7151 } // Browser does not implement `key`, polyfill as much of it as we can.
7152
7153
7154 if (nativeEvent.type === 'keypress') {
7155 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
7156 // thus be captured by `keypress`, no other non-printable key should.
7157
7158 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
7159 }
7160
7161 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
7162 // While user keyboard layout determines the actual meaning of each
7163 // `keyCode` value, almost all function keys have a universal value.
7164 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
7165 }
7166
7167 return '';
7168}
7169/**
7170 * Translation from modifier key to the associated property in the event.
7171 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
7172 */
7173
7174
7175var modifierKeyToProp = {
7176 Alt: 'altKey',
7177 Control: 'ctrlKey',
7178 Meta: 'metaKey',
7179 Shift: 'shiftKey'
7180}; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
7181// getModifierState. If getModifierState is not supported, we map it to a set of
7182// modifier keys exposed by the event. In this case, Lock-keys are not supported.
7183
7184function modifierStateGetter(keyArg) {
7185 var syntheticEvent = this;
7186 var nativeEvent = syntheticEvent.nativeEvent;
7187
7188 if (nativeEvent.getModifierState) {
7189 return nativeEvent.getModifierState(keyArg);
7190 }
7191
7192 var keyProp = modifierKeyToProp[keyArg];
7193 return keyProp ? !!nativeEvent[keyProp] : false;
7194}
7195
7196function getEventModifierState(nativeEvent) {
7197 return modifierStateGetter;
7198}
7199/**
7200 * @interface KeyboardEvent
7201 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7202 */
7203
7204
7205var KeyboardEventInterface = assign({}, UIEventInterface, {
7206 key: getEventKey,
7207 code: 0,
7208 location: 0,
7209 ctrlKey: 0,
7210 shiftKey: 0,
7211 altKey: 0,
7212 metaKey: 0,
7213 repeat: 0,
7214 locale: 0,
7215 getModifierState: getEventModifierState,
7216 // Legacy Interface
7217 charCode: function (event) {
7218 // `charCode` is the result of a KeyPress event and represents the value of
7219 // the actual printable character.
7220 // KeyPress is deprecated, but its replacement is not yet final and not
7221 // implemented in any major browser. Only KeyPress has charCode.
7222 if (event.type === 'keypress') {
7223 return getEventCharCode(event);
7224 }
7225
7226 return 0;
7227 },
7228 keyCode: function (event) {
7229 // `keyCode` is the result of a KeyDown/Up event and represents the value of
7230 // physical keyboard key.
7231 // The actual meaning of the value depends on the users' keyboard layout
7232 // which cannot be detected. Assuming that it is a US keyboard layout
7233 // provides a surprisingly accurate mapping for US and European users.
7234 // Due to this, it is left to the user to implement at this time.
7235 if (event.type === 'keydown' || event.type === 'keyup') {
7236 return event.keyCode;
7237 }
7238
7239 return 0;
7240 },
7241 which: function (event) {
7242 // `which` is an alias for either `keyCode` or `charCode` depending on the
7243 // type of the event.
7244 if (event.type === 'keypress') {
7245 return getEventCharCode(event);
7246 }
7247
7248 if (event.type === 'keydown' || event.type === 'keyup') {
7249 return event.keyCode;
7250 }
7251
7252 return 0;
7253 }
7254});
7255
7256var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface);
7257/**
7258 * @interface PointerEvent
7259 * @see http://www.w3.org/TR/pointerevents/
7260 */
7261
7262var PointerEventInterface = assign({}, MouseEventInterface, {
7263 pointerId: 0,
7264 width: 0,
7265 height: 0,
7266 pressure: 0,
7267 tangentialPressure: 0,
7268 tiltX: 0,
7269 tiltY: 0,
7270 twist: 0,
7271 pointerType: 0,
7272 isPrimary: 0
7273});
7274
7275var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface);
7276/**
7277 * @interface TouchEvent
7278 * @see http://www.w3.org/TR/touch-events/
7279 */
7280
7281var TouchEventInterface = assign({}, UIEventInterface, {
7282 touches: 0,
7283 targetTouches: 0,
7284 changedTouches: 0,
7285 altKey: 0,
7286 metaKey: 0,
7287 ctrlKey: 0,
7288 shiftKey: 0,
7289 getModifierState: getEventModifierState
7290});
7291
7292var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface);
7293/**
7294 * @interface Event
7295 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
7296 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
7297 */
7298
7299var TransitionEventInterface = assign({}, EventInterface, {
7300 propertyName: 0,
7301 elapsedTime: 0,
7302 pseudoElement: 0
7303});
7304
7305var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface);
7306/**
7307 * @interface WheelEvent
7308 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7309 */
7310
7311var WheelEventInterface = assign({}, MouseEventInterface, {
7312 deltaX: function (event) {
7313 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
7314 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
7315 },
7316 deltaY: function (event) {
7317 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
7318 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
7319 'wheelDelta' in event ? -event.wheelDelta : 0;
7320 },
7321 deltaZ: 0,
7322 // Browsers without "deltaMode" is reporting in raw wheel delta where one
7323 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
7324 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
7325 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
7326 deltaMode: 0
7327});
7328
7329var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface);
7330
7331var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
7332
7333var START_KEYCODE = 229;
7334var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
7335var documentMode = null;
7336
7337if (canUseDOM && 'documentMode' in document) {
7338 documentMode = document.documentMode;
7339} // Webkit offers a very useful `textInput` event that can be used to
7340// directly represent `beforeInput`. The IE `textinput` event is not as
7341// useful, so we don't use it.
7342
7343
7344var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
7345// by the native compositionend event may be incorrect. Japanese ideographic
7346// spaces, for instance (\u3000) are not recorded correctly.
7347
7348var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
7349var SPACEBAR_CODE = 32;
7350var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
7351
7352function registerEvents() {
7353 registerTwoPhaseEvent('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']);
7354 registerTwoPhaseEvent('onCompositionEnd', ['compositionend', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7355 registerTwoPhaseEvent('onCompositionStart', ['compositionstart', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7356 registerTwoPhaseEvent('onCompositionUpdate', ['compositionupdate', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7357} // Track whether we've ever handled a keypress on the space key.
7358
7359
7360var hasSpaceKeypress = false;
7361/**
7362 * Return whether a native keypress event is assumed to be a command.
7363 * This is required because Firefox fires `keypress` events for key commands
7364 * (cut, copy, select-all, etc.) even though no character is inserted.
7365 */
7366
7367function isKeypressCommand(nativeEvent) {
7368 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
7369 !(nativeEvent.ctrlKey && nativeEvent.altKey);
7370}
7371/**
7372 * Translate native top level events into event types.
7373 */
7374
7375
7376function getCompositionEventType(domEventName) {
7377 switch (domEventName) {
7378 case 'compositionstart':
7379 return 'onCompositionStart';
7380
7381 case 'compositionend':
7382 return 'onCompositionEnd';
7383
7384 case 'compositionupdate':
7385 return 'onCompositionUpdate';
7386 }
7387}
7388/**
7389 * Does our fallback best-guess model think this event signifies that
7390 * composition has begun?
7391 */
7392
7393
7394function isFallbackCompositionStart(domEventName, nativeEvent) {
7395 return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE;
7396}
7397/**
7398 * Does our fallback mode think that this event is the end of composition?
7399 */
7400
7401
7402function isFallbackCompositionEnd(domEventName, nativeEvent) {
7403 switch (domEventName) {
7404 case 'keyup':
7405 // Command keys insert or clear IME input.
7406 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
7407
7408 case 'keydown':
7409 // Expect IME keyCode on each keydown. If we get any other
7410 // code we must have exited earlier.
7411 return nativeEvent.keyCode !== START_KEYCODE;
7412
7413 case 'keypress':
7414 case 'mousedown':
7415 case 'focusout':
7416 // Events are not possible without cancelling IME.
7417 return true;
7418
7419 default:
7420 return false;
7421 }
7422}
7423/**
7424 * Google Input Tools provides composition data via a CustomEvent,
7425 * with the `data` property populated in the `detail` object. If this
7426 * is available on the event object, use it. If not, this is a plain
7427 * composition event and we have nothing special to extract.
7428 *
7429 * @param {object} nativeEvent
7430 * @return {?string}
7431 */
7432
7433
7434function getDataFromCustomEvent(nativeEvent) {
7435 var detail = nativeEvent.detail;
7436
7437 if (typeof detail === 'object' && 'data' in detail) {
7438 return detail.data;
7439 }
7440
7441 return null;
7442}
7443/**
7444 * Check if a composition event was triggered by Korean IME.
7445 * Our fallback mode does not work well with IE's Korean IME,
7446 * so just use native composition events when Korean IME is used.
7447 * Although CompositionEvent.locale property is deprecated,
7448 * it is available in IE, where our fallback mode is enabled.
7449 *
7450 * @param {object} nativeEvent
7451 * @return {boolean}
7452 */
7453
7454
7455function isUsingKoreanIME(nativeEvent) {
7456 return nativeEvent.locale === 'ko';
7457} // Track the current IME composition status, if any.
7458
7459
7460var isComposing = false;
7461/**
7462 * @return {?object} A SyntheticCompositionEvent.
7463 */
7464
7465function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
7466 var eventType;
7467 var fallbackData;
7468
7469 if (canUseCompositionEvent) {
7470 eventType = getCompositionEventType(domEventName);
7471 } else if (!isComposing) {
7472 if (isFallbackCompositionStart(domEventName, nativeEvent)) {
7473 eventType = 'onCompositionStart';
7474 }
7475 } else if (isFallbackCompositionEnd(domEventName, nativeEvent)) {
7476 eventType = 'onCompositionEnd';
7477 }
7478
7479 if (!eventType) {
7480 return null;
7481 }
7482
7483 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
7484 // The current composition is stored statically and must not be
7485 // overwritten while composition continues.
7486 if (!isComposing && eventType === 'onCompositionStart') {
7487 isComposing = initialize(nativeEventTarget);
7488 } else if (eventType === 'onCompositionEnd') {
7489 if (isComposing) {
7490 fallbackData = getData();
7491 }
7492 }
7493 }
7494
7495 var listeners = accumulateTwoPhaseListeners(targetInst, eventType);
7496
7497 if (listeners.length > 0) {
7498 var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget);
7499 dispatchQueue.push({
7500 event: event,
7501 listeners: listeners
7502 });
7503
7504 if (fallbackData) {
7505 // Inject data generated from fallback path into the synthetic event.
7506 // This matches the property of native CompositionEventInterface.
7507 event.data = fallbackData;
7508 } else {
7509 var customData = getDataFromCustomEvent(nativeEvent);
7510
7511 if (customData !== null) {
7512 event.data = customData;
7513 }
7514 }
7515 }
7516}
7517
7518function getNativeBeforeInputChars(domEventName, nativeEvent) {
7519 switch (domEventName) {
7520 case 'compositionend':
7521 return getDataFromCustomEvent(nativeEvent);
7522
7523 case 'keypress':
7524 /**
7525 * If native `textInput` events are available, our goal is to make
7526 * use of them. However, there is a special case: the spacebar key.
7527 * In Webkit, preventing default on a spacebar `textInput` event
7528 * cancels character insertion, but it *also* causes the browser
7529 * to fall back to its default spacebar behavior of scrolling the
7530 * page.
7531 *
7532 * Tracking at:
7533 * https://code.google.com/p/chromium/issues/detail?id=355103
7534 *
7535 * To avoid this issue, use the keypress event as if no `textInput`
7536 * event is available.
7537 */
7538 var which = nativeEvent.which;
7539
7540 if (which !== SPACEBAR_CODE) {
7541 return null;
7542 }
7543
7544 hasSpaceKeypress = true;
7545 return SPACEBAR_CHAR;
7546
7547 case 'textInput':
7548 // Record the characters to be added to the DOM.
7549 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
7550 // it at the keypress level and bail immediately. Android Chrome
7551 // doesn't give us keycodes, so we need to ignore it.
7552
7553 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
7554 return null;
7555 }
7556
7557 return chars;
7558
7559 default:
7560 // For other native event types, do nothing.
7561 return null;
7562 }
7563}
7564/**
7565 * For browsers that do not provide the `textInput` event, extract the
7566 * appropriate string to use for SyntheticInputEvent.
7567 */
7568
7569
7570function getFallbackBeforeInputChars(domEventName, nativeEvent) {
7571 // If we are currently composing (IME) and using a fallback to do so,
7572 // try to extract the composed characters from the fallback object.
7573 // If composition event is available, we extract a string only at
7574 // compositionevent, otherwise extract it at fallback events.
7575 if (isComposing) {
7576 if (domEventName === 'compositionend' || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) {
7577 var chars = getData();
7578 reset();
7579 isComposing = false;
7580 return chars;
7581 }
7582
7583 return null;
7584 }
7585
7586 switch (domEventName) {
7587 case 'paste':
7588 // If a paste event occurs after a keypress, throw out the input
7589 // chars. Paste events should not lead to BeforeInput events.
7590 return null;
7591
7592 case 'keypress':
7593 /**
7594 * As of v27, Firefox may fire keypress events even when no character
7595 * will be inserted. A few possibilities:
7596 *
7597 * - `which` is `0`. Arrow keys, Esc key, etc.
7598 *
7599 * - `which` is the pressed key code, but no char is available.
7600 * Ex: 'AltGr + d` in Polish. There is no modified character for
7601 * this key combination and no character is inserted into the
7602 * document, but FF fires the keypress for char code `100` anyway.
7603 * No `input` event will occur.
7604 *
7605 * - `which` is the pressed key code, but a command combination is
7606 * being used. Ex: `Cmd+C`. No character is inserted, and no
7607 * `input` event will occur.
7608 */
7609 if (!isKeypressCommand(nativeEvent)) {
7610 // IE fires the `keypress` event when a user types an emoji via
7611 // Touch keyboard of Windows. In such a case, the `char` property
7612 // holds an emoji character like `\uD83D\uDE0A`. Because its length
7613 // is 2, the property `which` does not represent an emoji correctly.
7614 // In such a case, we directly return the `char` property instead of
7615 // using `which`.
7616 if (nativeEvent.char && nativeEvent.char.length > 1) {
7617 return nativeEvent.char;
7618 } else if (nativeEvent.which) {
7619 return String.fromCharCode(nativeEvent.which);
7620 }
7621 }
7622
7623 return null;
7624
7625 case 'compositionend':
7626 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
7627
7628 default:
7629 return null;
7630 }
7631}
7632/**
7633 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
7634 * `textInput` or fallback behavior.
7635 *
7636 * @return {?object} A SyntheticInputEvent.
7637 */
7638
7639
7640function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
7641 var chars;
7642
7643 if (canUseTextInputEvent) {
7644 chars = getNativeBeforeInputChars(domEventName, nativeEvent);
7645 } else {
7646 chars = getFallbackBeforeInputChars(domEventName, nativeEvent);
7647 } // If no characters are being inserted, no BeforeInput event should
7648 // be fired.
7649
7650
7651 if (!chars) {
7652 return null;
7653 }
7654
7655 var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput');
7656
7657 if (listeners.length > 0) {
7658 var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget);
7659 dispatchQueue.push({
7660 event: event,
7661 listeners: listeners
7662 });
7663 event.data = chars;
7664 }
7665}
7666/**
7667 * Create an `onBeforeInput` event to match
7668 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
7669 *
7670 * This event plugin is based on the native `textInput` event
7671 * available in Chrome, Safari, Opera, and IE. This event fires after
7672 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
7673 *
7674 * `beforeInput` is spec'd but not implemented in any browsers, and
7675 * the `input` event does not provide any useful information about what has
7676 * actually been added, contrary to the spec. Thus, `textInput` is the best
7677 * available event to identify the characters that have actually been inserted
7678 * into the target node.
7679 *
7680 * This plugin is also responsible for emitting `composition` events, thus
7681 * allowing us to share composition fallback code for both `beforeInput` and
7682 * `composition` event types.
7683 */
7684
7685
7686function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7687 extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7688 extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7689}
7690
7691/**
7692 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
7693 */
7694var supportedInputTypes = {
7695 color: true,
7696 date: true,
7697 datetime: true,
7698 'datetime-local': true,
7699 email: true,
7700 month: true,
7701 number: true,
7702 password: true,
7703 range: true,
7704 search: true,
7705 tel: true,
7706 text: true,
7707 time: true,
7708 url: true,
7709 week: true
7710};
7711
7712function isTextInputElement(elem) {
7713 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7714
7715 if (nodeName === 'input') {
7716 return !!supportedInputTypes[elem.type];
7717 }
7718
7719 if (nodeName === 'textarea') {
7720 return true;
7721 }
7722
7723 return false;
7724}
7725
7726/**
7727 * Checks if an event is supported in the current execution environment.
7728 *
7729 * NOTE: This will not work correctly for non-generic events such as `change`,
7730 * `reset`, `load`, `error`, and `select`.
7731 *
7732 * Borrows from Modernizr.
7733 *
7734 * @param {string} eventNameSuffix Event name, e.g. "click".
7735 * @return {boolean} True if the event is supported.
7736 * @internal
7737 * @license Modernizr 3.0.0pre (Custom Build) | MIT
7738 */
7739
7740function isEventSupported(eventNameSuffix) {
7741 if (!canUseDOM) {
7742 return false;
7743 }
7744
7745 var eventName = 'on' + eventNameSuffix;
7746 var isSupported = (eventName in document);
7747
7748 if (!isSupported) {
7749 var element = document.createElement('div');
7750 element.setAttribute(eventName, 'return;');
7751 isSupported = typeof element[eventName] === 'function';
7752 }
7753
7754 return isSupported;
7755}
7756
7757function registerEvents$1() {
7758 registerTwoPhaseEvent('onChange', ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']);
7759}
7760
7761function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) {
7762 // Flag this event loop as needing state restore.
7763 enqueueStateRestore(target);
7764 var listeners = accumulateTwoPhaseListeners(inst, 'onChange');
7765
7766 if (listeners.length > 0) {
7767 var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target);
7768 dispatchQueue.push({
7769 event: event,
7770 listeners: listeners
7771 });
7772 }
7773}
7774/**
7775 * For IE shims
7776 */
7777
7778
7779var activeElement = null;
7780var activeElementInst = null;
7781/**
7782 * SECTION: handle `change` event
7783 */
7784
7785function shouldUseChangeEvent(elem) {
7786 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
7787 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
7788}
7789
7790function manualDispatchChangeEvent(nativeEvent) {
7791 var dispatchQueue = [];
7792 createAndAccumulateChangeEvent(dispatchQueue, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
7793 // other events and have it go through ReactBrowserEventEmitter. Since it
7794 // doesn't, we manually listen for the events and so we have to enqueue and
7795 // process the abstract event manually.
7796 //
7797 // Batching is necessary here in order to ensure that all event handlers run
7798 // before the next rerender (including event handlers attached to ancestor
7799 // elements instead of directly on the input). Without this, controlled
7800 // components don't work properly in conjunction with event bubbling because
7801 // the component is rerendered and the value reverted before all the event
7802 // handlers can run. See https://github.com/facebook/react/issues/708.
7803
7804 batchedUpdates(runEventInBatch, dispatchQueue);
7805}
7806
7807function runEventInBatch(dispatchQueue) {
7808 processDispatchQueue(dispatchQueue, 0);
7809}
7810
7811function getInstIfValueChanged(targetInst) {
7812 var targetNode = getNodeFromInstance(targetInst);
7813
7814 if (updateValueIfChanged(targetNode)) {
7815 return targetInst;
7816 }
7817}
7818
7819function getTargetInstForChangeEvent(domEventName, targetInst) {
7820 if (domEventName === 'change') {
7821 return targetInst;
7822 }
7823}
7824/**
7825 * SECTION: handle `input` event
7826 */
7827
7828
7829var isInputEventSupported = false;
7830
7831if (canUseDOM) {
7832 // IE9 claims to support the input event but fails to trigger it when
7833 // deleting text, so we ignore its input events.
7834 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
7835}
7836/**
7837 * (For IE <=9) Starts tracking propertychange events on the passed-in element
7838 * and override the value property so that we can distinguish user events from
7839 * value changes in JS.
7840 */
7841
7842
7843function startWatchingForValueChange(target, targetInst) {
7844 activeElement = target;
7845 activeElementInst = targetInst;
7846 activeElement.attachEvent('onpropertychange', handlePropertyChange);
7847}
7848/**
7849 * (For IE <=9) Removes the event listeners from the currently-tracked element,
7850 * if any exists.
7851 */
7852
7853
7854function stopWatchingForValueChange() {
7855 if (!activeElement) {
7856 return;
7857 }
7858
7859 activeElement.detachEvent('onpropertychange', handlePropertyChange);
7860 activeElement = null;
7861 activeElementInst = null;
7862}
7863/**
7864 * (For IE <=9) Handles a propertychange event, sending a `change` event if
7865 * the value of the active element has changed.
7866 */
7867
7868
7869function handlePropertyChange(nativeEvent) {
7870 if (nativeEvent.propertyName !== 'value') {
7871 return;
7872 }
7873
7874 if (getInstIfValueChanged(activeElementInst)) {
7875 manualDispatchChangeEvent(nativeEvent);
7876 }
7877}
7878
7879function handleEventsForInputEventPolyfill(domEventName, target, targetInst) {
7880 if (domEventName === 'focusin') {
7881 // In IE9, propertychange fires for most input events but is buggy and
7882 // doesn't fire when text is deleted, but conveniently, selectionchange
7883 // appears to fire in all of the remaining cases so we catch those and
7884 // forward the event if the value has changed
7885 // In either case, we don't want to call the event handler if the value
7886 // is changed from JS so we redefine a setter for `.value` that updates
7887 // our activeElementValue variable, allowing us to ignore those changes
7888 //
7889 // stopWatching() should be a noop here but we call it just in case we
7890 // missed a blur event somehow.
7891 stopWatchingForValueChange();
7892 startWatchingForValueChange(target, targetInst);
7893 } else if (domEventName === 'focusout') {
7894 stopWatchingForValueChange();
7895 }
7896} // For IE8 and IE9.
7897
7898
7899function getTargetInstForInputEventPolyfill(domEventName, targetInst) {
7900 if (domEventName === 'selectionchange' || domEventName === 'keyup' || domEventName === 'keydown') {
7901 // On the selectionchange event, the target is just document which isn't
7902 // helpful for us so just check activeElement instead.
7903 //
7904 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
7905 // propertychange on the first input event after setting `value` from a
7906 // script and fires only keydown, keypress, keyup. Catching keyup usually
7907 // gets it and catching keydown lets us fire an event for the first
7908 // keystroke if user does a key repeat (it'll be a little delayed: right
7909 // before the second keystroke). Other input methods (e.g., paste) seem to
7910 // fire selectionchange normally.
7911 return getInstIfValueChanged(activeElementInst);
7912 }
7913}
7914/**
7915 * SECTION: handle `click` event
7916 */
7917
7918
7919function shouldUseClickEvent(elem) {
7920 // Use the `click` event to detect changes to checkbox and radio inputs.
7921 // This approach works across all browsers, whereas `change` does not fire
7922 // until `blur` in IE8.
7923 var nodeName = elem.nodeName;
7924 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
7925}
7926
7927function getTargetInstForClickEvent(domEventName, targetInst) {
7928 if (domEventName === 'click') {
7929 return getInstIfValueChanged(targetInst);
7930 }
7931}
7932
7933function getTargetInstForInputOrChangeEvent(domEventName, targetInst) {
7934 if (domEventName === 'input' || domEventName === 'change') {
7935 return getInstIfValueChanged(targetInst);
7936 }
7937}
7938
7939function handleControlledInputBlur(node) {
7940 var state = node._wrapperState;
7941
7942 if (!state || !state.controlled || node.type !== 'number') {
7943 return;
7944 }
7945
7946 {
7947 // If controlled, assign the value attribute to the current value on blur
7948 setDefaultValue(node, 'number', node.value);
7949 }
7950}
7951/**
7952 * This plugin creates an `onChange` event that normalizes change events
7953 * across form elements. This event fires at a time when it's possible to
7954 * change the element's value without seeing a flicker.
7955 *
7956 * Supported elements are:
7957 * - input (see `isTextInputElement`)
7958 * - textarea
7959 * - select
7960 */
7961
7962
7963function extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7964 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
7965 var getTargetInstFunc, handleEventFunc;
7966
7967 if (shouldUseChangeEvent(targetNode)) {
7968 getTargetInstFunc = getTargetInstForChangeEvent;
7969 } else if (isTextInputElement(targetNode)) {
7970 if (isInputEventSupported) {
7971 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
7972 } else {
7973 getTargetInstFunc = getTargetInstForInputEventPolyfill;
7974 handleEventFunc = handleEventsForInputEventPolyfill;
7975 }
7976 } else if (shouldUseClickEvent(targetNode)) {
7977 getTargetInstFunc = getTargetInstForClickEvent;
7978 }
7979
7980 if (getTargetInstFunc) {
7981 var inst = getTargetInstFunc(domEventName, targetInst);
7982
7983 if (inst) {
7984 createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget);
7985 return;
7986 }
7987 }
7988
7989 if (handleEventFunc) {
7990 handleEventFunc(domEventName, targetNode, targetInst);
7991 } // When blurring, set the value attribute for number inputs
7992
7993
7994 if (domEventName === 'focusout') {
7995 handleControlledInputBlur(targetNode);
7996 }
7997}
7998
7999function registerEvents$2() {
8000 registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']);
8001 registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']);
8002 registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']);
8003 registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']);
8004}
8005/**
8006 * For almost every interaction we care about, there will be both a top-level
8007 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
8008 * we do not extract duplicate events. However, moving the mouse into the
8009 * browser from outside will not fire a `mouseout` event. In this case, we use
8010 * the `mouseover` top-level event.
8011 */
8012
8013
8014function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8015 var isOverEvent = domEventName === 'mouseover' || domEventName === 'pointerover';
8016 var isOutEvent = domEventName === 'mouseout' || domEventName === 'pointerout';
8017
8018 if (isOverEvent && !isReplayingEvent(nativeEvent)) {
8019 // If this is an over event with a target, we might have already dispatched
8020 // the event in the out event of the other target. If this is replayed,
8021 // then it's because we couldn't dispatch against this target previously
8022 // so we have to do it now instead.
8023 var related = nativeEvent.relatedTarget || nativeEvent.fromElement;
8024
8025 if (related) {
8026 // If the related node is managed by React, we can assume that we have
8027 // already dispatched the corresponding events during its mouseout.
8028 if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) {
8029 return;
8030 }
8031 }
8032 }
8033
8034 if (!isOutEvent && !isOverEvent) {
8035 // Must not be a mouse or pointer in or out - ignoring.
8036 return;
8037 }
8038
8039 var win; // TODO: why is this nullable in the types but we read from it?
8040
8041 if (nativeEventTarget.window === nativeEventTarget) {
8042 // `nativeEventTarget` is probably a window object.
8043 win = nativeEventTarget;
8044 } else {
8045 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
8046 var doc = nativeEventTarget.ownerDocument;
8047
8048 if (doc) {
8049 win = doc.defaultView || doc.parentWindow;
8050 } else {
8051 win = window;
8052 }
8053 }
8054
8055 var from;
8056 var to;
8057
8058 if (isOutEvent) {
8059 var _related = nativeEvent.relatedTarget || nativeEvent.toElement;
8060
8061 from = targetInst;
8062 to = _related ? getClosestInstanceFromNode(_related) : null;
8063
8064 if (to !== null) {
8065 var nearestMounted = getNearestMountedFiber(to);
8066
8067 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
8068 to = null;
8069 }
8070 }
8071 } else {
8072 // Moving to a node from outside the window.
8073 from = null;
8074 to = targetInst;
8075 }
8076
8077 if (from === to) {
8078 // Nothing pertains to our managed components.
8079 return;
8080 }
8081
8082 var SyntheticEventCtor = SyntheticMouseEvent;
8083 var leaveEventType = 'onMouseLeave';
8084 var enterEventType = 'onMouseEnter';
8085 var eventTypePrefix = 'mouse';
8086
8087 if (domEventName === 'pointerout' || domEventName === 'pointerover') {
8088 SyntheticEventCtor = SyntheticPointerEvent;
8089 leaveEventType = 'onPointerLeave';
8090 enterEventType = 'onPointerEnter';
8091 eventTypePrefix = 'pointer';
8092 }
8093
8094 var fromNode = from == null ? win : getNodeFromInstance(from);
8095 var toNode = to == null ? win : getNodeFromInstance(to);
8096 var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget);
8097 leave.target = fromNode;
8098 leave.relatedTarget = toNode;
8099 var enter = null; // We should only process this nativeEvent if we are processing
8100 // the first ancestor. Next time, we will ignore the event.
8101
8102 var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
8103
8104 if (nativeTargetInst === targetInst) {
8105 var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget);
8106 enterEvent.target = toNode;
8107 enterEvent.relatedTarget = fromNode;
8108 enter = enterEvent;
8109 }
8110
8111 accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to);
8112}
8113
8114/**
8115 * inlined Object.is polyfill to avoid requiring consumers ship their own
8116 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
8117 */
8118function is(x, y) {
8119 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
8120 ;
8121}
8122
8123var objectIs = typeof Object.is === 'function' ? Object.is : is;
8124
8125/**
8126 * Performs equality by iterating through keys on an object and returning false
8127 * when any key has values which are not strictly equal between the arguments.
8128 * Returns true when the values of all keys are strictly equal.
8129 */
8130
8131function shallowEqual(objA, objB) {
8132 if (objectIs(objA, objB)) {
8133 return true;
8134 }
8135
8136 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
8137 return false;
8138 }
8139
8140 var keysA = Object.keys(objA);
8141 var keysB = Object.keys(objB);
8142
8143 if (keysA.length !== keysB.length) {
8144 return false;
8145 } // Test for A's keys different from B.
8146
8147
8148 for (var i = 0; i < keysA.length; i++) {
8149 var currentKey = keysA[i];
8150
8151 if (!hasOwnProperty.call(objB, currentKey) || !objectIs(objA[currentKey], objB[currentKey])) {
8152 return false;
8153 }
8154 }
8155
8156 return true;
8157}
8158
8159/**
8160 * Given any node return the first leaf node without children.
8161 *
8162 * @param {DOMElement|DOMTextNode} node
8163 * @return {DOMElement|DOMTextNode}
8164 */
8165
8166function getLeafNode(node) {
8167 while (node && node.firstChild) {
8168 node = node.firstChild;
8169 }
8170
8171 return node;
8172}
8173/**
8174 * Get the next sibling within a container. This will walk up the
8175 * DOM if a node's siblings have been exhausted.
8176 *
8177 * @param {DOMElement|DOMTextNode} node
8178 * @return {?DOMElement|DOMTextNode}
8179 */
8180
8181
8182function getSiblingNode(node) {
8183 while (node) {
8184 if (node.nextSibling) {
8185 return node.nextSibling;
8186 }
8187
8188 node = node.parentNode;
8189 }
8190}
8191/**
8192 * Get object describing the nodes which contain characters at offset.
8193 *
8194 * @param {DOMElement|DOMTextNode} root
8195 * @param {number} offset
8196 * @return {?object}
8197 */
8198
8199
8200function getNodeForCharacterOffset(root, offset) {
8201 var node = getLeafNode(root);
8202 var nodeStart = 0;
8203 var nodeEnd = 0;
8204
8205 while (node) {
8206 if (node.nodeType === TEXT_NODE) {
8207 nodeEnd = nodeStart + node.textContent.length;
8208
8209 if (nodeStart <= offset && nodeEnd >= offset) {
8210 return {
8211 node: node,
8212 offset: offset - nodeStart
8213 };
8214 }
8215
8216 nodeStart = nodeEnd;
8217 }
8218
8219 node = getLeafNode(getSiblingNode(node));
8220 }
8221}
8222
8223/**
8224 * @param {DOMElement} outerNode
8225 * @return {?object}
8226 */
8227
8228function getOffsets(outerNode) {
8229 var ownerDocument = outerNode.ownerDocument;
8230 var win = ownerDocument && ownerDocument.defaultView || window;
8231 var selection = win.getSelection && win.getSelection();
8232
8233 if (!selection || selection.rangeCount === 0) {
8234 return null;
8235 }
8236
8237 var anchorNode = selection.anchorNode,
8238 anchorOffset = selection.anchorOffset,
8239 focusNode = selection.focusNode,
8240 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
8241 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
8242 // expose properties, triggering a "Permission denied error" if any of its
8243 // properties are accessed. The only seemingly possible way to avoid erroring
8244 // is to access a property that typically works for non-anonymous divs and
8245 // catch any error that may otherwise arise. See
8246 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
8247
8248 try {
8249 /* eslint-disable no-unused-expressions */
8250 anchorNode.nodeType;
8251 focusNode.nodeType;
8252 /* eslint-enable no-unused-expressions */
8253 } catch (e) {
8254 return null;
8255 }
8256
8257 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
8258}
8259/**
8260 * Returns {start, end} where `start` is the character/codepoint index of
8261 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
8262 * `end` is the index of (focusNode, focusOffset).
8263 *
8264 * Returns null if you pass in garbage input but we should probably just crash.
8265 *
8266 * Exported only for testing.
8267 */
8268
8269function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
8270 var length = 0;
8271 var start = -1;
8272 var end = -1;
8273 var indexWithinAnchor = 0;
8274 var indexWithinFocus = 0;
8275 var node = outerNode;
8276 var parentNode = null;
8277
8278 outer: while (true) {
8279 var next = null;
8280
8281 while (true) {
8282 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
8283 start = length + anchorOffset;
8284 }
8285
8286 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
8287 end = length + focusOffset;
8288 }
8289
8290 if (node.nodeType === TEXT_NODE) {
8291 length += node.nodeValue.length;
8292 }
8293
8294 if ((next = node.firstChild) === null) {
8295 break;
8296 } // Moving from `node` to its first child `next`.
8297
8298
8299 parentNode = node;
8300 node = next;
8301 }
8302
8303 while (true) {
8304 if (node === outerNode) {
8305 // If `outerNode` has children, this is always the second time visiting
8306 // it. If it has no children, this is still the first loop, and the only
8307 // valid selection is anchorNode and focusNode both equal to this node
8308 // and both offsets 0, in which case we will have handled above.
8309 break outer;
8310 }
8311
8312 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
8313 start = length;
8314 }
8315
8316 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
8317 end = length;
8318 }
8319
8320 if ((next = node.nextSibling) !== null) {
8321 break;
8322 }
8323
8324 node = parentNode;
8325 parentNode = node.parentNode;
8326 } // Moving from `node` to its next sibling `next`.
8327
8328
8329 node = next;
8330 }
8331
8332 if (start === -1 || end === -1) {
8333 // This should never happen. (Would happen if the anchor/focus nodes aren't
8334 // actually inside the passed-in node.)
8335 return null;
8336 }
8337
8338 return {
8339 start: start,
8340 end: end
8341 };
8342}
8343/**
8344 * In modern non-IE browsers, we can support both forward and backward
8345 * selections.
8346 *
8347 * Note: IE10+ supports the Selection object, but it does not support
8348 * the `extend` method, which means that even in modern IE, it's not possible
8349 * to programmatically create a backward selection. Thus, for all IE
8350 * versions, we use the old IE API to create our selections.
8351 *
8352 * @param {DOMElement|DOMTextNode} node
8353 * @param {object} offsets
8354 */
8355
8356function setOffsets(node, offsets) {
8357 var doc = node.ownerDocument || document;
8358 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
8359 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
8360 // fails when pasting 100+ items)
8361
8362 if (!win.getSelection) {
8363 return;
8364 }
8365
8366 var selection = win.getSelection();
8367 var length = node.textContent.length;
8368 var start = Math.min(offsets.start, length);
8369 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
8370 // Flip backward selections, so we can set with a single range.
8371
8372 if (!selection.extend && start > end) {
8373 var temp = end;
8374 end = start;
8375 start = temp;
8376 }
8377
8378 var startMarker = getNodeForCharacterOffset(node, start);
8379 var endMarker = getNodeForCharacterOffset(node, end);
8380
8381 if (startMarker && endMarker) {
8382 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
8383 return;
8384 }
8385
8386 var range = doc.createRange();
8387 range.setStart(startMarker.node, startMarker.offset);
8388 selection.removeAllRanges();
8389
8390 if (start > end) {
8391 selection.addRange(range);
8392 selection.extend(endMarker.node, endMarker.offset);
8393 } else {
8394 range.setEnd(endMarker.node, endMarker.offset);
8395 selection.addRange(range);
8396 }
8397 }
8398}
8399
8400function isTextNode(node) {
8401 return node && node.nodeType === TEXT_NODE;
8402}
8403
8404function containsNode(outerNode, innerNode) {
8405 if (!outerNode || !innerNode) {
8406 return false;
8407 } else if (outerNode === innerNode) {
8408 return true;
8409 } else if (isTextNode(outerNode)) {
8410 return false;
8411 } else if (isTextNode(innerNode)) {
8412 return containsNode(outerNode, innerNode.parentNode);
8413 } else if ('contains' in outerNode) {
8414 return outerNode.contains(innerNode);
8415 } else if (outerNode.compareDocumentPosition) {
8416 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
8417 } else {
8418 return false;
8419 }
8420}
8421
8422function isInDocument(node) {
8423 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
8424}
8425
8426function isSameOriginFrame(iframe) {
8427 try {
8428 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
8429 // to throw, e.g. if it has a cross-origin src attribute.
8430 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
8431 // iframe.contentDocument.defaultView;
8432 // A safety way is to access one of the cross origin properties: Window or Location
8433 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
8434 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
8435 return typeof iframe.contentWindow.location.href === 'string';
8436 } catch (err) {
8437 return false;
8438 }
8439}
8440
8441function getActiveElementDeep() {
8442 var win = window;
8443 var element = getActiveElement();
8444
8445 while (element instanceof win.HTMLIFrameElement) {
8446 if (isSameOriginFrame(element)) {
8447 win = element.contentWindow;
8448 } else {
8449 return element;
8450 }
8451
8452 element = getActiveElement(win.document);
8453 }
8454
8455 return element;
8456}
8457/**
8458 * @ReactInputSelection: React input selection module. Based on Selection.js,
8459 * but modified to be suitable for react and has a couple of bug fixes (doesn't
8460 * assume buttons have range selections allowed).
8461 * Input selection module for React.
8462 */
8463
8464/**
8465 * @hasSelectionCapabilities: we get the element types that support selection
8466 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
8467 * and `selectionEnd` rows.
8468 */
8469
8470
8471function hasSelectionCapabilities(elem) {
8472 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
8473 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
8474}
8475function getSelectionInformation() {
8476 var focusedElem = getActiveElementDeep();
8477 return {
8478 focusedElem: focusedElem,
8479 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
8480 };
8481}
8482/**
8483 * @restoreSelection: If any selection information was potentially lost,
8484 * restore it. This is useful when performing operations that could remove dom
8485 * nodes and place them back in, resulting in focus being lost.
8486 */
8487
8488function restoreSelection(priorSelectionInformation) {
8489 var curFocusedElem = getActiveElementDeep();
8490 var priorFocusedElem = priorSelectionInformation.focusedElem;
8491 var priorSelectionRange = priorSelectionInformation.selectionRange;
8492
8493 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
8494 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
8495 setSelection(priorFocusedElem, priorSelectionRange);
8496 } // Focusing a node can change the scroll position, which is undesirable
8497
8498
8499 var ancestors = [];
8500 var ancestor = priorFocusedElem;
8501
8502 while (ancestor = ancestor.parentNode) {
8503 if (ancestor.nodeType === ELEMENT_NODE) {
8504 ancestors.push({
8505 element: ancestor,
8506 left: ancestor.scrollLeft,
8507 top: ancestor.scrollTop
8508 });
8509 }
8510 }
8511
8512 if (typeof priorFocusedElem.focus === 'function') {
8513 priorFocusedElem.focus();
8514 }
8515
8516 for (var i = 0; i < ancestors.length; i++) {
8517 var info = ancestors[i];
8518 info.element.scrollLeft = info.left;
8519 info.element.scrollTop = info.top;
8520 }
8521 }
8522}
8523/**
8524 * @getSelection: Gets the selection bounds of a focused textarea, input or
8525 * contentEditable node.
8526 * -@input: Look up selection bounds of this input
8527 * -@return {start: selectionStart, end: selectionEnd}
8528 */
8529
8530function getSelection(input) {
8531 var selection;
8532
8533 if ('selectionStart' in input) {
8534 // Modern browser with input or textarea.
8535 selection = {
8536 start: input.selectionStart,
8537 end: input.selectionEnd
8538 };
8539 } else {
8540 // Content editable or old IE textarea.
8541 selection = getOffsets(input);
8542 }
8543
8544 return selection || {
8545 start: 0,
8546 end: 0
8547 };
8548}
8549/**
8550 * @setSelection: Sets the selection bounds of a textarea or input and focuses
8551 * the input.
8552 * -@input Set selection bounds of this input or textarea
8553 * -@offsets Object of same form that is returned from get*
8554 */
8555
8556function setSelection(input, offsets) {
8557 var start = offsets.start;
8558 var end = offsets.end;
8559
8560 if (end === undefined) {
8561 end = start;
8562 }
8563
8564 if ('selectionStart' in input) {
8565 input.selectionStart = start;
8566 input.selectionEnd = Math.min(end, input.value.length);
8567 } else {
8568 setOffsets(input, offsets);
8569 }
8570}
8571
8572var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
8573
8574function registerEvents$3() {
8575 registerTwoPhaseEvent('onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']);
8576}
8577
8578var activeElement$1 = null;
8579var activeElementInst$1 = null;
8580var lastSelection = null;
8581var mouseDown = false;
8582/**
8583 * Get an object which is a unique representation of the current selection.
8584 *
8585 * The return value will not be consistent across nodes or browsers, but
8586 * two identical selections on the same node will return identical objects.
8587 */
8588
8589function getSelection$1(node) {
8590 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
8591 return {
8592 start: node.selectionStart,
8593 end: node.selectionEnd
8594 };
8595 } else {
8596 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
8597 var selection = win.getSelection();
8598 return {
8599 anchorNode: selection.anchorNode,
8600 anchorOffset: selection.anchorOffset,
8601 focusNode: selection.focusNode,
8602 focusOffset: selection.focusOffset
8603 };
8604 }
8605}
8606/**
8607 * Get document associated with the event target.
8608 */
8609
8610
8611function getEventTargetDocument(eventTarget) {
8612 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
8613}
8614/**
8615 * Poll selection to see whether it's changed.
8616 *
8617 * @param {object} nativeEvent
8618 * @param {object} nativeEventTarget
8619 * @return {?SyntheticEvent}
8620 */
8621
8622
8623function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
8624 // Ensure we have the right element, and that the user is not dragging a
8625 // selection (this matches native `select` event behavior). In HTML5, select
8626 // fires only on input and textarea thus if there's no focused element we
8627 // won't dispatch.
8628 var doc = getEventTargetDocument(nativeEventTarget);
8629
8630 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
8631 return;
8632 } // Only fire when selection has actually changed.
8633
8634
8635 var currentSelection = getSelection$1(activeElement$1);
8636
8637 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
8638 lastSelection = currentSelection;
8639 var listeners = accumulateTwoPhaseListeners(activeElementInst$1, 'onSelect');
8640
8641 if (listeners.length > 0) {
8642 var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget);
8643 dispatchQueue.push({
8644 event: event,
8645 listeners: listeners
8646 });
8647 event.target = activeElement$1;
8648 }
8649 }
8650}
8651/**
8652 * This plugin creates an `onSelect` event that normalizes select events
8653 * across form elements.
8654 *
8655 * Supported elements are:
8656 * - input (see `isTextInputElement`)
8657 * - textarea
8658 * - contentEditable
8659 *
8660 * This differs from native browser implementations in the following ways:
8661 * - Fires on contentEditable fields as well as inputs.
8662 * - Fires for collapsed selection.
8663 * - Fires after user input.
8664 */
8665
8666
8667function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8668 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
8669
8670 switch (domEventName) {
8671 // Track the input node that has focus.
8672 case 'focusin':
8673 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
8674 activeElement$1 = targetNode;
8675 activeElementInst$1 = targetInst;
8676 lastSelection = null;
8677 }
8678
8679 break;
8680
8681 case 'focusout':
8682 activeElement$1 = null;
8683 activeElementInst$1 = null;
8684 lastSelection = null;
8685 break;
8686 // Don't fire the event while the user is dragging. This matches the
8687 // semantics of the native select event.
8688
8689 case 'mousedown':
8690 mouseDown = true;
8691 break;
8692
8693 case 'contextmenu':
8694 case 'mouseup':
8695 case 'dragend':
8696 mouseDown = false;
8697 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8698 break;
8699 // Chrome and IE fire non-standard event when selection is changed (and
8700 // sometimes when it hasn't). IE's event fires out of order with respect
8701 // to key and input events on deletion, so we discard it.
8702 //
8703 // Firefox doesn't support selectionchange, so check selection status
8704 // after each key entry. The selection changes after keydown and before
8705 // keyup, but we check on keydown as well in the case of holding down a
8706 // key, when multiple keydown events are fired but only one keyup is.
8707 // This is also our approach for IE handling, for the reason above.
8708
8709 case 'selectionchange':
8710 if (skipSelectionChangeEvent) {
8711 break;
8712 }
8713
8714 // falls through
8715
8716 case 'keydown':
8717 case 'keyup':
8718 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8719 }
8720}
8721
8722/**
8723 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
8724 *
8725 * @param {string} styleProp
8726 * @param {string} eventName
8727 * @returns {object}
8728 */
8729
8730function makePrefixMap(styleProp, eventName) {
8731 var prefixes = {};
8732 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
8733 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
8734 prefixes['Moz' + styleProp] = 'moz' + eventName;
8735 return prefixes;
8736}
8737/**
8738 * A list of event names to a configurable list of vendor prefixes.
8739 */
8740
8741
8742var vendorPrefixes = {
8743 animationend: makePrefixMap('Animation', 'AnimationEnd'),
8744 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
8745 animationstart: makePrefixMap('Animation', 'AnimationStart'),
8746 transitionend: makePrefixMap('Transition', 'TransitionEnd')
8747};
8748/**
8749 * Event names that have already been detected and prefixed (if applicable).
8750 */
8751
8752var prefixedEventNames = {};
8753/**
8754 * Element to check for prefixes on.
8755 */
8756
8757var style = {};
8758/**
8759 * Bootstrap if a DOM exists.
8760 */
8761
8762if (canUseDOM) {
8763 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
8764 // the un-prefixed "animation" and "transition" properties are defined on the
8765 // style object but the events that fire will still be prefixed, so we need
8766 // to check if the un-prefixed events are usable, and if not remove them from the map.
8767
8768 if (!('AnimationEvent' in window)) {
8769 delete vendorPrefixes.animationend.animation;
8770 delete vendorPrefixes.animationiteration.animation;
8771 delete vendorPrefixes.animationstart.animation;
8772 } // Same as above
8773
8774
8775 if (!('TransitionEvent' in window)) {
8776 delete vendorPrefixes.transitionend.transition;
8777 }
8778}
8779/**
8780 * Attempts to determine the correct vendor prefixed event name.
8781 *
8782 * @param {string} eventName
8783 * @returns {string}
8784 */
8785
8786
8787function getVendorPrefixedEventName(eventName) {
8788 if (prefixedEventNames[eventName]) {
8789 return prefixedEventNames[eventName];
8790 } else if (!vendorPrefixes[eventName]) {
8791 return eventName;
8792 }
8793
8794 var prefixMap = vendorPrefixes[eventName];
8795
8796 for (var styleProp in prefixMap) {
8797 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
8798 return prefixedEventNames[eventName] = prefixMap[styleProp];
8799 }
8800 }
8801
8802 return eventName;
8803}
8804
8805var ANIMATION_END = getVendorPrefixedEventName('animationend');
8806var ANIMATION_ITERATION = getVendorPrefixedEventName('animationiteration');
8807var ANIMATION_START = getVendorPrefixedEventName('animationstart');
8808var TRANSITION_END = getVendorPrefixedEventName('transitionend');
8809
8810var topLevelEventsToReactNames = new Map(); // NOTE: Capitalization is important in this list!
8811//
8812// E.g. it needs "pointerDown", not "pointerdown".
8813// This is because we derive both React name ("onPointerDown")
8814// and DOM name ("pointerdown") from the same list.
8815//
8816// Exceptions that don't match this convention are listed separately.
8817//
8818// prettier-ignore
8819
8820var simpleEventPluginEvents = ['abort', 'auxClick', 'cancel', 'canPlay', 'canPlayThrough', 'click', 'close', 'contextMenu', 'copy', 'cut', 'drag', 'dragEnd', 'dragEnter', 'dragExit', 'dragLeave', 'dragOver', 'dragStart', 'drop', 'durationChange', 'emptied', 'encrypted', 'ended', 'error', 'gotPointerCapture', 'input', 'invalid', 'keyDown', 'keyPress', 'keyUp', 'load', 'loadedData', 'loadedMetadata', 'loadStart', 'lostPointerCapture', 'mouseDown', 'mouseMove', 'mouseOut', 'mouseOver', 'mouseUp', 'paste', 'pause', 'play', 'playing', 'pointerCancel', 'pointerDown', 'pointerMove', 'pointerOut', 'pointerOver', 'pointerUp', 'progress', 'rateChange', 'reset', 'resize', 'seeked', 'seeking', 'stalled', 'submit', 'suspend', 'timeUpdate', 'touchCancel', 'touchEnd', 'touchStart', 'volumeChange', 'scroll', 'toggle', 'touchMove', 'waiting', 'wheel'];
8821
8822function registerSimpleEvent(domEventName, reactName) {
8823 topLevelEventsToReactNames.set(domEventName, reactName);
8824 registerTwoPhaseEvent(reactName, [domEventName]);
8825}
8826
8827function registerSimpleEvents() {
8828 for (var i = 0; i < simpleEventPluginEvents.length; i++) {
8829 var eventName = simpleEventPluginEvents[i];
8830 var domEventName = eventName.toLowerCase();
8831 var capitalizedEvent = eventName[0].toUpperCase() + eventName.slice(1);
8832 registerSimpleEvent(domEventName, 'on' + capitalizedEvent);
8833 } // Special cases where event names don't match.
8834
8835
8836 registerSimpleEvent(ANIMATION_END, 'onAnimationEnd');
8837 registerSimpleEvent(ANIMATION_ITERATION, 'onAnimationIteration');
8838 registerSimpleEvent(ANIMATION_START, 'onAnimationStart');
8839 registerSimpleEvent('dblclick', 'onDoubleClick');
8840 registerSimpleEvent('focusin', 'onFocus');
8841 registerSimpleEvent('focusout', 'onBlur');
8842 registerSimpleEvent(TRANSITION_END, 'onTransitionEnd');
8843}
8844
8845function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8846 var reactName = topLevelEventsToReactNames.get(domEventName);
8847
8848 if (reactName === undefined) {
8849 return;
8850 }
8851
8852 var SyntheticEventCtor = SyntheticEvent;
8853 var reactEventType = domEventName;
8854
8855 switch (domEventName) {
8856 case 'keypress':
8857 // Firefox creates a keypress event for function keys too. This removes
8858 // the unwanted keypress events. Enter is however both printable and
8859 // non-printable. One would expect Tab to be as well (but it isn't).
8860 if (getEventCharCode(nativeEvent) === 0) {
8861 return;
8862 }
8863
8864 /* falls through */
8865
8866 case 'keydown':
8867 case 'keyup':
8868 SyntheticEventCtor = SyntheticKeyboardEvent;
8869 break;
8870
8871 case 'focusin':
8872 reactEventType = 'focus';
8873 SyntheticEventCtor = SyntheticFocusEvent;
8874 break;
8875
8876 case 'focusout':
8877 reactEventType = 'blur';
8878 SyntheticEventCtor = SyntheticFocusEvent;
8879 break;
8880
8881 case 'beforeblur':
8882 case 'afterblur':
8883 SyntheticEventCtor = SyntheticFocusEvent;
8884 break;
8885
8886 case 'click':
8887 // Firefox creates a click event on right mouse clicks. This removes the
8888 // unwanted click events.
8889 if (nativeEvent.button === 2) {
8890 return;
8891 }
8892
8893 /* falls through */
8894
8895 case 'auxclick':
8896 case 'dblclick':
8897 case 'mousedown':
8898 case 'mousemove':
8899 case 'mouseup': // TODO: Disabled elements should not respond to mouse events
8900
8901 /* falls through */
8902
8903 case 'mouseout':
8904 case 'mouseover':
8905 case 'contextmenu':
8906 SyntheticEventCtor = SyntheticMouseEvent;
8907 break;
8908
8909 case 'drag':
8910 case 'dragend':
8911 case 'dragenter':
8912 case 'dragexit':
8913 case 'dragleave':
8914 case 'dragover':
8915 case 'dragstart':
8916 case 'drop':
8917 SyntheticEventCtor = SyntheticDragEvent;
8918 break;
8919
8920 case 'touchcancel':
8921 case 'touchend':
8922 case 'touchmove':
8923 case 'touchstart':
8924 SyntheticEventCtor = SyntheticTouchEvent;
8925 break;
8926
8927 case ANIMATION_END:
8928 case ANIMATION_ITERATION:
8929 case ANIMATION_START:
8930 SyntheticEventCtor = SyntheticAnimationEvent;
8931 break;
8932
8933 case TRANSITION_END:
8934 SyntheticEventCtor = SyntheticTransitionEvent;
8935 break;
8936
8937 case 'scroll':
8938 SyntheticEventCtor = SyntheticUIEvent;
8939 break;
8940
8941 case 'wheel':
8942 SyntheticEventCtor = SyntheticWheelEvent;
8943 break;
8944
8945 case 'copy':
8946 case 'cut':
8947 case 'paste':
8948 SyntheticEventCtor = SyntheticClipboardEvent;
8949 break;
8950
8951 case 'gotpointercapture':
8952 case 'lostpointercapture':
8953 case 'pointercancel':
8954 case 'pointerdown':
8955 case 'pointermove':
8956 case 'pointerout':
8957 case 'pointerover':
8958 case 'pointerup':
8959 SyntheticEventCtor = SyntheticPointerEvent;
8960 break;
8961 }
8962
8963 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8964
8965 {
8966 // Some events don't bubble in the browser.
8967 // In the past, React has always bubbled them, but this can be surprising.
8968 // We're going to try aligning closer to the browser behavior by not bubbling
8969 // them in React either. We'll start by not bubbling onScroll, and then expand.
8970 var accumulateTargetOnly = !inCapturePhase && // TODO: ideally, we'd eventually add all events from
8971 // nonDelegatedEvents list in DOMPluginEventSystem.
8972 // Then we can remove this special list.
8973 // This is a breaking change that can wait until React 18.
8974 domEventName === 'scroll';
8975
8976 var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly);
8977
8978 if (_listeners.length > 0) {
8979 // Intentionally create event lazily.
8980 var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
8981
8982 dispatchQueue.push({
8983 event: _event,
8984 listeners: _listeners
8985 });
8986 }
8987 }
8988}
8989
8990// TODO: remove top-level side effect.
8991registerSimpleEvents();
8992registerEvents$2();
8993registerEvents$1();
8994registerEvents$3();
8995registerEvents();
8996
8997function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8998 // TODO: we should remove the concept of a "SimpleEventPlugin".
8999 // This is the basic functionality of the event system. All
9000 // the other plugins are essentially polyfills. So the plugin
9001 // should probably be inlined somewhere and have its logic
9002 // be core the to event system. This would potentially allow
9003 // us to ship builds of React without the polyfilled plugins below.
9004 extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
9005 var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0; // We don't process these events unless we are in the
9006 // event's native "bubble" phase, which means that we're
9007 // not in the capture phase. That's because we emulate
9008 // the capture phase here still. This is a trade-off,
9009 // because in an ideal world we would not emulate and use
9010 // the phases properly, like we do with the SimpleEvent
9011 // plugin. However, the plugins below either expect
9012 // emulation (EnterLeave) or use state localized to that
9013 // plugin (BeforeInput, Change, Select). The state in
9014 // these modules complicates things, as you'll essentially
9015 // get the case where the capture phase event might change
9016 // state, only for the following bubble event to come in
9017 // later and not trigger anything as the state now
9018 // invalidates the heuristics of the event plugin. We
9019 // could alter all these plugins to work in such ways, but
9020 // that might cause other unknown side-effects that we
9021 // can't foresee right now.
9022
9023 if (shouldProcessPolyfillPlugins) {
9024 extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9025 extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9026 extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9027 extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9028 }
9029} // List of events that need to be individually attached to media elements.
9030
9031
9032var mediaEventTypes = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied', 'encrypted', 'ended', 'error', 'loadeddata', 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing', 'progress', 'ratechange', 'resize', 'seeked', 'seeking', 'stalled', 'suspend', 'timeupdate', 'volumechange', 'waiting']; // We should not delegate these events to the container, but rather
9033// set them on the actual target element itself. This is primarily
9034// because these events do not consistently bubble in the DOM.
9035
9036var nonDelegatedEvents = new Set(['cancel', 'close', 'invalid', 'load', 'scroll', 'toggle'].concat(mediaEventTypes));
9037
9038function executeDispatch(event, listener, currentTarget) {
9039 var type = event.type || 'unknown-event';
9040 event.currentTarget = currentTarget;
9041 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
9042 event.currentTarget = null;
9043}
9044
9045function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) {
9046 var previousInstance;
9047
9048 if (inCapturePhase) {
9049 for (var i = dispatchListeners.length - 1; i >= 0; i--) {
9050 var _dispatchListeners$i = dispatchListeners[i],
9051 instance = _dispatchListeners$i.instance,
9052 currentTarget = _dispatchListeners$i.currentTarget,
9053 listener = _dispatchListeners$i.listener;
9054
9055 if (instance !== previousInstance && event.isPropagationStopped()) {
9056 return;
9057 }
9058
9059 executeDispatch(event, listener, currentTarget);
9060 previousInstance = instance;
9061 }
9062 } else {
9063 for (var _i = 0; _i < dispatchListeners.length; _i++) {
9064 var _dispatchListeners$_i = dispatchListeners[_i],
9065 _instance = _dispatchListeners$_i.instance,
9066 _currentTarget = _dispatchListeners$_i.currentTarget,
9067 _listener = _dispatchListeners$_i.listener;
9068
9069 if (_instance !== previousInstance && event.isPropagationStopped()) {
9070 return;
9071 }
9072
9073 executeDispatch(event, _listener, _currentTarget);
9074 previousInstance = _instance;
9075 }
9076 }
9077}
9078
9079function processDispatchQueue(dispatchQueue, eventSystemFlags) {
9080 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
9081
9082 for (var i = 0; i < dispatchQueue.length; i++) {
9083 var _dispatchQueue$i = dispatchQueue[i],
9084 event = _dispatchQueue$i.event,
9085 listeners = _dispatchQueue$i.listeners;
9086 processDispatchQueueItemsInOrder(event, listeners, inCapturePhase); // event system doesn't use pooling.
9087 } // This would be a good time to rethrow if any of the event handlers threw.
9088
9089
9090 rethrowCaughtError();
9091}
9092
9093function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
9094 var nativeEventTarget = getEventTarget(nativeEvent);
9095 var dispatchQueue = [];
9096 extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
9097 processDispatchQueue(dispatchQueue, eventSystemFlags);
9098}
9099
9100function listenToNonDelegatedEvent(domEventName, targetElement) {
9101 {
9102 if (!nonDelegatedEvents.has(domEventName)) {
9103 error('Did not expect a listenToNonDelegatedEvent() call for "%s". ' + 'This is a bug in React. Please file an issue.', domEventName);
9104 }
9105 }
9106
9107 var isCapturePhaseListener = false;
9108 var listenerSet = getEventListenerSet(targetElement);
9109 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener);
9110
9111 if (!listenerSet.has(listenerSetKey)) {
9112 addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener);
9113 listenerSet.add(listenerSetKey);
9114 }
9115}
9116function listenToNativeEvent(domEventName, isCapturePhaseListener, target) {
9117 {
9118 if (nonDelegatedEvents.has(domEventName) && !isCapturePhaseListener) {
9119 error('Did not expect a listenToNativeEvent() call for "%s" in the bubble phase. ' + 'This is a bug in React. Please file an issue.', domEventName);
9120 }
9121 }
9122
9123 var eventSystemFlags = 0;
9124
9125 if (isCapturePhaseListener) {
9126 eventSystemFlags |= IS_CAPTURE_PHASE;
9127 }
9128
9129 addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener);
9130} // This is only used by createEventHandle when the
9131var listeningMarker = '_reactListening' + Math.random().toString(36).slice(2);
9132function listenToAllSupportedEvents(rootContainerElement) {
9133 if (!rootContainerElement[listeningMarker]) {
9134 rootContainerElement[listeningMarker] = true;
9135 allNativeEvents.forEach(function (domEventName) {
9136 // We handle selectionchange separately because it
9137 // doesn't bubble and needs to be on the document.
9138 if (domEventName !== 'selectionchange') {
9139 if (!nonDelegatedEvents.has(domEventName)) {
9140 listenToNativeEvent(domEventName, false, rootContainerElement);
9141 }
9142
9143 listenToNativeEvent(domEventName, true, rootContainerElement);
9144 }
9145 });
9146 var ownerDocument = rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
9147
9148 if (ownerDocument !== null) {
9149 // The selectionchange event also needs deduplication
9150 // but it is attached to the document.
9151 if (!ownerDocument[listeningMarker]) {
9152 ownerDocument[listeningMarker] = true;
9153 listenToNativeEvent('selectionchange', false, ownerDocument);
9154 }
9155 }
9156 }
9157}
9158
9159function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) {
9160 var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags); // If passive option is not supported, then the event will be
9161 // active and not passive.
9162
9163 var isPassiveListener = undefined;
9164
9165 if (passiveBrowserEventsSupported) {
9166 // Browsers introduced an intervention, making these events
9167 // passive by default on document. React doesn't bind them
9168 // to document anymore, but changing this now would undo
9169 // the performance wins from the change. So we emulate
9170 // the existing behavior manually on the roots now.
9171 // https://github.com/facebook/react/issues/19651
9172 if (domEventName === 'touchstart' || domEventName === 'touchmove' || domEventName === 'wheel') {
9173 isPassiveListener = true;
9174 }
9175 }
9176
9177 targetContainer = targetContainer;
9178 var unsubscribeListener; // When legacyFBSupport is enabled, it's for when we
9179
9180
9181 if (isCapturePhaseListener) {
9182 if (isPassiveListener !== undefined) {
9183 unsubscribeListener = addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
9184 } else {
9185 unsubscribeListener = addEventCaptureListener(targetContainer, domEventName, listener);
9186 }
9187 } else {
9188 if (isPassiveListener !== undefined) {
9189 unsubscribeListener = addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
9190 } else {
9191 unsubscribeListener = addEventBubbleListener(targetContainer, domEventName, listener);
9192 }
9193 }
9194}
9195
9196function isMatchingRootContainer(grandContainer, targetContainer) {
9197 return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer;
9198}
9199
9200function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
9201 var ancestorInst = targetInst;
9202
9203 if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) {
9204 var targetContainerNode = targetContainer; // If we are using the legacy FB support flag, we
9205
9206 if (targetInst !== null) {
9207 // The below logic attempts to work out if we need to change
9208 // the target fiber to a different ancestor. We had similar logic
9209 // in the legacy event system, except the big difference between
9210 // systems is that the modern event system now has an event listener
9211 // attached to each React Root and React Portal Root. Together,
9212 // the DOM nodes representing these roots are the "rootContainer".
9213 // To figure out which ancestor instance we should use, we traverse
9214 // up the fiber tree from the target instance and attempt to find
9215 // root boundaries that match that of our current "rootContainer".
9216 // If we find that "rootContainer", we find the parent fiber
9217 // sub-tree for that root and make that our ancestor instance.
9218 var node = targetInst;
9219
9220 mainLoop: while (true) {
9221 if (node === null) {
9222 return;
9223 }
9224
9225 var nodeTag = node.tag;
9226
9227 if (nodeTag === HostRoot || nodeTag === HostPortal) {
9228 var container = node.stateNode.containerInfo;
9229
9230 if (isMatchingRootContainer(container, targetContainerNode)) {
9231 break;
9232 }
9233
9234 if (nodeTag === HostPortal) {
9235 // The target is a portal, but it's not the rootContainer we're looking for.
9236 // Normally portals handle their own events all the way down to the root.
9237 // So we should be able to stop now. However, we don't know if this portal
9238 // was part of *our* root.
9239 var grandNode = node.return;
9240
9241 while (grandNode !== null) {
9242 var grandTag = grandNode.tag;
9243
9244 if (grandTag === HostRoot || grandTag === HostPortal) {
9245 var grandContainer = grandNode.stateNode.containerInfo;
9246
9247 if (isMatchingRootContainer(grandContainer, targetContainerNode)) {
9248 // This is the rootContainer we're looking for and we found it as
9249 // a parent of the Portal. That means we can ignore it because the
9250 // Portal will bubble through to us.
9251 return;
9252 }
9253 }
9254
9255 grandNode = grandNode.return;
9256 }
9257 } // Now we need to find it's corresponding host fiber in the other
9258 // tree. To do this we can use getClosestInstanceFromNode, but we
9259 // need to validate that the fiber is a host instance, otherwise
9260 // we need to traverse up through the DOM till we find the correct
9261 // node that is from the other tree.
9262
9263
9264 while (container !== null) {
9265 var parentNode = getClosestInstanceFromNode(container);
9266
9267 if (parentNode === null) {
9268 return;
9269 }
9270
9271 var parentTag = parentNode.tag;
9272
9273 if (parentTag === HostComponent || parentTag === HostText) {
9274 node = ancestorInst = parentNode;
9275 continue mainLoop;
9276 }
9277
9278 container = container.parentNode;
9279 }
9280 }
9281
9282 node = node.return;
9283 }
9284 }
9285 }
9286
9287 batchedUpdates(function () {
9288 return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst);
9289 });
9290}
9291
9292function createDispatchListener(instance, listener, currentTarget) {
9293 return {
9294 instance: instance,
9295 listener: listener,
9296 currentTarget: currentTarget
9297 };
9298}
9299
9300function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly, nativeEvent) {
9301 var captureName = reactName !== null ? reactName + 'Capture' : null;
9302 var reactEventName = inCapturePhase ? captureName : reactName;
9303 var listeners = [];
9304 var instance = targetFiber;
9305 var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path.
9306
9307 while (instance !== null) {
9308 var _instance2 = instance,
9309 stateNode = _instance2.stateNode,
9310 tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>)
9311
9312 if (tag === HostComponent && stateNode !== null) {
9313 lastHostComponent = stateNode; // createEventHandle listeners
9314
9315
9316 if (reactEventName !== null) {
9317 var listener = getListener(instance, reactEventName);
9318
9319 if (listener != null) {
9320 listeners.push(createDispatchListener(instance, listener, lastHostComponent));
9321 }
9322 }
9323 } // If we are only accumulating events for the target, then we don't
9324 // continue to propagate through the React fiber tree to find other
9325 // listeners.
9326
9327
9328 if (accumulateTargetOnly) {
9329 break;
9330 } // If we are processing the onBeforeBlur event, then we need to take
9331
9332 instance = instance.return;
9333 }
9334
9335 return listeners;
9336} // We should only use this function for:
9337// - BeforeInputEventPlugin
9338// - ChangeEventPlugin
9339// - SelectEventPlugin
9340// This is because we only process these plugins
9341// in the bubble phase, so we need to accumulate two
9342// phase event listeners (via emulation).
9343
9344function accumulateTwoPhaseListeners(targetFiber, reactName) {
9345 var captureName = reactName + 'Capture';
9346 var listeners = [];
9347 var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path.
9348
9349 while (instance !== null) {
9350 var _instance3 = instance,
9351 stateNode = _instance3.stateNode,
9352 tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>)
9353
9354 if (tag === HostComponent && stateNode !== null) {
9355 var currentTarget = stateNode;
9356 var captureListener = getListener(instance, captureName);
9357
9358 if (captureListener != null) {
9359 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
9360 }
9361
9362 var bubbleListener = getListener(instance, reactName);
9363
9364 if (bubbleListener != null) {
9365 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
9366 }
9367 }
9368
9369 instance = instance.return;
9370 }
9371
9372 return listeners;
9373}
9374
9375function getParent(inst) {
9376 if (inst === null) {
9377 return null;
9378 }
9379
9380 do {
9381 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
9382 // That is depending on if we want nested subtrees (layers) to bubble
9383 // events to their parent. We could also go through parentNode on the
9384 // host node but that wouldn't work for React Native and doesn't let us
9385 // do the portal feature.
9386 } while (inst && inst.tag !== HostComponent);
9387
9388 if (inst) {
9389 return inst;
9390 }
9391
9392 return null;
9393}
9394/**
9395 * Return the lowest common ancestor of A and B, or null if they are in
9396 * different trees.
9397 */
9398
9399
9400function getLowestCommonAncestor(instA, instB) {
9401 var nodeA = instA;
9402 var nodeB = instB;
9403 var depthA = 0;
9404
9405 for (var tempA = nodeA; tempA; tempA = getParent(tempA)) {
9406 depthA++;
9407 }
9408
9409 var depthB = 0;
9410
9411 for (var tempB = nodeB; tempB; tempB = getParent(tempB)) {
9412 depthB++;
9413 } // If A is deeper, crawl up.
9414
9415
9416 while (depthA - depthB > 0) {
9417 nodeA = getParent(nodeA);
9418 depthA--;
9419 } // If B is deeper, crawl up.
9420
9421
9422 while (depthB - depthA > 0) {
9423 nodeB = getParent(nodeB);
9424 depthB--;
9425 } // Walk in lockstep until we find a match.
9426
9427
9428 var depth = depthA;
9429
9430 while (depth--) {
9431 if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) {
9432 return nodeA;
9433 }
9434
9435 nodeA = getParent(nodeA);
9436 nodeB = getParent(nodeB);
9437 }
9438
9439 return null;
9440}
9441
9442function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) {
9443 var registrationName = event._reactName;
9444 var listeners = [];
9445 var instance = target;
9446
9447 while (instance !== null) {
9448 if (instance === common) {
9449 break;
9450 }
9451
9452 var _instance4 = instance,
9453 alternate = _instance4.alternate,
9454 stateNode = _instance4.stateNode,
9455 tag = _instance4.tag;
9456
9457 if (alternate !== null && alternate === common) {
9458 break;
9459 }
9460
9461 if (tag === HostComponent && stateNode !== null) {
9462 var currentTarget = stateNode;
9463
9464 if (inCapturePhase) {
9465 var captureListener = getListener(instance, registrationName);
9466
9467 if (captureListener != null) {
9468 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
9469 }
9470 } else if (!inCapturePhase) {
9471 var bubbleListener = getListener(instance, registrationName);
9472
9473 if (bubbleListener != null) {
9474 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
9475 }
9476 }
9477 }
9478
9479 instance = instance.return;
9480 }
9481
9482 if (listeners.length !== 0) {
9483 dispatchQueue.push({
9484 event: event,
9485 listeners: listeners
9486 });
9487 }
9488} // We should only use this function for:
9489// - EnterLeaveEventPlugin
9490// This is because we only process this plugin
9491// in the bubble phase, so we need to accumulate two
9492// phase event listeners.
9493
9494
9495function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) {
9496 var common = from && to ? getLowestCommonAncestor(from, to) : null;
9497
9498 if (from !== null) {
9499 accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false);
9500 }
9501
9502 if (to !== null && enterEvent !== null) {
9503 accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true);
9504 }
9505}
9506function getListenerSetKey(domEventName, capture) {
9507 return domEventName + "__" + (capture ? 'capture' : 'bubble');
9508}
9509
9510var didWarnInvalidHydration = false;
9511var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
9512var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
9513var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
9514var AUTOFOCUS = 'autoFocus';
9515var CHILDREN = 'children';
9516var STYLE = 'style';
9517var HTML$1 = '__html';
9518var warnedUnknownTags;
9519var validatePropertiesInDevelopment;
9520var warnForPropDifference;
9521var warnForExtraAttributes;
9522var warnForInvalidEventListener;
9523var canDiffStyleForHydrationWarning;
9524var normalizeHTML;
9525
9526{
9527 warnedUnknownTags = {
9528 // There are working polyfills for <dialog>. Let people use it.
9529 dialog: true,
9530 // Electron ships a custom <webview> tag to display external web content in
9531 // an isolated frame and process.
9532 // This tag is not present in non Electron environments such as JSDom which
9533 // is often used for testing purposes.
9534 // @see https://electronjs.org/docs/api/webview-tag
9535 webview: true
9536 };
9537
9538 validatePropertiesInDevelopment = function (type, props) {
9539 validateProperties(type, props);
9540 validateProperties$1(type, props);
9541 validateProperties$2(type, props, {
9542 registrationNameDependencies: registrationNameDependencies,
9543 possibleRegistrationNames: possibleRegistrationNames
9544 });
9545 }; // IE 11 parses & normalizes the style attribute as opposed to other
9546 // browsers. It adds spaces and sorts the properties in some
9547 // non-alphabetical order. Handling that would require sorting CSS
9548 // properties in the client & server versions or applying
9549 // `expectedStyle` to a temporary DOM node to read its `style` attribute
9550 // normalized. Since it only affects IE, we're skipping style warnings
9551 // in that browser completely in favor of doing all that work.
9552 // See https://github.com/facebook/react/issues/11807
9553
9554
9555 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
9556
9557 warnForPropDifference = function (propName, serverValue, clientValue) {
9558 if (didWarnInvalidHydration) {
9559 return;
9560 }
9561
9562 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
9563 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
9564
9565 if (normalizedServerValue === normalizedClientValue) {
9566 return;
9567 }
9568
9569 didWarnInvalidHydration = true;
9570
9571 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
9572 };
9573
9574 warnForExtraAttributes = function (attributeNames) {
9575 if (didWarnInvalidHydration) {
9576 return;
9577 }
9578
9579 didWarnInvalidHydration = true;
9580 var names = [];
9581 attributeNames.forEach(function (name) {
9582 names.push(name);
9583 });
9584
9585 error('Extra attributes from the server: %s', names);
9586 };
9587
9588 warnForInvalidEventListener = function (registrationName, listener) {
9589 if (listener === false) {
9590 error('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);
9591 } else {
9592 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
9593 }
9594 }; // Parse the HTML and read it back to normalize the HTML string so that it
9595 // can be used for comparison.
9596
9597
9598 normalizeHTML = function (parent, html) {
9599 // We could have created a separate document here to avoid
9600 // re-initializing custom elements if they exist. But this breaks
9601 // how <noscript> is being handled. So we use the same document.
9602 // See the discussion in https://github.com/facebook/react/pull/11157.
9603 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
9604 testElement.innerHTML = html;
9605 return testElement.innerHTML;
9606 };
9607} // HTML parsing normalizes CR and CRLF to LF.
9608// It also can turn \u0000 into \uFFFD inside attributes.
9609// https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
9610// If we have a mismatch, it might be caused by that.
9611// We will still patch up in this case but not fire the warning.
9612
9613
9614var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
9615var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
9616
9617function normalizeMarkupForTextOrAttribute(markup) {
9618 {
9619 checkHtmlStringCoercion(markup);
9620 }
9621
9622 var markupString = typeof markup === 'string' ? markup : '' + markup;
9623 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
9624}
9625
9626function checkForUnmatchedText(serverText, clientText, isConcurrentMode, shouldWarnDev) {
9627 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
9628 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
9629
9630 if (normalizedServerText === normalizedClientText) {
9631 return;
9632 }
9633
9634 if (shouldWarnDev) {
9635 {
9636 if (!didWarnInvalidHydration) {
9637 didWarnInvalidHydration = true;
9638
9639 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
9640 }
9641 }
9642 }
9643
9644 if (isConcurrentMode && enableClientRenderFallbackOnTextMismatch) {
9645 // In concurrent roots, we throw when there's a text mismatch and revert to
9646 // client rendering, up to the nearest Suspense boundary.
9647 throw new Error('Text content does not match server-rendered HTML.');
9648 }
9649}
9650
9651function getOwnerDocumentFromRootContainer(rootContainerElement) {
9652 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
9653}
9654
9655function noop() {}
9656
9657function trapClickOnNonInteractiveElement(node) {
9658 // Mobile Safari does not fire properly bubble click events on
9659 // non-interactive elements, which means delegated click listeners do not
9660 // fire. The workaround for this bug involves attaching an empty click
9661 // listener on the target node.
9662 // https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
9663 // Just set it using the onclick property so that we don't have to manage any
9664 // bookkeeping for it. Not sure if we need to clear it when the listener is
9665 // removed.
9666 // TODO: Only do this for the relevant Safaris maybe?
9667 node.onclick = noop;
9668}
9669
9670function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
9671 for (var propKey in nextProps) {
9672 if (!nextProps.hasOwnProperty(propKey)) {
9673 continue;
9674 }
9675
9676 var nextProp = nextProps[propKey];
9677
9678 if (propKey === STYLE) {
9679 {
9680 if (nextProp) {
9681 // Freeze the next style object so that we can assume it won't be
9682 // mutated. We have already warned for this in the past.
9683 Object.freeze(nextProp);
9684 }
9685 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
9686
9687
9688 setValueForStyles(domElement, nextProp);
9689 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9690 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
9691
9692 if (nextHtml != null) {
9693 setInnerHTML(domElement, nextHtml);
9694 }
9695 } else if (propKey === CHILDREN) {
9696 if (typeof nextProp === 'string') {
9697 // Avoid setting initial textContent when the text is empty. In IE11 setting
9698 // textContent on a <textarea> will cause the placeholder to not
9699 // show within the <textarea> until it has been focused and blurred again.
9700 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
9701 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
9702
9703 if (canSetTextContent) {
9704 setTextContent(domElement, nextProp);
9705 }
9706 } else if (typeof nextProp === 'number') {
9707 setTextContent(domElement, '' + nextProp);
9708 }
9709 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
9710 if (nextProp != null) {
9711 if ( typeof nextProp !== 'function') {
9712 warnForInvalidEventListener(propKey, nextProp);
9713 }
9714
9715 if (propKey === 'onScroll') {
9716 listenToNonDelegatedEvent('scroll', domElement);
9717 }
9718 }
9719 } else if (nextProp != null) {
9720 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
9721 }
9722 }
9723}
9724
9725function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
9726 // TODO: Handle wasCustomComponentTag
9727 for (var i = 0; i < updatePayload.length; i += 2) {
9728 var propKey = updatePayload[i];
9729 var propValue = updatePayload[i + 1];
9730
9731 if (propKey === STYLE) {
9732 setValueForStyles(domElement, propValue);
9733 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9734 setInnerHTML(domElement, propValue);
9735 } else if (propKey === CHILDREN) {
9736 setTextContent(domElement, propValue);
9737 } else {
9738 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
9739 }
9740 }
9741}
9742
9743function createElement(type, props, rootContainerElement, parentNamespace) {
9744 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
9745 // tags get no namespace.
9746
9747 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
9748 var domElement;
9749 var namespaceURI = parentNamespace;
9750
9751 if (namespaceURI === HTML_NAMESPACE) {
9752 namespaceURI = getIntrinsicNamespace(type);
9753 }
9754
9755 if (namespaceURI === HTML_NAMESPACE) {
9756 {
9757 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
9758 // allow <SVG> or <mATH>.
9759
9760 if (!isCustomComponentTag && type !== type.toLowerCase()) {
9761 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
9762 }
9763 }
9764
9765 if (type === 'script') {
9766 // Create the script via .innerHTML so its "parser-inserted" flag is
9767 // set to true and it does not execute
9768 var div = ownerDocument.createElement('div');
9769
9770 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
9771 // This is guaranteed to yield a script element.
9772
9773 var firstChild = div.firstChild;
9774 domElement = div.removeChild(firstChild);
9775 } else if (typeof props.is === 'string') {
9776 // $FlowIssue `createElement` should be updated for Web Components
9777 domElement = ownerDocument.createElement(type, {
9778 is: props.is
9779 });
9780 } else {
9781 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
9782 // See discussion in https://github.com/facebook/react/pull/6896
9783 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
9784 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
9785 // attributes on `select`s needs to be added before `option`s are inserted.
9786 // This prevents:
9787 // - a bug where the `select` does not scroll to the correct option because singular
9788 // `select` elements automatically pick the first item #13222
9789 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
9790 // See https://github.com/facebook/react/issues/13222
9791 // and https://github.com/facebook/react/issues/14239
9792
9793 if (type === 'select') {
9794 var node = domElement;
9795
9796 if (props.multiple) {
9797 node.multiple = true;
9798 } else if (props.size) {
9799 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
9800 // it is possible that no option is selected.
9801 //
9802 // This is only necessary when a select in "single selection mode".
9803 node.size = props.size;
9804 }
9805 }
9806 }
9807 } else {
9808 domElement = ownerDocument.createElementNS(namespaceURI, type);
9809 }
9810
9811 {
9812 if (namespaceURI === HTML_NAMESPACE) {
9813 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !hasOwnProperty.call(warnedUnknownTags, type)) {
9814 warnedUnknownTags[type] = true;
9815
9816 error('The tag <%s> is unrecognized in this browser. ' + 'If you meant to render a React component, start its name with ' + 'an uppercase letter.', type);
9817 }
9818 }
9819 }
9820
9821 return domElement;
9822}
9823function createTextNode(text, rootContainerElement) {
9824 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
9825}
9826function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
9827 var isCustomComponentTag = isCustomComponent(tag, rawProps);
9828
9829 {
9830 validatePropertiesInDevelopment(tag, rawProps);
9831 } // TODO: Make sure that we check isMounted before firing any of these events.
9832
9833
9834 var props;
9835
9836 switch (tag) {
9837 case 'dialog':
9838 listenToNonDelegatedEvent('cancel', domElement);
9839 listenToNonDelegatedEvent('close', domElement);
9840 props = rawProps;
9841 break;
9842
9843 case 'iframe':
9844 case 'object':
9845 case 'embed':
9846 // We listen to this event in case to ensure emulated bubble
9847 // listeners still fire for the load event.
9848 listenToNonDelegatedEvent('load', domElement);
9849 props = rawProps;
9850 break;
9851
9852 case 'video':
9853 case 'audio':
9854 // We listen to these events in case to ensure emulated bubble
9855 // listeners still fire for all the media events.
9856 for (var i = 0; i < mediaEventTypes.length; i++) {
9857 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
9858 }
9859
9860 props = rawProps;
9861 break;
9862
9863 case 'source':
9864 // We listen to this event in case to ensure emulated bubble
9865 // listeners still fire for the error event.
9866 listenToNonDelegatedEvent('error', domElement);
9867 props = rawProps;
9868 break;
9869
9870 case 'img':
9871 case 'image':
9872 case 'link':
9873 // We listen to these events in case to ensure emulated bubble
9874 // listeners still fire for error and load events.
9875 listenToNonDelegatedEvent('error', domElement);
9876 listenToNonDelegatedEvent('load', domElement);
9877 props = rawProps;
9878 break;
9879
9880 case 'details':
9881 // We listen to this event in case to ensure emulated bubble
9882 // listeners still fire for the toggle event.
9883 listenToNonDelegatedEvent('toggle', domElement);
9884 props = rawProps;
9885 break;
9886
9887 case 'input':
9888 initWrapperState(domElement, rawProps);
9889 props = getHostProps(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9890 // listeners still fire for the invalid event.
9891
9892 listenToNonDelegatedEvent('invalid', domElement);
9893 break;
9894
9895 case 'option':
9896 validateProps(domElement, rawProps);
9897 props = rawProps;
9898 break;
9899
9900 case 'select':
9901 initWrapperState$1(domElement, rawProps);
9902 props = getHostProps$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9903 // listeners still fire for the invalid event.
9904
9905 listenToNonDelegatedEvent('invalid', domElement);
9906 break;
9907
9908 case 'textarea':
9909 initWrapperState$2(domElement, rawProps);
9910 props = getHostProps$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9911 // listeners still fire for the invalid event.
9912
9913 listenToNonDelegatedEvent('invalid', domElement);
9914 break;
9915
9916 default:
9917 props = rawProps;
9918 }
9919
9920 assertValidProps(tag, props);
9921 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
9922
9923 switch (tag) {
9924 case 'input':
9925 // TODO: Make sure we check if this is still unmounted or do any clean
9926 // up necessary since we never stop tracking anymore.
9927 track(domElement);
9928 postMountWrapper(domElement, rawProps, false);
9929 break;
9930
9931 case 'textarea':
9932 // TODO: Make sure we check if this is still unmounted or do any clean
9933 // up necessary since we never stop tracking anymore.
9934 track(domElement);
9935 postMountWrapper$3(domElement);
9936 break;
9937
9938 case 'option':
9939 postMountWrapper$1(domElement, rawProps);
9940 break;
9941
9942 case 'select':
9943 postMountWrapper$2(domElement, rawProps);
9944 break;
9945
9946 default:
9947 if (typeof props.onClick === 'function') {
9948 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9949 trapClickOnNonInteractiveElement(domElement);
9950 }
9951
9952 break;
9953 }
9954} // Calculate the diff between the two objects.
9955
9956function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
9957 {
9958 validatePropertiesInDevelopment(tag, nextRawProps);
9959 }
9960
9961 var updatePayload = null;
9962 var lastProps;
9963 var nextProps;
9964
9965 switch (tag) {
9966 case 'input':
9967 lastProps = getHostProps(domElement, lastRawProps);
9968 nextProps = getHostProps(domElement, nextRawProps);
9969 updatePayload = [];
9970 break;
9971
9972 case 'select':
9973 lastProps = getHostProps$1(domElement, lastRawProps);
9974 nextProps = getHostProps$1(domElement, nextRawProps);
9975 updatePayload = [];
9976 break;
9977
9978 case 'textarea':
9979 lastProps = getHostProps$2(domElement, lastRawProps);
9980 nextProps = getHostProps$2(domElement, nextRawProps);
9981 updatePayload = [];
9982 break;
9983
9984 default:
9985 lastProps = lastRawProps;
9986 nextProps = nextRawProps;
9987
9988 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
9989 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9990 trapClickOnNonInteractiveElement(domElement);
9991 }
9992
9993 break;
9994 }
9995
9996 assertValidProps(tag, nextProps);
9997 var propKey;
9998 var styleName;
9999 var styleUpdates = null;
10000
10001 for (propKey in lastProps) {
10002 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
10003 continue;
10004 }
10005
10006 if (propKey === STYLE) {
10007 var lastStyle = lastProps[propKey];
10008
10009 for (styleName in lastStyle) {
10010 if (lastStyle.hasOwnProperty(styleName)) {
10011 if (!styleUpdates) {
10012 styleUpdates = {};
10013 }
10014
10015 styleUpdates[styleName] = '';
10016 }
10017 }
10018 } else if (propKey === DANGEROUSLY_SET_INNER_HTML || propKey === CHILDREN) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
10019 // This is a special case. If any listener updates we need to ensure
10020 // that the "current" fiber pointer gets updated so we need a commit
10021 // to update this element.
10022 if (!updatePayload) {
10023 updatePayload = [];
10024 }
10025 } else {
10026 // For all other deleted properties we add it to the queue. We use
10027 // the allowed property list in the commit phase instead.
10028 (updatePayload = updatePayload || []).push(propKey, null);
10029 }
10030 }
10031
10032 for (propKey in nextProps) {
10033 var nextProp = nextProps[propKey];
10034 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
10035
10036 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
10037 continue;
10038 }
10039
10040 if (propKey === STYLE) {
10041 {
10042 if (nextProp) {
10043 // Freeze the next style object so that we can assume it won't be
10044 // mutated. We have already warned for this in the past.
10045 Object.freeze(nextProp);
10046 }
10047 }
10048
10049 if (lastProp) {
10050 // Unset styles on `lastProp` but not on `nextProp`.
10051 for (styleName in lastProp) {
10052 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
10053 if (!styleUpdates) {
10054 styleUpdates = {};
10055 }
10056
10057 styleUpdates[styleName] = '';
10058 }
10059 } // Update styles that changed since `lastProp`.
10060
10061
10062 for (styleName in nextProp) {
10063 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
10064 if (!styleUpdates) {
10065 styleUpdates = {};
10066 }
10067
10068 styleUpdates[styleName] = nextProp[styleName];
10069 }
10070 }
10071 } else {
10072 // Relies on `updateStylesByID` not mutating `styleUpdates`.
10073 if (!styleUpdates) {
10074 if (!updatePayload) {
10075 updatePayload = [];
10076 }
10077
10078 updatePayload.push(propKey, styleUpdates);
10079 }
10080
10081 styleUpdates = nextProp;
10082 }
10083 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
10084 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
10085 var lastHtml = lastProp ? lastProp[HTML$1] : undefined;
10086
10087 if (nextHtml != null) {
10088 if (lastHtml !== nextHtml) {
10089 (updatePayload = updatePayload || []).push(propKey, nextHtml);
10090 }
10091 }
10092 } else if (propKey === CHILDREN) {
10093 if (typeof nextProp === 'string' || typeof nextProp === 'number') {
10094 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
10095 }
10096 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
10097 if (nextProp != null) {
10098 // We eagerly listen to this even though we haven't committed yet.
10099 if ( typeof nextProp !== 'function') {
10100 warnForInvalidEventListener(propKey, nextProp);
10101 }
10102
10103 if (propKey === 'onScroll') {
10104 listenToNonDelegatedEvent('scroll', domElement);
10105 }
10106 }
10107
10108 if (!updatePayload && lastProp !== nextProp) {
10109 // This is a special case. If any listener updates we need to ensure
10110 // that the "current" props pointer gets updated so we need a commit
10111 // to update this element.
10112 updatePayload = [];
10113 }
10114 } else {
10115 // For any other property we always add it to the queue and then we
10116 // filter it out using the allowed property list during the commit.
10117 (updatePayload = updatePayload || []).push(propKey, nextProp);
10118 }
10119 }
10120
10121 if (styleUpdates) {
10122 {
10123 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
10124 }
10125
10126 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
10127 }
10128
10129 return updatePayload;
10130} // Apply the diff.
10131
10132function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
10133 // Update checked *before* name.
10134 // In the middle of an update, it is possible to have multiple checked.
10135 // When a checked radio tries to change name, browser makes another radio's checked false.
10136 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
10137 updateChecked(domElement, nextRawProps);
10138 }
10139
10140 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
10141 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
10142
10143 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
10144 // changed.
10145
10146 switch (tag) {
10147 case 'input':
10148 // Update the wrapper around inputs *after* updating props. This has to
10149 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
10150 // raise warnings and prevent the new value from being assigned.
10151 updateWrapper(domElement, nextRawProps);
10152 break;
10153
10154 case 'textarea':
10155 updateWrapper$1(domElement, nextRawProps);
10156 break;
10157
10158 case 'select':
10159 // <select> value update needs to occur after <option> children
10160 // reconciliation
10161 postUpdateWrapper(domElement, nextRawProps);
10162 break;
10163 }
10164}
10165
10166function getPossibleStandardName(propName) {
10167 {
10168 var lowerCasedName = propName.toLowerCase();
10169
10170 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
10171 return null;
10172 }
10173
10174 return possibleStandardNames[lowerCasedName] || null;
10175 }
10176}
10177
10178function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement, isConcurrentMode, shouldWarnDev) {
10179 var isCustomComponentTag;
10180 var extraAttributeNames;
10181
10182 {
10183 isCustomComponentTag = isCustomComponent(tag, rawProps);
10184 validatePropertiesInDevelopment(tag, rawProps);
10185 } // TODO: Make sure that we check isMounted before firing any of these events.
10186
10187
10188 switch (tag) {
10189 case 'dialog':
10190 listenToNonDelegatedEvent('cancel', domElement);
10191 listenToNonDelegatedEvent('close', domElement);
10192 break;
10193
10194 case 'iframe':
10195 case 'object':
10196 case 'embed':
10197 // We listen to this event in case to ensure emulated bubble
10198 // listeners still fire for the load event.
10199 listenToNonDelegatedEvent('load', domElement);
10200 break;
10201
10202 case 'video':
10203 case 'audio':
10204 // We listen to these events in case to ensure emulated bubble
10205 // listeners still fire for all the media events.
10206 for (var i = 0; i < mediaEventTypes.length; i++) {
10207 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
10208 }
10209
10210 break;
10211
10212 case 'source':
10213 // We listen to this event in case to ensure emulated bubble
10214 // listeners still fire for the error event.
10215 listenToNonDelegatedEvent('error', domElement);
10216 break;
10217
10218 case 'img':
10219 case 'image':
10220 case 'link':
10221 // We listen to these events in case to ensure emulated bubble
10222 // listeners still fire for error and load events.
10223 listenToNonDelegatedEvent('error', domElement);
10224 listenToNonDelegatedEvent('load', domElement);
10225 break;
10226
10227 case 'details':
10228 // We listen to this event in case to ensure emulated bubble
10229 // listeners still fire for the toggle event.
10230 listenToNonDelegatedEvent('toggle', domElement);
10231 break;
10232
10233 case 'input':
10234 initWrapperState(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
10235 // listeners still fire for the invalid event.
10236
10237 listenToNonDelegatedEvent('invalid', domElement);
10238 break;
10239
10240 case 'option':
10241 validateProps(domElement, rawProps);
10242 break;
10243
10244 case 'select':
10245 initWrapperState$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
10246 // listeners still fire for the invalid event.
10247
10248 listenToNonDelegatedEvent('invalid', domElement);
10249 break;
10250
10251 case 'textarea':
10252 initWrapperState$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
10253 // listeners still fire for the invalid event.
10254
10255 listenToNonDelegatedEvent('invalid', domElement);
10256 break;
10257 }
10258
10259 assertValidProps(tag, rawProps);
10260
10261 {
10262 extraAttributeNames = new Set();
10263 var attributes = domElement.attributes;
10264
10265 for (var _i = 0; _i < attributes.length; _i++) {
10266 var name = attributes[_i].name.toLowerCase();
10267
10268 switch (name) {
10269 // Controlled attributes are not validated
10270 // TODO: Only ignore them on controlled tags.
10271 case 'value':
10272 break;
10273
10274 case 'checked':
10275 break;
10276
10277 case 'selected':
10278 break;
10279
10280 default:
10281 // Intentionally use the original name.
10282 // See discussion in https://github.com/facebook/react/pull/10676.
10283 extraAttributeNames.add(attributes[_i].name);
10284 }
10285 }
10286 }
10287
10288 var updatePayload = null;
10289
10290 for (var propKey in rawProps) {
10291 if (!rawProps.hasOwnProperty(propKey)) {
10292 continue;
10293 }
10294
10295 var nextProp = rawProps[propKey];
10296
10297 if (propKey === CHILDREN) {
10298 // For text content children we compare against textContent. This
10299 // might match additional HTML that is hidden when we read it using
10300 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
10301 // satisfies our requirement. Our requirement is not to produce perfect
10302 // HTML and attributes. Ideally we should preserve structure but it's
10303 // ok not to if the visible content is still enough to indicate what
10304 // even listeners these nodes might be wired up to.
10305 // TODO: Warn if there is more than a single textNode as a child.
10306 // TODO: Should we use domElement.firstChild.nodeValue to compare?
10307 if (typeof nextProp === 'string') {
10308 if (domElement.textContent !== nextProp) {
10309 if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10310 checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
10311 }
10312
10313 updatePayload = [CHILDREN, nextProp];
10314 }
10315 } else if (typeof nextProp === 'number') {
10316 if (domElement.textContent !== '' + nextProp) {
10317 if (rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10318 checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
10319 }
10320
10321 updatePayload = [CHILDREN, '' + nextProp];
10322 }
10323 }
10324 } else if (registrationNameDependencies.hasOwnProperty(propKey)) {
10325 if (nextProp != null) {
10326 if ( typeof nextProp !== 'function') {
10327 warnForInvalidEventListener(propKey, nextProp);
10328 }
10329
10330 if (propKey === 'onScroll') {
10331 listenToNonDelegatedEvent('scroll', domElement);
10332 }
10333 }
10334 } else if (shouldWarnDev && true && // Convince Flow we've calculated it (it's DEV-only in this method.)
10335 typeof isCustomComponentTag === 'boolean') {
10336 // Validate that the properties correspond to their expected values.
10337 var serverValue = void 0;
10338 var propertyInfo = isCustomComponentTag && enableCustomElementPropertySupport ? null : getPropertyInfo(propKey);
10339
10340 if (rawProps[SUPPRESS_HYDRATION_WARNING] === true) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
10341 // TODO: Only ignore them on controlled tags.
10342 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
10343 var serverHTML = domElement.innerHTML;
10344 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
10345
10346 if (nextHtml != null) {
10347 var expectedHTML = normalizeHTML(domElement, nextHtml);
10348
10349 if (expectedHTML !== serverHTML) {
10350 warnForPropDifference(propKey, serverHTML, expectedHTML);
10351 }
10352 }
10353 } else if (propKey === STYLE) {
10354 // $FlowFixMe - Should be inferred as not undefined.
10355 extraAttributeNames.delete(propKey);
10356
10357 if (canDiffStyleForHydrationWarning) {
10358 var expectedStyle = createDangerousStringForStyles(nextProp);
10359 serverValue = domElement.getAttribute('style');
10360
10361 if (expectedStyle !== serverValue) {
10362 warnForPropDifference(propKey, serverValue, expectedStyle);
10363 }
10364 }
10365 } else if (isCustomComponentTag && !enableCustomElementPropertySupport) {
10366 // $FlowFixMe - Should be inferred as not undefined.
10367 extraAttributeNames.delete(propKey.toLowerCase());
10368 serverValue = getValueForAttribute(domElement, propKey, nextProp);
10369
10370 if (nextProp !== serverValue) {
10371 warnForPropDifference(propKey, serverValue, nextProp);
10372 }
10373 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
10374 var isMismatchDueToBadCasing = false;
10375
10376 if (propertyInfo !== null) {
10377 // $FlowFixMe - Should be inferred as not undefined.
10378 extraAttributeNames.delete(propertyInfo.attributeName);
10379 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
10380 } else {
10381 var ownNamespace = parentNamespace;
10382
10383 if (ownNamespace === HTML_NAMESPACE) {
10384 ownNamespace = getIntrinsicNamespace(tag);
10385 }
10386
10387 if (ownNamespace === HTML_NAMESPACE) {
10388 // $FlowFixMe - Should be inferred as not undefined.
10389 extraAttributeNames.delete(propKey.toLowerCase());
10390 } else {
10391 var standardName = getPossibleStandardName(propKey);
10392
10393 if (standardName !== null && standardName !== propKey) {
10394 // If an SVG prop is supplied with bad casing, it will
10395 // be successfully parsed from HTML, but will produce a mismatch
10396 // (and would be incorrectly rendered on the client).
10397 // However, we already warn about bad casing elsewhere.
10398 // So we'll skip the misleading extra mismatch warning in this case.
10399 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
10400
10401 extraAttributeNames.delete(standardName);
10402 } // $FlowFixMe - Should be inferred as not undefined.
10403
10404
10405 extraAttributeNames.delete(propKey);
10406 }
10407
10408 serverValue = getValueForAttribute(domElement, propKey, nextProp);
10409 }
10410
10411 var dontWarnCustomElement = enableCustomElementPropertySupport ;
10412
10413 if (!dontWarnCustomElement && nextProp !== serverValue && !isMismatchDueToBadCasing) {
10414 warnForPropDifference(propKey, serverValue, nextProp);
10415 }
10416 }
10417 }
10418 }
10419
10420 {
10421 if (shouldWarnDev) {
10422 if ( // $FlowFixMe - Should be inferred as not undefined.
10423 extraAttributeNames.size > 0 && rawProps[SUPPRESS_HYDRATION_WARNING] !== true) {
10424 // $FlowFixMe - Should be inferred as not undefined.
10425 warnForExtraAttributes(extraAttributeNames);
10426 }
10427 }
10428 }
10429
10430 switch (tag) {
10431 case 'input':
10432 // TODO: Make sure we check if this is still unmounted or do any clean
10433 // up necessary since we never stop tracking anymore.
10434 track(domElement);
10435 postMountWrapper(domElement, rawProps, true);
10436 break;
10437
10438 case 'textarea':
10439 // TODO: Make sure we check if this is still unmounted or do any clean
10440 // up necessary since we never stop tracking anymore.
10441 track(domElement);
10442 postMountWrapper$3(domElement);
10443 break;
10444
10445 case 'select':
10446 case 'option':
10447 // For input and textarea we current always set the value property at
10448 // post mount to force it to diverge from attributes. However, for
10449 // option and select we don't quite do the same thing and select
10450 // is not resilient to the DOM state changing so we don't do that here.
10451 // TODO: Consider not doing this for input and textarea.
10452 break;
10453
10454 default:
10455 if (typeof rawProps.onClick === 'function') {
10456 // TODO: This cast may not be sound for SVG, MathML or custom elements.
10457 trapClickOnNonInteractiveElement(domElement);
10458 }
10459
10460 break;
10461 }
10462
10463 return updatePayload;
10464}
10465function diffHydratedText(textNode, text, isConcurrentMode) {
10466 var isDifferent = textNode.nodeValue !== text;
10467 return isDifferent;
10468}
10469function warnForDeletedHydratableElement(parentNode, child) {
10470 {
10471 if (didWarnInvalidHydration) {
10472 return;
10473 }
10474
10475 didWarnInvalidHydration = true;
10476
10477 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
10478 }
10479}
10480function warnForDeletedHydratableText(parentNode, child) {
10481 {
10482 if (didWarnInvalidHydration) {
10483 return;
10484 }
10485
10486 didWarnInvalidHydration = true;
10487
10488 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
10489 }
10490}
10491function warnForInsertedHydratedElement(parentNode, tag, props) {
10492 {
10493 if (didWarnInvalidHydration) {
10494 return;
10495 }
10496
10497 didWarnInvalidHydration = true;
10498
10499 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
10500 }
10501}
10502function warnForInsertedHydratedText(parentNode, text) {
10503 {
10504 if (text === '') {
10505 // We expect to insert empty text nodes since they're not represented in
10506 // the HTML.
10507 // TODO: Remove this special case if we can just avoid inserting empty
10508 // text nodes.
10509 return;
10510 }
10511
10512 if (didWarnInvalidHydration) {
10513 return;
10514 }
10515
10516 didWarnInvalidHydration = true;
10517
10518 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
10519 }
10520}
10521function restoreControlledState$3(domElement, tag, props) {
10522 switch (tag) {
10523 case 'input':
10524 restoreControlledState(domElement, props);
10525 return;
10526
10527 case 'textarea':
10528 restoreControlledState$2(domElement, props);
10529 return;
10530
10531 case 'select':
10532 restoreControlledState$1(domElement, props);
10533 return;
10534 }
10535}
10536
10537var validateDOMNesting = function () {};
10538
10539var updatedAncestorInfo = function () {};
10540
10541{
10542 // This validation code was written based on the HTML5 parsing spec:
10543 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
10544 //
10545 // Note: this does not catch all invalid nesting, nor does it try to (as it's
10546 // not clear what practical benefit doing so provides); instead, we warn only
10547 // for cases where the parser will give a parse tree differing from what React
10548 // intended. For example, <b><div></div></b> is invalid but we don't warn
10549 // because it still parses correctly; we do warn for other cases like nested
10550 // <p> tags where the beginning of the second element implicitly closes the
10551 // first, causing a confusing mess.
10552 // https://html.spec.whatwg.org/multipage/syntax.html#special
10553 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
10554
10555 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
10556 // TODO: Distinguish by namespace here -- for <title>, including it here
10557 // errs on the side of fewer warnings
10558 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
10559
10560 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
10561
10562 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
10563 var emptyAncestorInfo = {
10564 current: null,
10565 formTag: null,
10566 aTagInScope: null,
10567 buttonTagInScope: null,
10568 nobrTagInScope: null,
10569 pTagInButtonScope: null,
10570 listItemTagAutoclosing: null,
10571 dlItemTagAutoclosing: null
10572 };
10573
10574 updatedAncestorInfo = function (oldInfo, tag) {
10575 var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo);
10576
10577 var info = {
10578 tag: tag
10579 };
10580
10581 if (inScopeTags.indexOf(tag) !== -1) {
10582 ancestorInfo.aTagInScope = null;
10583 ancestorInfo.buttonTagInScope = null;
10584 ancestorInfo.nobrTagInScope = null;
10585 }
10586
10587 if (buttonScopeTags.indexOf(tag) !== -1) {
10588 ancestorInfo.pTagInButtonScope = null;
10589 } // See rules for 'li', 'dd', 'dt' start tags in
10590 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
10591
10592
10593 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
10594 ancestorInfo.listItemTagAutoclosing = null;
10595 ancestorInfo.dlItemTagAutoclosing = null;
10596 }
10597
10598 ancestorInfo.current = info;
10599
10600 if (tag === 'form') {
10601 ancestorInfo.formTag = info;
10602 }
10603
10604 if (tag === 'a') {
10605 ancestorInfo.aTagInScope = info;
10606 }
10607
10608 if (tag === 'button') {
10609 ancestorInfo.buttonTagInScope = info;
10610 }
10611
10612 if (tag === 'nobr') {
10613 ancestorInfo.nobrTagInScope = info;
10614 }
10615
10616 if (tag === 'p') {
10617 ancestorInfo.pTagInButtonScope = info;
10618 }
10619
10620 if (tag === 'li') {
10621 ancestorInfo.listItemTagAutoclosing = info;
10622 }
10623
10624 if (tag === 'dd' || tag === 'dt') {
10625 ancestorInfo.dlItemTagAutoclosing = info;
10626 }
10627
10628 return ancestorInfo;
10629 };
10630 /**
10631 * Returns whether
10632 */
10633
10634
10635 var isTagValidWithParent = function (tag, parentTag) {
10636 // First, let's check if we're in an unusual parsing mode...
10637 switch (parentTag) {
10638 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
10639 case 'select':
10640 return tag === 'option' || tag === 'optgroup' || tag === '#text';
10641
10642 case 'optgroup':
10643 return tag === 'option' || tag === '#text';
10644 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
10645 // but
10646
10647 case 'option':
10648 return tag === '#text';
10649 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
10650 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
10651 // No special behavior since these rules fall back to "in body" mode for
10652 // all except special table nodes which cause bad parsing behavior anyway.
10653 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
10654
10655 case 'tr':
10656 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
10657 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
10658
10659 case 'tbody':
10660 case 'thead':
10661 case 'tfoot':
10662 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
10663 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
10664
10665 case 'colgroup':
10666 return tag === 'col' || tag === 'template';
10667 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
10668
10669 case 'table':
10670 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
10671 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
10672
10673 case 'head':
10674 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
10675 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
10676
10677 case 'html':
10678 return tag === 'head' || tag === 'body' || tag === 'frameset';
10679
10680 case 'frameset':
10681 return tag === 'frame';
10682
10683 case '#document':
10684 return tag === 'html';
10685 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
10686 // where the parsing rules cause implicit opens or closes to be added.
10687 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
10688
10689
10690 switch (tag) {
10691 case 'h1':
10692 case 'h2':
10693 case 'h3':
10694 case 'h4':
10695 case 'h5':
10696 case 'h6':
10697 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
10698
10699 case 'rp':
10700 case 'rt':
10701 return impliedEndTags.indexOf(parentTag) === -1;
10702
10703 case 'body':
10704 case 'caption':
10705 case 'col':
10706 case 'colgroup':
10707 case 'frameset':
10708 case 'frame':
10709 case 'head':
10710 case 'html':
10711 case 'tbody':
10712 case 'td':
10713 case 'tfoot':
10714 case 'th':
10715 case 'thead':
10716 case 'tr':
10717 // These tags are only valid with a few parents that have special child
10718 // parsing rules -- if we're down here, then none of those matched and
10719 // so we allow it only if we don't know what the parent is, as all other
10720 // cases are invalid.
10721 return parentTag == null;
10722 }
10723
10724 return true;
10725 };
10726 /**
10727 * Returns whether
10728 */
10729
10730
10731 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
10732 switch (tag) {
10733 case 'address':
10734 case 'article':
10735 case 'aside':
10736 case 'blockquote':
10737 case 'center':
10738 case 'details':
10739 case 'dialog':
10740 case 'dir':
10741 case 'div':
10742 case 'dl':
10743 case 'fieldset':
10744 case 'figcaption':
10745 case 'figure':
10746 case 'footer':
10747 case 'header':
10748 case 'hgroup':
10749 case 'main':
10750 case 'menu':
10751 case 'nav':
10752 case 'ol':
10753 case 'p':
10754 case 'section':
10755 case 'summary':
10756 case 'ul':
10757 case 'pre':
10758 case 'listing':
10759 case 'table':
10760 case 'hr':
10761 case 'xmp':
10762 case 'h1':
10763 case 'h2':
10764 case 'h3':
10765 case 'h4':
10766 case 'h5':
10767 case 'h6':
10768 return ancestorInfo.pTagInButtonScope;
10769
10770 case 'form':
10771 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
10772
10773 case 'li':
10774 return ancestorInfo.listItemTagAutoclosing;
10775
10776 case 'dd':
10777 case 'dt':
10778 return ancestorInfo.dlItemTagAutoclosing;
10779
10780 case 'button':
10781 return ancestorInfo.buttonTagInScope;
10782
10783 case 'a':
10784 // Spec says something about storing a list of markers, but it sounds
10785 // equivalent to this check.
10786 return ancestorInfo.aTagInScope;
10787
10788 case 'nobr':
10789 return ancestorInfo.nobrTagInScope;
10790 }
10791
10792 return null;
10793 };
10794
10795 var didWarn$1 = {};
10796
10797 validateDOMNesting = function (childTag, childText, ancestorInfo) {
10798 ancestorInfo = ancestorInfo || emptyAncestorInfo;
10799 var parentInfo = ancestorInfo.current;
10800 var parentTag = parentInfo && parentInfo.tag;
10801
10802 if (childText != null) {
10803 if (childTag != null) {
10804 error('validateDOMNesting: when childText is passed, childTag should be null');
10805 }
10806
10807 childTag = '#text';
10808 }
10809
10810 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
10811 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
10812 var invalidParentOrAncestor = invalidParent || invalidAncestor;
10813
10814 if (!invalidParentOrAncestor) {
10815 return;
10816 }
10817
10818 var ancestorTag = invalidParentOrAncestor.tag;
10819 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag;
10820
10821 if (didWarn$1[warnKey]) {
10822 return;
10823 }
10824
10825 didWarn$1[warnKey] = true;
10826 var tagDisplayName = childTag;
10827 var whitespaceInfo = '';
10828
10829 if (childTag === '#text') {
10830 if (/\S/.test(childText)) {
10831 tagDisplayName = 'Text nodes';
10832 } else {
10833 tagDisplayName = 'Whitespace text nodes';
10834 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
10835 }
10836 } else {
10837 tagDisplayName = '<' + childTag + '>';
10838 }
10839
10840 if (invalidParent) {
10841 var info = '';
10842
10843 if (ancestorTag === 'table' && childTag === 'tr') {
10844 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
10845 }
10846
10847 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);
10848 } else {
10849 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);
10850 }
10851 };
10852}
10853
10854var SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
10855var SUSPENSE_START_DATA = '$';
10856var SUSPENSE_END_DATA = '/$';
10857var SUSPENSE_PENDING_START_DATA = '$?';
10858var SUSPENSE_FALLBACK_START_DATA = '$!';
10859var STYLE$1 = 'style';
10860var eventsEnabled = null;
10861var selectionInformation = null;
10862function getRootHostContext(rootContainerInstance) {
10863 var type;
10864 var namespace;
10865 var nodeType = rootContainerInstance.nodeType;
10866
10867 switch (nodeType) {
10868 case DOCUMENT_NODE:
10869 case DOCUMENT_FRAGMENT_NODE:
10870 {
10871 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
10872 var root = rootContainerInstance.documentElement;
10873 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
10874 break;
10875 }
10876
10877 default:
10878 {
10879 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
10880 var ownNamespace = container.namespaceURI || null;
10881 type = container.tagName;
10882 namespace = getChildNamespace(ownNamespace, type);
10883 break;
10884 }
10885 }
10886
10887 {
10888 var validatedTag = type.toLowerCase();
10889 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
10890 return {
10891 namespace: namespace,
10892 ancestorInfo: ancestorInfo
10893 };
10894 }
10895}
10896function getChildHostContext(parentHostContext, type, rootContainerInstance) {
10897 {
10898 var parentHostContextDev = parentHostContext;
10899 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
10900 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
10901 return {
10902 namespace: namespace,
10903 ancestorInfo: ancestorInfo
10904 };
10905 }
10906}
10907function getPublicInstance(instance) {
10908 return instance;
10909}
10910function prepareForCommit(containerInfo) {
10911 eventsEnabled = isEnabled();
10912 selectionInformation = getSelectionInformation();
10913 var activeInstance = null;
10914
10915 setEnabled(false);
10916 return activeInstance;
10917}
10918function resetAfterCommit(containerInfo) {
10919 restoreSelection(selectionInformation);
10920 setEnabled(eventsEnabled);
10921 eventsEnabled = null;
10922 selectionInformation = null;
10923}
10924function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10925 var parentNamespace;
10926
10927 {
10928 // TODO: take namespace into account when validating.
10929 var hostContextDev = hostContext;
10930 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
10931
10932 if (typeof props.children === 'string' || typeof props.children === 'number') {
10933 var string = '' + props.children;
10934 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10935 validateDOMNesting(null, string, ownAncestorInfo);
10936 }
10937
10938 parentNamespace = hostContextDev.namespace;
10939 }
10940
10941 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
10942 precacheFiberNode(internalInstanceHandle, domElement);
10943 updateFiberProps(domElement, props);
10944 return domElement;
10945}
10946function appendInitialChild(parentInstance, child) {
10947 parentInstance.appendChild(child);
10948}
10949function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
10950 setInitialProperties(domElement, type, props, rootContainerInstance);
10951
10952 switch (type) {
10953 case 'button':
10954 case 'input':
10955 case 'select':
10956 case 'textarea':
10957 return !!props.autoFocus;
10958
10959 case 'img':
10960 return true;
10961
10962 default:
10963 return false;
10964 }
10965}
10966function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
10967 {
10968 var hostContextDev = hostContext;
10969
10970 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
10971 var string = '' + newProps.children;
10972 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10973 validateDOMNesting(null, string, ownAncestorInfo);
10974 }
10975 }
10976
10977 return diffProperties(domElement, type, oldProps, newProps);
10978}
10979function shouldSetTextContent(type, props) {
10980 return type === 'textarea' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
10981}
10982function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
10983 {
10984 var hostContextDev = hostContext;
10985 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
10986 }
10987
10988 var textNode = createTextNode(text, rootContainerInstance);
10989 precacheFiberNode(internalInstanceHandle, textNode);
10990 return textNode;
10991}
10992function getCurrentEventPriority() {
10993 var currentEvent = window.event;
10994
10995 if (currentEvent === undefined) {
10996 return DefaultEventPriority;
10997 }
10998
10999 return getEventPriority(currentEvent.type);
11000}
11001// if a component just imports ReactDOM (e.g. for findDOMNode).
11002// Some environments might not have setTimeout or clearTimeout.
11003
11004var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
11005var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
11006var noTimeout = -1;
11007var localPromise = typeof Promise === 'function' ? Promise : undefined; // -------------------
11008var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : typeof localPromise !== 'undefined' ? function (callback) {
11009 return localPromise.resolve(null).then(callback).catch(handleErrorInNextTick);
11010} : scheduleTimeout; // TODO: Determine the best fallback here.
11011
11012function handleErrorInNextTick(error) {
11013 setTimeout(function () {
11014 throw error;
11015 });
11016} // -------------------
11017function commitMount(domElement, type, newProps, internalInstanceHandle) {
11018 // Despite the naming that might imply otherwise, this method only
11019 // fires if there is an `Update` effect scheduled during mounting.
11020 // This happens if `finalizeInitialChildren` returns `true` (which it
11021 // does to implement the `autoFocus` attribute on the client). But
11022 // there are also other cases when this might happen (such as patching
11023 // up text content during hydration mismatch). So we'll check this again.
11024 switch (type) {
11025 case 'button':
11026 case 'input':
11027 case 'select':
11028 case 'textarea':
11029 if (newProps.autoFocus) {
11030 domElement.focus();
11031 }
11032
11033 return;
11034
11035 case 'img':
11036 {
11037 if (newProps.src) {
11038 domElement.src = newProps.src;
11039 }
11040
11041 return;
11042 }
11043 }
11044}
11045function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
11046 // Apply the diff to the DOM node.
11047 updateProperties(domElement, updatePayload, type, oldProps, newProps); // Update the props handle so that we know which props are the ones with
11048 // with current event handlers.
11049
11050 updateFiberProps(domElement, newProps);
11051}
11052function resetTextContent(domElement) {
11053 setTextContent(domElement, '');
11054}
11055function commitTextUpdate(textInstance, oldText, newText) {
11056 textInstance.nodeValue = newText;
11057}
11058function appendChild(parentInstance, child) {
11059 parentInstance.appendChild(child);
11060}
11061function appendChildToContainer(container, child) {
11062 var parentNode;
11063
11064 if (container.nodeType === COMMENT_NODE) {
11065 parentNode = container.parentNode;
11066 parentNode.insertBefore(child, container);
11067 } else {
11068 parentNode = container;
11069 parentNode.appendChild(child);
11070 } // This container might be used for a portal.
11071 // If something inside a portal is clicked, that click should bubble
11072 // through the React tree. However, on Mobile Safari the click would
11073 // never bubble through the *DOM* tree unless an ancestor with onclick
11074 // event exists. So we wouldn't see it and dispatch it.
11075 // This is why we ensure that non React root containers have inline onclick
11076 // defined.
11077 // https://github.com/facebook/react/issues/11918
11078
11079
11080 var reactRootContainer = container._reactRootContainer;
11081
11082 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
11083 // TODO: This cast may not be sound for SVG, MathML or custom elements.
11084 trapClickOnNonInteractiveElement(parentNode);
11085 }
11086}
11087function insertBefore(parentInstance, child, beforeChild) {
11088 parentInstance.insertBefore(child, beforeChild);
11089}
11090function insertInContainerBefore(container, child, beforeChild) {
11091 if (container.nodeType === COMMENT_NODE) {
11092 container.parentNode.insertBefore(child, beforeChild);
11093 } else {
11094 container.insertBefore(child, beforeChild);
11095 }
11096}
11097
11098function removeChild(parentInstance, child) {
11099 parentInstance.removeChild(child);
11100}
11101function removeChildFromContainer(container, child) {
11102 if (container.nodeType === COMMENT_NODE) {
11103 container.parentNode.removeChild(child);
11104 } else {
11105 container.removeChild(child);
11106 }
11107}
11108function clearSuspenseBoundary(parentInstance, suspenseInstance) {
11109 var node = suspenseInstance; // Delete all nodes within this suspense boundary.
11110 // There might be nested nodes so we need to keep track of how
11111 // deep we are and only break out when we're back on top.
11112
11113 var depth = 0;
11114
11115 do {
11116 var nextNode = node.nextSibling;
11117 parentInstance.removeChild(node);
11118
11119 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
11120 var data = nextNode.data;
11121
11122 if (data === SUSPENSE_END_DATA) {
11123 if (depth === 0) {
11124 parentInstance.removeChild(nextNode); // Retry if any event replaying was blocked on this.
11125
11126 retryIfBlockedOn(suspenseInstance);
11127 return;
11128 } else {
11129 depth--;
11130 }
11131 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) {
11132 depth++;
11133 }
11134 }
11135
11136 node = nextNode;
11137 } while (node); // TODO: Warn, we didn't find the end comment boundary.
11138 // Retry if any event replaying was blocked on this.
11139
11140
11141 retryIfBlockedOn(suspenseInstance);
11142}
11143function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
11144 if (container.nodeType === COMMENT_NODE) {
11145 clearSuspenseBoundary(container.parentNode, suspenseInstance);
11146 } else if (container.nodeType === ELEMENT_NODE) {
11147 clearSuspenseBoundary(container, suspenseInstance);
11148 } // Retry if any event replaying was blocked on this.
11149
11150
11151 retryIfBlockedOn(container);
11152}
11153function hideInstance(instance) {
11154 // TODO: Does this work for all element types? What about MathML? Should we
11155 // pass host context to this method?
11156 instance = instance;
11157 var style = instance.style;
11158
11159 if (typeof style.setProperty === 'function') {
11160 style.setProperty('display', 'none', 'important');
11161 } else {
11162 style.display = 'none';
11163 }
11164}
11165function hideTextInstance(textInstance) {
11166 textInstance.nodeValue = '';
11167}
11168function unhideInstance(instance, props) {
11169 instance = instance;
11170 var styleProp = props[STYLE$1];
11171 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
11172 instance.style.display = dangerousStyleValue('display', display);
11173}
11174function unhideTextInstance(textInstance, text) {
11175 textInstance.nodeValue = text;
11176}
11177function clearContainer(container) {
11178 if (container.nodeType === ELEMENT_NODE) {
11179 container.textContent = '';
11180 } else if (container.nodeType === DOCUMENT_NODE) {
11181 if (container.documentElement) {
11182 container.removeChild(container.documentElement);
11183 }
11184 }
11185} // -------------------
11186function canHydrateInstance(instance, type, props) {
11187 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
11188 return null;
11189 } // This has now been refined to an element node.
11190
11191
11192 return instance;
11193}
11194function canHydrateTextInstance(instance, text) {
11195 if (text === '' || instance.nodeType !== TEXT_NODE) {
11196 // Empty strings are not parsed by HTML so there won't be a correct match here.
11197 return null;
11198 } // This has now been refined to a text node.
11199
11200
11201 return instance;
11202}
11203function canHydrateSuspenseInstance(instance) {
11204 if (instance.nodeType !== COMMENT_NODE) {
11205 // Empty strings are not parsed by HTML so there won't be a correct match here.
11206 return null;
11207 } // This has now been refined to a suspense node.
11208
11209
11210 return instance;
11211}
11212function isSuspenseInstancePending(instance) {
11213 return instance.data === SUSPENSE_PENDING_START_DATA;
11214}
11215function isSuspenseInstanceFallback(instance) {
11216 return instance.data === SUSPENSE_FALLBACK_START_DATA;
11217}
11218function getSuspenseInstanceFallbackErrorDetails(instance) {
11219 var dataset = instance.nextSibling && instance.nextSibling.dataset;
11220 var digest, message, stack;
11221
11222 if (dataset) {
11223 digest = dataset.dgst;
11224
11225 {
11226 message = dataset.msg;
11227 stack = dataset.stck;
11228 }
11229 }
11230
11231 {
11232 return {
11233 message: message,
11234 digest: digest,
11235 stack: stack
11236 };
11237 } // let value = {message: undefined, hash: undefined};
11238 // const nextSibling = instance.nextSibling;
11239 // if (nextSibling) {
11240 // const dataset = ((nextSibling: any): HTMLTemplateElement).dataset;
11241 // value.message = dataset.msg;
11242 // value.hash = dataset.hash;
11243 // if (true) {
11244 // value.stack = dataset.stack;
11245 // }
11246 // }
11247 // return value;
11248
11249}
11250function registerSuspenseInstanceRetry(instance, callback) {
11251 instance._reactRetry = callback;
11252}
11253
11254function getNextHydratable(node) {
11255 // Skip non-hydratable nodes.
11256 for (; node != null; node = node.nextSibling) {
11257 var nodeType = node.nodeType;
11258
11259 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
11260 break;
11261 }
11262
11263 if (nodeType === COMMENT_NODE) {
11264 var nodeData = node.data;
11265
11266 if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) {
11267 break;
11268 }
11269
11270 if (nodeData === SUSPENSE_END_DATA) {
11271 return null;
11272 }
11273 }
11274 }
11275
11276 return node;
11277}
11278
11279function getNextHydratableSibling(instance) {
11280 return getNextHydratable(instance.nextSibling);
11281}
11282function getFirstHydratableChild(parentInstance) {
11283 return getNextHydratable(parentInstance.firstChild);
11284}
11285function getFirstHydratableChildWithinContainer(parentContainer) {
11286 return getNextHydratable(parentContainer.firstChild);
11287}
11288function getFirstHydratableChildWithinSuspenseInstance(parentInstance) {
11289 return getNextHydratable(parentInstance.nextSibling);
11290}
11291function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle, shouldWarnDev) {
11292 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
11293 // get attached.
11294
11295 updateFiberProps(instance, props);
11296 var parentNamespace;
11297
11298 {
11299 var hostContextDev = hostContext;
11300 parentNamespace = hostContextDev.namespace;
11301 } // TODO: Temporary hack to check if we're in a concurrent root. We can delete
11302 // when the legacy root API is removed.
11303
11304
11305 var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
11306 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance, isConcurrentMode, shouldWarnDev);
11307}
11308function hydrateTextInstance(textInstance, text, internalInstanceHandle, shouldWarnDev) {
11309 precacheFiberNode(internalInstanceHandle, textInstance); // TODO: Temporary hack to check if we're in a concurrent root. We can delete
11310 // when the legacy root API is removed.
11311
11312 var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
11313 return diffHydratedText(textInstance, text);
11314}
11315function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) {
11316 precacheFiberNode(internalInstanceHandle, suspenseInstance);
11317}
11318function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
11319 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
11320 // There might be nested nodes so we need to keep track of how
11321 // deep we are and only break out when we're back on top.
11322
11323 var depth = 0;
11324
11325 while (node) {
11326 if (node.nodeType === COMMENT_NODE) {
11327 var data = node.data;
11328
11329 if (data === SUSPENSE_END_DATA) {
11330 if (depth === 0) {
11331 return getNextHydratableSibling(node);
11332 } else {
11333 depth--;
11334 }
11335 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
11336 depth++;
11337 }
11338 }
11339
11340 node = node.nextSibling;
11341 } // TODO: Warn, we didn't find the end comment boundary.
11342
11343
11344 return null;
11345} // Returns the SuspenseInstance if this node is a direct child of a
11346// SuspenseInstance. I.e. if its previous sibling is a Comment with
11347// SUSPENSE_x_START_DATA. Otherwise, null.
11348
11349function getParentSuspenseInstance(targetInstance) {
11350 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
11351 // There might be nested nodes so we need to keep track of how
11352 // deep we are and only break out when we're back on top.
11353
11354 var depth = 0;
11355
11356 while (node) {
11357 if (node.nodeType === COMMENT_NODE) {
11358 var data = node.data;
11359
11360 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
11361 if (depth === 0) {
11362 return node;
11363 } else {
11364 depth--;
11365 }
11366 } else if (data === SUSPENSE_END_DATA) {
11367 depth++;
11368 }
11369 }
11370
11371 node = node.previousSibling;
11372 }
11373
11374 return null;
11375}
11376function commitHydratedContainer(container) {
11377 // Retry if any event replaying was blocked on this.
11378 retryIfBlockedOn(container);
11379}
11380function commitHydratedSuspenseInstance(suspenseInstance) {
11381 // Retry if any event replaying was blocked on this.
11382 retryIfBlockedOn(suspenseInstance);
11383}
11384function shouldDeleteUnhydratedTailInstances(parentType) {
11385 return parentType !== 'head' && parentType !== 'body';
11386}
11387function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text, isConcurrentMode) {
11388 var shouldWarnDev = true;
11389 checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
11390}
11391function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text, isConcurrentMode) {
11392 if (parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11393 var shouldWarnDev = true;
11394 checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
11395 }
11396}
11397function didNotHydrateInstanceWithinContainer(parentContainer, instance) {
11398 {
11399 if (instance.nodeType === ELEMENT_NODE) {
11400 warnForDeletedHydratableElement(parentContainer, instance);
11401 } else if (instance.nodeType === COMMENT_NODE) ; else {
11402 warnForDeletedHydratableText(parentContainer, instance);
11403 }
11404 }
11405}
11406function didNotHydrateInstanceWithinSuspenseInstance(parentInstance, instance) {
11407 {
11408 // $FlowFixMe: Only Element or Document can be parent nodes.
11409 var parentNode = parentInstance.parentNode;
11410
11411 if (parentNode !== null) {
11412 if (instance.nodeType === ELEMENT_NODE) {
11413 warnForDeletedHydratableElement(parentNode, instance);
11414 } else if (instance.nodeType === COMMENT_NODE) ; else {
11415 warnForDeletedHydratableText(parentNode, instance);
11416 }
11417 }
11418 }
11419}
11420function didNotHydrateInstance(parentType, parentProps, parentInstance, instance, isConcurrentMode) {
11421 {
11422 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11423 if (instance.nodeType === ELEMENT_NODE) {
11424 warnForDeletedHydratableElement(parentInstance, instance);
11425 } else if (instance.nodeType === COMMENT_NODE) ; else {
11426 warnForDeletedHydratableText(parentInstance, instance);
11427 }
11428 }
11429 }
11430}
11431function didNotFindHydratableInstanceWithinContainer(parentContainer, type, props) {
11432 {
11433 warnForInsertedHydratedElement(parentContainer, type);
11434 }
11435}
11436function didNotFindHydratableTextInstanceWithinContainer(parentContainer, text) {
11437 {
11438 warnForInsertedHydratedText(parentContainer, text);
11439 }
11440}
11441function didNotFindHydratableInstanceWithinSuspenseInstance(parentInstance, type, props) {
11442 {
11443 // $FlowFixMe: Only Element or Document can be parent nodes.
11444 var parentNode = parentInstance.parentNode;
11445 if (parentNode !== null) warnForInsertedHydratedElement(parentNode, type);
11446 }
11447}
11448function didNotFindHydratableTextInstanceWithinSuspenseInstance(parentInstance, text) {
11449 {
11450 // $FlowFixMe: Only Element or Document can be parent nodes.
11451 var parentNode = parentInstance.parentNode;
11452 if (parentNode !== null) warnForInsertedHydratedText(parentNode, text);
11453 }
11454}
11455function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props, isConcurrentMode) {
11456 {
11457 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11458 warnForInsertedHydratedElement(parentInstance, type);
11459 }
11460 }
11461}
11462function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text, isConcurrentMode) {
11463 {
11464 if (isConcurrentMode || parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11465 warnForInsertedHydratedText(parentInstance, text);
11466 }
11467 }
11468}
11469function errorHydratingContainer(parentContainer) {
11470 {
11471 // TODO: This gets logged by onRecoverableError, too, so we should be
11472 // able to remove it.
11473 error('An error occurred during hydration. The server HTML was replaced with client content in <%s>.', parentContainer.nodeName.toLowerCase());
11474 }
11475}
11476function preparePortalMount(portalInstance) {
11477 listenToAllSupportedEvents(portalInstance);
11478}
11479
11480var randomKey = Math.random().toString(36).slice(2);
11481var internalInstanceKey = '__reactFiber$' + randomKey;
11482var internalPropsKey = '__reactProps$' + randomKey;
11483var internalContainerInstanceKey = '__reactContainer$' + randomKey;
11484var internalEventHandlersKey = '__reactEvents$' + randomKey;
11485var internalEventHandlerListenersKey = '__reactListeners$' + randomKey;
11486var internalEventHandlesSetKey = '__reactHandles$' + randomKey;
11487function detachDeletedInstance(node) {
11488 // TODO: This function is only called on host components. I don't think all of
11489 // these fields are relevant.
11490 delete node[internalInstanceKey];
11491 delete node[internalPropsKey];
11492 delete node[internalEventHandlersKey];
11493 delete node[internalEventHandlerListenersKey];
11494 delete node[internalEventHandlesSetKey];
11495}
11496function precacheFiberNode(hostInst, node) {
11497 node[internalInstanceKey] = hostInst;
11498}
11499function markContainerAsRoot(hostRoot, node) {
11500 node[internalContainerInstanceKey] = hostRoot;
11501}
11502function unmarkContainerAsRoot(node) {
11503 node[internalContainerInstanceKey] = null;
11504}
11505function isContainerMarkedAsRoot(node) {
11506 return !!node[internalContainerInstanceKey];
11507} // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
11508// If the target node is part of a hydrated or not yet rendered subtree, then
11509// this may also return a SuspenseComponent or HostRoot to indicate that.
11510// Conceptually the HostRoot fiber is a child of the Container node. So if you
11511// pass the Container node as the targetNode, you will not actually get the
11512// HostRoot back. To get to the HostRoot, you need to pass a child of it.
11513// The same thing applies to Suspense boundaries.
11514
11515function getClosestInstanceFromNode(targetNode) {
11516 var targetInst = targetNode[internalInstanceKey];
11517
11518 if (targetInst) {
11519 // Don't return HostRoot or SuspenseComponent here.
11520 return targetInst;
11521 } // If the direct event target isn't a React owned DOM node, we need to look
11522 // to see if one of its parents is a React owned DOM node.
11523
11524
11525 var parentNode = targetNode.parentNode;
11526
11527 while (parentNode) {
11528 // We'll check if this is a container root that could include
11529 // React nodes in the future. We need to check this first because
11530 // if we're a child of a dehydrated container, we need to first
11531 // find that inner container before moving on to finding the parent
11532 // instance. Note that we don't check this field on the targetNode
11533 // itself because the fibers are conceptually between the container
11534 // node and the first child. It isn't surrounding the container node.
11535 // If it's not a container, we check if it's an instance.
11536 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
11537
11538 if (targetInst) {
11539 // Since this wasn't the direct target of the event, we might have
11540 // stepped past dehydrated DOM nodes to get here. However they could
11541 // also have been non-React nodes. We need to answer which one.
11542 // If we the instance doesn't have any children, then there can't be
11543 // a nested suspense boundary within it. So we can use this as a fast
11544 // bailout. Most of the time, when people add non-React children to
11545 // the tree, it is using a ref to a child-less DOM node.
11546 // Normally we'd only need to check one of the fibers because if it
11547 // has ever gone from having children to deleting them or vice versa
11548 // it would have deleted the dehydrated boundary nested inside already.
11549 // However, since the HostRoot starts out with an alternate it might
11550 // have one on the alternate so we need to check in case this was a
11551 // root.
11552 var alternate = targetInst.alternate;
11553
11554 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
11555 // Next we need to figure out if the node that skipped past is
11556 // nested within a dehydrated boundary and if so, which one.
11557 var suspenseInstance = getParentSuspenseInstance(targetNode);
11558
11559 while (suspenseInstance !== null) {
11560 // We found a suspense instance. That means that we haven't
11561 // hydrated it yet. Even though we leave the comments in the
11562 // DOM after hydrating, and there are boundaries in the DOM
11563 // that could already be hydrated, we wouldn't have found them
11564 // through this pass since if the target is hydrated it would
11565 // have had an internalInstanceKey on it.
11566 // Let's get the fiber associated with the SuspenseComponent
11567 // as the deepest instance.
11568 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
11569
11570 if (targetSuspenseInst) {
11571 return targetSuspenseInst;
11572 } // If we don't find a Fiber on the comment, it might be because
11573 // we haven't gotten to hydrate it yet. There might still be a
11574 // parent boundary that hasn't above this one so we need to find
11575 // the outer most that is known.
11576
11577
11578 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
11579 // host component also hasn't hydrated yet. We can return it
11580 // below since it will bail out on the isMounted check later.
11581 }
11582 }
11583
11584 return targetInst;
11585 }
11586
11587 targetNode = parentNode;
11588 parentNode = targetNode.parentNode;
11589 }
11590
11591 return null;
11592}
11593/**
11594 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
11595 * instance, or null if the node was not rendered by this React.
11596 */
11597
11598function getInstanceFromNode(node) {
11599 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
11600
11601 if (inst) {
11602 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
11603 return inst;
11604 } else {
11605 return null;
11606 }
11607 }
11608
11609 return null;
11610}
11611/**
11612 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
11613 * DOM node.
11614 */
11615
11616function getNodeFromInstance(inst) {
11617 if (inst.tag === HostComponent || inst.tag === HostText) {
11618 // In Fiber this, is just the state node right now. We assume it will be
11619 // a host component or host text.
11620 return inst.stateNode;
11621 } // Without this first invariant, passing a non-DOM-component triggers the next
11622 // invariant for a missing parent, which is super confusing.
11623
11624
11625 throw new Error('getNodeFromInstance: Invalid argument.');
11626}
11627function getFiberCurrentPropsFromNode(node) {
11628 return node[internalPropsKey] || null;
11629}
11630function updateFiberProps(node, props) {
11631 node[internalPropsKey] = props;
11632}
11633function getEventListenerSet(node) {
11634 var elementListenerSet = node[internalEventHandlersKey];
11635
11636 if (elementListenerSet === undefined) {
11637 elementListenerSet = node[internalEventHandlersKey] = new Set();
11638 }
11639
11640 return elementListenerSet;
11641}
11642
11643var loggedTypeFailures = {};
11644var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
11645
11646function setCurrentlyValidatingElement(element) {
11647 {
11648 if (element) {
11649 var owner = element._owner;
11650 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
11651 ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
11652 } else {
11653 ReactDebugCurrentFrame$1.setExtraStackFrame(null);
11654 }
11655 }
11656}
11657
11658function checkPropTypes(typeSpecs, values, location, componentName, element) {
11659 {
11660 // $FlowFixMe This is okay but Flow doesn't know it.
11661 var has = Function.call.bind(hasOwnProperty);
11662
11663 for (var typeSpecName in typeSpecs) {
11664 if (has(typeSpecs, typeSpecName)) {
11665 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
11666 // fail the render phase where it didn't fail before. So we log it.
11667 // After these have been cleaned up, we'll let them throw.
11668
11669 try {
11670 // This is intentionally an invariant that gets caught. It's the same
11671 // behavior as without this statement except with a better message.
11672 if (typeof typeSpecs[typeSpecName] !== 'function') {
11673 // eslint-disable-next-line react-internal/prod-error-codes
11674 var err = Error((componentName || 'React class') + ': ' + location + ' type `' + typeSpecName + '` is invalid; ' + 'it must be a function, usually from the `prop-types` package, but received `' + typeof typeSpecs[typeSpecName] + '`.' + 'This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`.');
11675 err.name = 'Invariant Violation';
11676 throw err;
11677 }
11678
11679 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
11680 } catch (ex) {
11681 error$1 = ex;
11682 }
11683
11684 if (error$1 && !(error$1 instanceof Error)) {
11685 setCurrentlyValidatingElement(element);
11686
11687 error('%s: type specification of %s' + ' `%s` is invalid; the type checker ' + 'function must return `null` or an `Error` but returned a %s. ' + 'You may have forgotten to pass an argument to the type checker ' + 'creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and ' + 'shape all require an argument).', componentName || 'React class', location, typeSpecName, typeof error$1);
11688
11689 setCurrentlyValidatingElement(null);
11690 }
11691
11692 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
11693 // Only monitor this failure once because there tends to be a lot of the
11694 // same error.
11695 loggedTypeFailures[error$1.message] = true;
11696 setCurrentlyValidatingElement(element);
11697
11698 error('Failed %s type: %s', location, error$1.message);
11699
11700 setCurrentlyValidatingElement(null);
11701 }
11702 }
11703 }
11704 }
11705}
11706
11707var valueStack = [];
11708var fiberStack;
11709
11710{
11711 fiberStack = [];
11712}
11713
11714var index = -1;
11715
11716function createCursor(defaultValue) {
11717 return {
11718 current: defaultValue
11719 };
11720}
11721
11722function pop(cursor, fiber) {
11723 if (index < 0) {
11724 {
11725 error('Unexpected pop.');
11726 }
11727
11728 return;
11729 }
11730
11731 {
11732 if (fiber !== fiberStack[index]) {
11733 error('Unexpected Fiber popped.');
11734 }
11735 }
11736
11737 cursor.current = valueStack[index];
11738 valueStack[index] = null;
11739
11740 {
11741 fiberStack[index] = null;
11742 }
11743
11744 index--;
11745}
11746
11747function push(cursor, value, fiber) {
11748 index++;
11749 valueStack[index] = cursor.current;
11750
11751 {
11752 fiberStack[index] = fiber;
11753 }
11754
11755 cursor.current = value;
11756}
11757
11758var warnedAboutMissingGetChildContext;
11759
11760{
11761 warnedAboutMissingGetChildContext = {};
11762}
11763
11764var emptyContextObject = {};
11765
11766{
11767 Object.freeze(emptyContextObject);
11768} // A cursor to the current merged context object on the stack.
11769
11770
11771var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
11772
11773var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
11774// We use this to get access to the parent context after we have already
11775// pushed the next context provider, and now need to merge their contexts.
11776
11777var previousContext = emptyContextObject;
11778
11779function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
11780 {
11781 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
11782 // If the fiber is a context provider itself, when we read its context
11783 // we may have already pushed its own child context on the stack. A context
11784 // provider should not "see" its own child context. Therefore we read the
11785 // previous (parent) context instead for a context provider.
11786 return previousContext;
11787 }
11788
11789 return contextStackCursor.current;
11790 }
11791}
11792
11793function cacheContext(workInProgress, unmaskedContext, maskedContext) {
11794 {
11795 var instance = workInProgress.stateNode;
11796 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
11797 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
11798 }
11799}
11800
11801function getMaskedContext(workInProgress, unmaskedContext) {
11802 {
11803 var type = workInProgress.type;
11804 var contextTypes = type.contextTypes;
11805
11806 if (!contextTypes) {
11807 return emptyContextObject;
11808 } // Avoid recreating masked context unless unmasked context has changed.
11809 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
11810 // This may trigger infinite loops if componentWillReceiveProps calls setState.
11811
11812
11813 var instance = workInProgress.stateNode;
11814
11815 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
11816 return instance.__reactInternalMemoizedMaskedChildContext;
11817 }
11818
11819 var context = {};
11820
11821 for (var key in contextTypes) {
11822 context[key] = unmaskedContext[key];
11823 }
11824
11825 {
11826 var name = getComponentNameFromFiber(workInProgress) || 'Unknown';
11827 checkPropTypes(contextTypes, context, 'context', name);
11828 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
11829 // Context is created before the class component is instantiated so check for instance.
11830
11831
11832 if (instance) {
11833 cacheContext(workInProgress, unmaskedContext, context);
11834 }
11835
11836 return context;
11837 }
11838}
11839
11840function hasContextChanged() {
11841 {
11842 return didPerformWorkStackCursor.current;
11843 }
11844}
11845
11846function isContextProvider(type) {
11847 {
11848 var childContextTypes = type.childContextTypes;
11849 return childContextTypes !== null && childContextTypes !== undefined;
11850 }
11851}
11852
11853function popContext(fiber) {
11854 {
11855 pop(didPerformWorkStackCursor, fiber);
11856 pop(contextStackCursor, fiber);
11857 }
11858}
11859
11860function popTopLevelContextObject(fiber) {
11861 {
11862 pop(didPerformWorkStackCursor, fiber);
11863 pop(contextStackCursor, fiber);
11864 }
11865}
11866
11867function pushTopLevelContextObject(fiber, context, didChange) {
11868 {
11869 if (contextStackCursor.current !== emptyContextObject) {
11870 throw new Error('Unexpected context found on stack. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11871 }
11872
11873 push(contextStackCursor, context, fiber);
11874 push(didPerformWorkStackCursor, didChange, fiber);
11875 }
11876}
11877
11878function processChildContext(fiber, type, parentContext) {
11879 {
11880 var instance = fiber.stateNode;
11881 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
11882 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
11883
11884 if (typeof instance.getChildContext !== 'function') {
11885 {
11886 var componentName = getComponentNameFromFiber(fiber) || 'Unknown';
11887
11888 if (!warnedAboutMissingGetChildContext[componentName]) {
11889 warnedAboutMissingGetChildContext[componentName] = true;
11890
11891 error('%s.childContextTypes is specified but there is no getChildContext() method ' + 'on the instance. You can either define getChildContext() on %s or remove ' + 'childContextTypes from it.', componentName, componentName);
11892 }
11893 }
11894
11895 return parentContext;
11896 }
11897
11898 var childContext = instance.getChildContext();
11899
11900 for (var contextKey in childContext) {
11901 if (!(contextKey in childContextTypes)) {
11902 throw new Error((getComponentNameFromFiber(fiber) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes.");
11903 }
11904 }
11905
11906 {
11907 var name = getComponentNameFromFiber(fiber) || 'Unknown';
11908 checkPropTypes(childContextTypes, childContext, 'child context', name);
11909 }
11910
11911 return assign({}, parentContext, childContext);
11912 }
11913}
11914
11915function pushContextProvider(workInProgress) {
11916 {
11917 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
11918 // If the instance does not exist yet, we will push null at first,
11919 // and replace it on the stack later when invalidating the context.
11920
11921 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
11922 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
11923
11924 previousContext = contextStackCursor.current;
11925 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
11926 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
11927 return true;
11928 }
11929}
11930
11931function invalidateContextProvider(workInProgress, type, didChange) {
11932 {
11933 var instance = workInProgress.stateNode;
11934
11935 if (!instance) {
11936 throw new Error('Expected to have an instance by this point. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11937 }
11938
11939 if (didChange) {
11940 // Merge parent and own context.
11941 // Skip this if we're not updating due to sCU.
11942 // This avoids unnecessarily recomputing memoized values.
11943 var mergedContext = processChildContext(workInProgress, type, previousContext);
11944 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
11945 // It is important to unwind the context in the reverse order.
11946
11947 pop(didPerformWorkStackCursor, workInProgress);
11948 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
11949
11950 push(contextStackCursor, mergedContext, workInProgress);
11951 push(didPerformWorkStackCursor, didChange, workInProgress);
11952 } else {
11953 pop(didPerformWorkStackCursor, workInProgress);
11954 push(didPerformWorkStackCursor, didChange, workInProgress);
11955 }
11956 }
11957}
11958
11959function findCurrentUnmaskedContext(fiber) {
11960 {
11961 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11962 // makes sense elsewhere
11963 if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) {
11964 throw new Error('Expected subtree parent to be a mounted class component. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11965 }
11966
11967 var node = fiber;
11968
11969 do {
11970 switch (node.tag) {
11971 case HostRoot:
11972 return node.stateNode.context;
11973
11974 case ClassComponent:
11975 {
11976 var Component = node.type;
11977
11978 if (isContextProvider(Component)) {
11979 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11980 }
11981
11982 break;
11983 }
11984 }
11985
11986 node = node.return;
11987 } while (node !== null);
11988
11989 throw new Error('Found unexpected detached subtree parent. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11990 }
11991}
11992
11993var LegacyRoot = 0;
11994var ConcurrentRoot = 1;
11995
11996var syncQueue = null;
11997var includesLegacySyncCallbacks = false;
11998var isFlushingSyncQueue = false;
11999function scheduleSyncCallback(callback) {
12000 // Push this callback into an internal queue. We'll flush these either in
12001 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
12002 if (syncQueue === null) {
12003 syncQueue = [callback];
12004 } else {
12005 // Push onto existing queue. Don't need to schedule a callback because
12006 // we already scheduled one when we created the queue.
12007 syncQueue.push(callback);
12008 }
12009}
12010function scheduleLegacySyncCallback(callback) {
12011 includesLegacySyncCallbacks = true;
12012 scheduleSyncCallback(callback);
12013}
12014function flushSyncCallbacksOnlyInLegacyMode() {
12015 // Only flushes the queue if there's a legacy sync callback scheduled.
12016 // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So
12017 // it might make more sense for the queue to be a list of roots instead of a
12018 // list of generic callbacks. Then we can have two: one for legacy roots, one
12019 // for concurrent roots. And this method would only flush the legacy ones.
12020 if (includesLegacySyncCallbacks) {
12021 flushSyncCallbacks();
12022 }
12023}
12024function flushSyncCallbacks() {
12025 if (!isFlushingSyncQueue && syncQueue !== null) {
12026 // Prevent re-entrance.
12027 isFlushingSyncQueue = true;
12028 var i = 0;
12029 var previousUpdatePriority = getCurrentUpdatePriority();
12030
12031 try {
12032 var isSync = true;
12033 var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this
12034 // queue is in the render or commit phases.
12035
12036 setCurrentUpdatePriority(DiscreteEventPriority);
12037
12038 for (; i < queue.length; i++) {
12039 var callback = queue[i];
12040
12041 do {
12042 callback = callback(isSync);
12043 } while (callback !== null);
12044 }
12045
12046 syncQueue = null;
12047 includesLegacySyncCallbacks = false;
12048 } catch (error) {
12049 // If something throws, leave the remaining callbacks on the queue.
12050 if (syncQueue !== null) {
12051 syncQueue = syncQueue.slice(i + 1);
12052 } // Resume flushing in the next tick
12053
12054
12055 scheduleCallback(ImmediatePriority, flushSyncCallbacks);
12056 throw error;
12057 } finally {
12058 setCurrentUpdatePriority(previousUpdatePriority);
12059 isFlushingSyncQueue = false;
12060 }
12061 }
12062
12063 return null;
12064}
12065
12066// TODO: Use the unified fiber stack module instead of this local one?
12067// Intentionally not using it yet to derisk the initial implementation, because
12068// the way we push/pop these values is a bit unusual. If there's a mistake, I'd
12069// rather the ids be wrong than crash the whole reconciler.
12070var forkStack = [];
12071var forkStackIndex = 0;
12072var treeForkProvider = null;
12073var treeForkCount = 0;
12074var idStack = [];
12075var idStackIndex = 0;
12076var treeContextProvider = null;
12077var treeContextId = 1;
12078var treeContextOverflow = '';
12079function isForkedChild(workInProgress) {
12080 warnIfNotHydrating();
12081 return (workInProgress.flags & Forked) !== NoFlags;
12082}
12083function getForksAtLevel(workInProgress) {
12084 warnIfNotHydrating();
12085 return treeForkCount;
12086}
12087function getTreeId() {
12088 var overflow = treeContextOverflow;
12089 var idWithLeadingBit = treeContextId;
12090 var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit);
12091 return id.toString(32) + overflow;
12092}
12093function pushTreeFork(workInProgress, totalChildren) {
12094 // This is called right after we reconcile an array (or iterator) of child
12095 // fibers, because that's the only place where we know how many children in
12096 // the whole set without doing extra work later, or storing addtional
12097 // information on the fiber.
12098 //
12099 // That's why this function is separate from pushTreeId — it's called during
12100 // the render phase of the fork parent, not the child, which is where we push
12101 // the other context values.
12102 //
12103 // In the Fizz implementation this is much simpler because the child is
12104 // rendered in the same callstack as the parent.
12105 //
12106 // It might be better to just add a `forks` field to the Fiber type. It would
12107 // make this module simpler.
12108 warnIfNotHydrating();
12109 forkStack[forkStackIndex++] = treeForkCount;
12110 forkStack[forkStackIndex++] = treeForkProvider;
12111 treeForkProvider = workInProgress;
12112 treeForkCount = totalChildren;
12113}
12114function pushTreeId(workInProgress, totalChildren, index) {
12115 warnIfNotHydrating();
12116 idStack[idStackIndex++] = treeContextId;
12117 idStack[idStackIndex++] = treeContextOverflow;
12118 idStack[idStackIndex++] = treeContextProvider;
12119 treeContextProvider = workInProgress;
12120 var baseIdWithLeadingBit = treeContextId;
12121 var baseOverflow = treeContextOverflow; // The leftmost 1 marks the end of the sequence, non-inclusive. It's not part
12122 // of the id; we use it to account for leading 0s.
12123
12124 var baseLength = getBitLength(baseIdWithLeadingBit) - 1;
12125 var baseId = baseIdWithLeadingBit & ~(1 << baseLength);
12126 var slot = index + 1;
12127 var length = getBitLength(totalChildren) + baseLength; // 30 is the max length we can store without overflowing, taking into
12128 // consideration the leading 1 we use to mark the end of the sequence.
12129
12130 if (length > 30) {
12131 // We overflowed the bitwise-safe range. Fall back to slower algorithm.
12132 // This branch assumes the length of the base id is greater than 5; it won't
12133 // work for smaller ids, because you need 5 bits per character.
12134 //
12135 // We encode the id in multiple steps: first the base id, then the
12136 // remaining digits.
12137 //
12138 // Each 5 bit sequence corresponds to a single base 32 character. So for
12139 // example, if the current id is 23 bits long, we can convert 20 of those
12140 // bits into a string of 4 characters, with 3 bits left over.
12141 //
12142 // First calculate how many bits in the base id represent a complete
12143 // sequence of characters.
12144 var numberOfOverflowBits = baseLength - baseLength % 5; // Then create a bitmask that selects only those bits.
12145
12146 var newOverflowBits = (1 << numberOfOverflowBits) - 1; // Select the bits, and convert them to a base 32 string.
12147
12148 var newOverflow = (baseId & newOverflowBits).toString(32); // Now we can remove those bits from the base id.
12149
12150 var restOfBaseId = baseId >> numberOfOverflowBits;
12151 var restOfBaseLength = baseLength - numberOfOverflowBits; // Finally, encode the rest of the bits using the normal algorithm. Because
12152 // we made more room, this time it won't overflow.
12153
12154 var restOfLength = getBitLength(totalChildren) + restOfBaseLength;
12155 var restOfNewBits = slot << restOfBaseLength;
12156 var id = restOfNewBits | restOfBaseId;
12157 var overflow = newOverflow + baseOverflow;
12158 treeContextId = 1 << restOfLength | id;
12159 treeContextOverflow = overflow;
12160 } else {
12161 // Normal path
12162 var newBits = slot << baseLength;
12163
12164 var _id = newBits | baseId;
12165
12166 var _overflow = baseOverflow;
12167 treeContextId = 1 << length | _id;
12168 treeContextOverflow = _overflow;
12169 }
12170}
12171function pushMaterializedTreeId(workInProgress) {
12172 warnIfNotHydrating(); // This component materialized an id. This will affect any ids that appear
12173 // in its children.
12174
12175 var returnFiber = workInProgress.return;
12176
12177 if (returnFiber !== null) {
12178 var numberOfForks = 1;
12179 var slotIndex = 0;
12180 pushTreeFork(workInProgress, numberOfForks);
12181 pushTreeId(workInProgress, numberOfForks, slotIndex);
12182 }
12183}
12184
12185function getBitLength(number) {
12186 return 32 - clz32(number);
12187}
12188
12189function getLeadingBit(id) {
12190 return 1 << getBitLength(id) - 1;
12191}
12192
12193function popTreeContext(workInProgress) {
12194 // Restore the previous values.
12195 // This is a bit more complicated than other context-like modules in Fiber
12196 // because the same Fiber may appear on the stack multiple times and for
12197 // different reasons. We have to keep popping until the work-in-progress is
12198 // no longer at the top of the stack.
12199 while (workInProgress === treeForkProvider) {
12200 treeForkProvider = forkStack[--forkStackIndex];
12201 forkStack[forkStackIndex] = null;
12202 treeForkCount = forkStack[--forkStackIndex];
12203 forkStack[forkStackIndex] = null;
12204 }
12205
12206 while (workInProgress === treeContextProvider) {
12207 treeContextProvider = idStack[--idStackIndex];
12208 idStack[idStackIndex] = null;
12209 treeContextOverflow = idStack[--idStackIndex];
12210 idStack[idStackIndex] = null;
12211 treeContextId = idStack[--idStackIndex];
12212 idStack[idStackIndex] = null;
12213 }
12214}
12215function getSuspendedTreeContext() {
12216 warnIfNotHydrating();
12217
12218 if (treeContextProvider !== null) {
12219 return {
12220 id: treeContextId,
12221 overflow: treeContextOverflow
12222 };
12223 } else {
12224 return null;
12225 }
12226}
12227function restoreSuspendedTreeContext(workInProgress, suspendedContext) {
12228 warnIfNotHydrating();
12229 idStack[idStackIndex++] = treeContextId;
12230 idStack[idStackIndex++] = treeContextOverflow;
12231 idStack[idStackIndex++] = treeContextProvider;
12232 treeContextId = suspendedContext.id;
12233 treeContextOverflow = suspendedContext.overflow;
12234 treeContextProvider = workInProgress;
12235}
12236
12237function warnIfNotHydrating() {
12238 {
12239 if (!getIsHydrating()) {
12240 error('Expected to be hydrating. This is a bug in React. Please file ' + 'an issue.');
12241 }
12242 }
12243}
12244
12245// This may have been an insertion or a hydration.
12246
12247var hydrationParentFiber = null;
12248var nextHydratableInstance = null;
12249var isHydrating = false; // This flag allows for warning supression when we expect there to be mismatches
12250// due to earlier mismatches or a suspended fiber.
12251
12252var didSuspendOrErrorDEV = false; // Hydration errors that were thrown inside this boundary
12253
12254var hydrationErrors = null;
12255
12256function warnIfHydrating() {
12257 {
12258 if (isHydrating) {
12259 error('We should not be hydrating here. This is a bug in React. Please file a bug.');
12260 }
12261 }
12262}
12263
12264function markDidThrowWhileHydratingDEV() {
12265 {
12266 didSuspendOrErrorDEV = true;
12267 }
12268}
12269function didSuspendOrErrorWhileHydratingDEV() {
12270 {
12271 return didSuspendOrErrorDEV;
12272 }
12273}
12274
12275function enterHydrationState(fiber) {
12276
12277 var parentInstance = fiber.stateNode.containerInfo;
12278 nextHydratableInstance = getFirstHydratableChildWithinContainer(parentInstance);
12279 hydrationParentFiber = fiber;
12280 isHydrating = true;
12281 hydrationErrors = null;
12282 didSuspendOrErrorDEV = false;
12283 return true;
12284}
12285
12286function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) {
12287
12288 nextHydratableInstance = getFirstHydratableChildWithinSuspenseInstance(suspenseInstance);
12289 hydrationParentFiber = fiber;
12290 isHydrating = true;
12291 hydrationErrors = null;
12292 didSuspendOrErrorDEV = false;
12293
12294 if (treeContext !== null) {
12295 restoreSuspendedTreeContext(fiber, treeContext);
12296 }
12297
12298 return true;
12299}
12300
12301function warnUnhydratedInstance(returnFiber, instance) {
12302 {
12303 switch (returnFiber.tag) {
12304 case HostRoot:
12305 {
12306 didNotHydrateInstanceWithinContainer(returnFiber.stateNode.containerInfo, instance);
12307 break;
12308 }
12309
12310 case HostComponent:
12311 {
12312 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
12313 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance, // TODO: Delete this argument when we remove the legacy root API.
12314 isConcurrentMode);
12315 break;
12316 }
12317
12318 case SuspenseComponent:
12319 {
12320 var suspenseState = returnFiber.memoizedState;
12321 if (suspenseState.dehydrated !== null) didNotHydrateInstanceWithinSuspenseInstance(suspenseState.dehydrated, instance);
12322 break;
12323 }
12324 }
12325 }
12326}
12327
12328function deleteHydratableInstance(returnFiber, instance) {
12329 warnUnhydratedInstance(returnFiber, instance);
12330 var childToDelete = createFiberFromHostInstanceForDeletion();
12331 childToDelete.stateNode = instance;
12332 childToDelete.return = returnFiber;
12333 var deletions = returnFiber.deletions;
12334
12335 if (deletions === null) {
12336 returnFiber.deletions = [childToDelete];
12337 returnFiber.flags |= ChildDeletion;
12338 } else {
12339 deletions.push(childToDelete);
12340 }
12341}
12342
12343function warnNonhydratedInstance(returnFiber, fiber) {
12344 {
12345 if (didSuspendOrErrorDEV) {
12346 // Inside a boundary that already suspended. We're currently rendering the
12347 // siblings of a suspended node. The mismatch may be due to the missing
12348 // data, so it's probably a false positive.
12349 return;
12350 }
12351
12352 switch (returnFiber.tag) {
12353 case HostRoot:
12354 {
12355 var parentContainer = returnFiber.stateNode.containerInfo;
12356
12357 switch (fiber.tag) {
12358 case HostComponent:
12359 var type = fiber.type;
12360 var props = fiber.pendingProps;
12361 didNotFindHydratableInstanceWithinContainer(parentContainer, type);
12362 break;
12363
12364 case HostText:
12365 var text = fiber.pendingProps;
12366 didNotFindHydratableTextInstanceWithinContainer(parentContainer, text);
12367 break;
12368 }
12369
12370 break;
12371 }
12372
12373 case HostComponent:
12374 {
12375 var parentType = returnFiber.type;
12376 var parentProps = returnFiber.memoizedProps;
12377 var parentInstance = returnFiber.stateNode;
12378
12379 switch (fiber.tag) {
12380 case HostComponent:
12381 {
12382 var _type = fiber.type;
12383 var _props = fiber.pendingProps;
12384 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
12385 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type, _props, // TODO: Delete this argument when we remove the legacy root API.
12386 isConcurrentMode);
12387 break;
12388 }
12389
12390 case HostText:
12391 {
12392 var _text = fiber.pendingProps;
12393
12394 var _isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
12395
12396 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text, // TODO: Delete this argument when we remove the legacy root API.
12397 _isConcurrentMode);
12398 break;
12399 }
12400 }
12401
12402 break;
12403 }
12404
12405 case SuspenseComponent:
12406 {
12407 var suspenseState = returnFiber.memoizedState;
12408 var _parentInstance = suspenseState.dehydrated;
12409 if (_parentInstance !== null) switch (fiber.tag) {
12410 case HostComponent:
12411 var _type2 = fiber.type;
12412 var _props2 = fiber.pendingProps;
12413 didNotFindHydratableInstanceWithinSuspenseInstance(_parentInstance, _type2);
12414 break;
12415
12416 case HostText:
12417 var _text2 = fiber.pendingProps;
12418 didNotFindHydratableTextInstanceWithinSuspenseInstance(_parentInstance, _text2);
12419 break;
12420 }
12421 break;
12422 }
12423
12424 default:
12425 return;
12426 }
12427 }
12428}
12429
12430function insertNonHydratedInstance(returnFiber, fiber) {
12431 fiber.flags = fiber.flags & ~Hydrating | Placement;
12432 warnNonhydratedInstance(returnFiber, fiber);
12433}
12434
12435function tryHydrate(fiber, nextInstance) {
12436 switch (fiber.tag) {
12437 case HostComponent:
12438 {
12439 var type = fiber.type;
12440 var props = fiber.pendingProps;
12441 var instance = canHydrateInstance(nextInstance, type);
12442
12443 if (instance !== null) {
12444 fiber.stateNode = instance;
12445 hydrationParentFiber = fiber;
12446 nextHydratableInstance = getFirstHydratableChild(instance);
12447 return true;
12448 }
12449
12450 return false;
12451 }
12452
12453 case HostText:
12454 {
12455 var text = fiber.pendingProps;
12456 var textInstance = canHydrateTextInstance(nextInstance, text);
12457
12458 if (textInstance !== null) {
12459 fiber.stateNode = textInstance;
12460 hydrationParentFiber = fiber; // Text Instances don't have children so there's nothing to hydrate.
12461
12462 nextHydratableInstance = null;
12463 return true;
12464 }
12465
12466 return false;
12467 }
12468
12469 case SuspenseComponent:
12470 {
12471 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
12472
12473 if (suspenseInstance !== null) {
12474 var suspenseState = {
12475 dehydrated: suspenseInstance,
12476 treeContext: getSuspendedTreeContext(),
12477 retryLane: OffscreenLane
12478 };
12479 fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber.
12480 // This simplifies the code for getHostSibling and deleting nodes,
12481 // since it doesn't have to consider all Suspense boundaries and
12482 // check if they're dehydrated ones or not.
12483
12484 var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
12485 dehydratedFragment.return = fiber;
12486 fiber.child = dehydratedFragment;
12487 hydrationParentFiber = fiber; // While a Suspense Instance does have children, we won't step into
12488 // it during the first pass. Instead, we'll reenter it later.
12489
12490 nextHydratableInstance = null;
12491 return true;
12492 }
12493
12494 return false;
12495 }
12496
12497 default:
12498 return false;
12499 }
12500}
12501
12502function shouldClientRenderOnMismatch(fiber) {
12503 return (fiber.mode & ConcurrentMode) !== NoMode && (fiber.flags & DidCapture) === NoFlags;
12504}
12505
12506function throwOnHydrationMismatch(fiber) {
12507 throw new Error('Hydration failed because the initial UI does not match what was ' + 'rendered on the server.');
12508}
12509
12510function tryToClaimNextHydratableInstance(fiber) {
12511 if (!isHydrating) {
12512 return;
12513 }
12514
12515 var nextInstance = nextHydratableInstance;
12516
12517 if (!nextInstance) {
12518 if (shouldClientRenderOnMismatch(fiber)) {
12519 warnNonhydratedInstance(hydrationParentFiber, fiber);
12520 throwOnHydrationMismatch();
12521 } // Nothing to hydrate. Make it an insertion.
12522
12523
12524 insertNonHydratedInstance(hydrationParentFiber, fiber);
12525 isHydrating = false;
12526 hydrationParentFiber = fiber;
12527 return;
12528 }
12529
12530 var firstAttemptedInstance = nextInstance;
12531
12532 if (!tryHydrate(fiber, nextInstance)) {
12533 if (shouldClientRenderOnMismatch(fiber)) {
12534 warnNonhydratedInstance(hydrationParentFiber, fiber);
12535 throwOnHydrationMismatch();
12536 } // If we can't hydrate this instance let's try the next one.
12537 // We use this as a heuristic. It's based on intuition and not data so it
12538 // might be flawed or unnecessary.
12539
12540
12541 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
12542 var prevHydrationParentFiber = hydrationParentFiber;
12543
12544 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
12545 // Nothing to hydrate. Make it an insertion.
12546 insertNonHydratedInstance(hydrationParentFiber, fiber);
12547 isHydrating = false;
12548 hydrationParentFiber = fiber;
12549 return;
12550 } // We matched the next one, we'll now assume that the first one was
12551 // superfluous and we'll delete it. Since we can't eagerly delete it
12552 // we'll have to schedule a deletion. To do that, this node needs a dummy
12553 // fiber associated with it.
12554
12555
12556 deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance);
12557 }
12558}
12559
12560function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
12561
12562 var instance = fiber.stateNode;
12563 var shouldWarnIfMismatchDev = !didSuspendOrErrorDEV;
12564 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber, shouldWarnIfMismatchDev); // TODO: Type this specific to this type of component.
12565
12566 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
12567 // is a new ref we mark this as an update.
12568
12569 if (updatePayload !== null) {
12570 return true;
12571 }
12572
12573 return false;
12574}
12575
12576function prepareToHydrateHostTextInstance(fiber) {
12577
12578 var textInstance = fiber.stateNode;
12579 var textContent = fiber.memoizedProps;
12580 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
12581
12582 if (shouldUpdate) {
12583 // We assume that prepareToHydrateHostTextInstance is called in a context where the
12584 // hydration parent is the parent host component of this host text.
12585 var returnFiber = hydrationParentFiber;
12586
12587 if (returnFiber !== null) {
12588 switch (returnFiber.tag) {
12589 case HostRoot:
12590 {
12591 var parentContainer = returnFiber.stateNode.containerInfo;
12592 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
12593 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent, // TODO: Delete this argument when we remove the legacy root API.
12594 isConcurrentMode);
12595 break;
12596 }
12597
12598 case HostComponent:
12599 {
12600 var parentType = returnFiber.type;
12601 var parentProps = returnFiber.memoizedProps;
12602 var parentInstance = returnFiber.stateNode;
12603
12604 var _isConcurrentMode2 = (returnFiber.mode & ConcurrentMode) !== NoMode;
12605
12606 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent, // TODO: Delete this argument when we remove the legacy root API.
12607 _isConcurrentMode2);
12608 break;
12609 }
12610 }
12611 }
12612 }
12613
12614 return shouldUpdate;
12615}
12616
12617function prepareToHydrateHostSuspenseInstance(fiber) {
12618
12619 var suspenseState = fiber.memoizedState;
12620 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
12621
12622 if (!suspenseInstance) {
12623 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.');
12624 }
12625
12626 hydrateSuspenseInstance(suspenseInstance, fiber);
12627}
12628
12629function skipPastDehydratedSuspenseInstance(fiber) {
12630
12631 var suspenseState = fiber.memoizedState;
12632 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
12633
12634 if (!suspenseInstance) {
12635 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.');
12636 }
12637
12638 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
12639}
12640
12641function popToNextHostParent(fiber) {
12642 var parent = fiber.return;
12643
12644 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
12645 parent = parent.return;
12646 }
12647
12648 hydrationParentFiber = parent;
12649}
12650
12651function popHydrationState(fiber) {
12652
12653 if (fiber !== hydrationParentFiber) {
12654 // We're deeper than the current hydration context, inside an inserted
12655 // tree.
12656 return false;
12657 }
12658
12659 if (!isHydrating) {
12660 // If we're not currently hydrating but we're in a hydration context, then
12661 // we were an insertion and now need to pop up reenter hydration of our
12662 // siblings.
12663 popToNextHostParent(fiber);
12664 isHydrating = true;
12665 return false;
12666 } // If we have any remaining hydratable nodes, we need to delete them now.
12667 // We only do this deeper than head and body since they tend to have random
12668 // other nodes in them. We also ignore components with pure text content in
12669 // side of them. We also don't delete anything inside the root container.
12670
12671
12672 if (fiber.tag !== HostRoot && (fiber.tag !== HostComponent || shouldDeleteUnhydratedTailInstances(fiber.type) && !shouldSetTextContent(fiber.type, fiber.memoizedProps))) {
12673 var nextInstance = nextHydratableInstance;
12674
12675 if (nextInstance) {
12676 if (shouldClientRenderOnMismatch(fiber)) {
12677 warnIfUnhydratedTailNodes(fiber);
12678 throwOnHydrationMismatch();
12679 } else {
12680 while (nextInstance) {
12681 deleteHydratableInstance(fiber, nextInstance);
12682 nextInstance = getNextHydratableSibling(nextInstance);
12683 }
12684 }
12685 }
12686 }
12687
12688 popToNextHostParent(fiber);
12689
12690 if (fiber.tag === SuspenseComponent) {
12691 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
12692 } else {
12693 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
12694 }
12695
12696 return true;
12697}
12698
12699function hasUnhydratedTailNodes() {
12700 return isHydrating && nextHydratableInstance !== null;
12701}
12702
12703function warnIfUnhydratedTailNodes(fiber) {
12704 var nextInstance = nextHydratableInstance;
12705
12706 while (nextInstance) {
12707 warnUnhydratedInstance(fiber, nextInstance);
12708 nextInstance = getNextHydratableSibling(nextInstance);
12709 }
12710}
12711
12712function resetHydrationState() {
12713
12714 hydrationParentFiber = null;
12715 nextHydratableInstance = null;
12716 isHydrating = false;
12717 didSuspendOrErrorDEV = false;
12718}
12719
12720function upgradeHydrationErrorsToRecoverable() {
12721 if (hydrationErrors !== null) {
12722 // Successfully completed a forced client render. The errors that occurred
12723 // during the hydration attempt are now recovered. We will log them in
12724 // commit phase, once the entire tree has finished.
12725 queueRecoverableErrors(hydrationErrors);
12726 hydrationErrors = null;
12727 }
12728}
12729
12730function getIsHydrating() {
12731 return isHydrating;
12732}
12733
12734function queueHydrationError(error) {
12735 if (hydrationErrors === null) {
12736 hydrationErrors = [error];
12737 } else {
12738 hydrationErrors.push(error);
12739 }
12740}
12741
12742var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
12743var NoTransition = null;
12744function requestCurrentTransition() {
12745 return ReactCurrentBatchConfig$1.transition;
12746}
12747
12748var ReactStrictModeWarnings = {
12749 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
12750 flushPendingUnsafeLifecycleWarnings: function () {},
12751 recordLegacyContextWarning: function (fiber, instance) {},
12752 flushLegacyContextWarning: function () {},
12753 discardPendingWarnings: function () {}
12754};
12755
12756{
12757 var findStrictRoot = function (fiber) {
12758 var maybeStrictRoot = null;
12759 var node = fiber;
12760
12761 while (node !== null) {
12762 if (node.mode & StrictLegacyMode) {
12763 maybeStrictRoot = node;
12764 }
12765
12766 node = node.return;
12767 }
12768
12769 return maybeStrictRoot;
12770 };
12771
12772 var setToSortedString = function (set) {
12773 var array = [];
12774 set.forEach(function (value) {
12775 array.push(value);
12776 });
12777 return array.sort().join(', ');
12778 };
12779
12780 var pendingComponentWillMountWarnings = [];
12781 var pendingUNSAFE_ComponentWillMountWarnings = [];
12782 var pendingComponentWillReceivePropsWarnings = [];
12783 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12784 var pendingComponentWillUpdateWarnings = [];
12785 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
12786
12787 var didWarnAboutUnsafeLifecycles = new Set();
12788
12789 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
12790 // Dedupe strategy: Warn once per component.
12791 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
12792 return;
12793 }
12794
12795 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
12796 instance.componentWillMount.__suppressDeprecationWarning !== true) {
12797 pendingComponentWillMountWarnings.push(fiber);
12798 }
12799
12800 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === 'function') {
12801 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
12802 }
12803
12804 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12805 pendingComponentWillReceivePropsWarnings.push(fiber);
12806 }
12807
12808 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12809 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
12810 }
12811
12812 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12813 pendingComponentWillUpdateWarnings.push(fiber);
12814 }
12815
12816 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
12817 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
12818 }
12819 };
12820
12821 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
12822 // We do an initial pass to gather component names
12823 var componentWillMountUniqueNames = new Set();
12824
12825 if (pendingComponentWillMountWarnings.length > 0) {
12826 pendingComponentWillMountWarnings.forEach(function (fiber) {
12827 componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12828 didWarnAboutUnsafeLifecycles.add(fiber.type);
12829 });
12830 pendingComponentWillMountWarnings = [];
12831 }
12832
12833 var UNSAFE_componentWillMountUniqueNames = new Set();
12834
12835 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
12836 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
12837 UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12838 didWarnAboutUnsafeLifecycles.add(fiber.type);
12839 });
12840 pendingUNSAFE_ComponentWillMountWarnings = [];
12841 }
12842
12843 var componentWillReceivePropsUniqueNames = new Set();
12844
12845 if (pendingComponentWillReceivePropsWarnings.length > 0) {
12846 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
12847 componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12848 didWarnAboutUnsafeLifecycles.add(fiber.type);
12849 });
12850 pendingComponentWillReceivePropsWarnings = [];
12851 }
12852
12853 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
12854
12855 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
12856 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
12857 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12858 didWarnAboutUnsafeLifecycles.add(fiber.type);
12859 });
12860 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12861 }
12862
12863 var componentWillUpdateUniqueNames = new Set();
12864
12865 if (pendingComponentWillUpdateWarnings.length > 0) {
12866 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
12867 componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12868 didWarnAboutUnsafeLifecycles.add(fiber.type);
12869 });
12870 pendingComponentWillUpdateWarnings = [];
12871 }
12872
12873 var UNSAFE_componentWillUpdateUniqueNames = new Set();
12874
12875 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
12876 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
12877 UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12878 didWarnAboutUnsafeLifecycles.add(fiber.type);
12879 });
12880 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12881 } // Finally, we flush all the warnings
12882 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
12883
12884
12885 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
12886 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
12887
12888 error('Using UNSAFE_componentWillMount in strict mode is not recommended and may indicate bugs in your code. ' + 'See https://reactjs.org/link/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);
12889 }
12890
12891 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
12892 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
12893
12894 error('Using UNSAFE_componentWillReceiveProps in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/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://reactjs.org/link/derived-state\n' + '\nPlease update the following components: %s', _sortedNames);
12895 }
12896
12897 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
12898 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
12899
12900 error('Using UNSAFE_componentWillUpdate in strict mode is not recommended ' + 'and may indicate bugs in your code. ' + 'See https://reactjs.org/link/unsafe-component-lifecycles for details.\n\n' + '* Move data fetching code or side effects to componentDidUpdate.\n' + '\nPlease update the following components: %s', _sortedNames2);
12901 }
12902
12903 if (componentWillMountUniqueNames.size > 0) {
12904 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
12905
12906 warn('componentWillMount has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/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 18.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);
12907 }
12908
12909 if (componentWillReceivePropsUniqueNames.size > 0) {
12910 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
12911
12912 warn('componentWillReceiveProps has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/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://reactjs.org/link/derived-state\n' + '* Rename componentWillReceiveProps to UNSAFE_componentWillReceiveProps to suppress ' + 'this warning in non-strict mode. In React 18.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);
12913 }
12914
12915 if (componentWillUpdateUniqueNames.size > 0) {
12916 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
12917
12918 warn('componentWillUpdate has been renamed, and is not recommended for use. ' + 'See https://reactjs.org/link/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 18.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);
12919 }
12920 };
12921
12922 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
12923
12924 var didWarnAboutLegacyContext = new Set();
12925
12926 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
12927 var strictRoot = findStrictRoot(fiber);
12928
12929 if (strictRoot === null) {
12930 error('Expected to find a StrictMode component in a strict mode tree. ' + 'This error is likely caused by a bug in React. Please file an issue.');
12931
12932 return;
12933 } // Dedup strategy: Warn once per component.
12934
12935
12936 if (didWarnAboutLegacyContext.has(fiber.type)) {
12937 return;
12938 }
12939
12940 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
12941
12942 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
12943 if (warningsForRoot === undefined) {
12944 warningsForRoot = [];
12945 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
12946 }
12947
12948 warningsForRoot.push(fiber);
12949 }
12950 };
12951
12952 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
12953 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
12954 if (fiberArray.length === 0) {
12955 return;
12956 }
12957
12958 var firstFiber = fiberArray[0];
12959 var uniqueNames = new Set();
12960 fiberArray.forEach(function (fiber) {
12961 uniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12962 didWarnAboutLegacyContext.add(fiber.type);
12963 });
12964 var sortedNames = setToSortedString(uniqueNames);
12965
12966 try {
12967 setCurrentFiber(firstFiber);
12968
12969 error('Legacy context API has been detected within a strict-mode tree.' + '\n\nThe old API will be supported in all 16.x releases, but applications ' + 'using it should migrate to the new version.' + '\n\nPlease update the following components: %s' + '\n\nLearn more about this warning here: https://reactjs.org/link/legacy-context', sortedNames);
12970 } finally {
12971 resetCurrentFiber();
12972 }
12973 });
12974 };
12975
12976 ReactStrictModeWarnings.discardPendingWarnings = function () {
12977 pendingComponentWillMountWarnings = [];
12978 pendingUNSAFE_ComponentWillMountWarnings = [];
12979 pendingComponentWillReceivePropsWarnings = [];
12980 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12981 pendingComponentWillUpdateWarnings = [];
12982 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12983 pendingLegacyContextWarning = new Map();
12984 };
12985}
12986
12987function resolveDefaultProps(Component, baseProps) {
12988 if (Component && Component.defaultProps) {
12989 // Resolve default props. Taken from ReactElement
12990 var props = assign({}, baseProps);
12991 var defaultProps = Component.defaultProps;
12992
12993 for (var propName in defaultProps) {
12994 if (props[propName] === undefined) {
12995 props[propName] = defaultProps[propName];
12996 }
12997 }
12998
12999 return props;
13000 }
13001
13002 return baseProps;
13003}
13004
13005var valueCursor = createCursor(null);
13006var rendererSigil;
13007
13008{
13009 // Use this to detect multiple renderers using the same context
13010 rendererSigil = {};
13011}
13012
13013var currentlyRenderingFiber = null;
13014var lastContextDependency = null;
13015var lastFullyObservedContext = null;
13016var isDisallowedContextReadInDEV = false;
13017function resetContextDependencies() {
13018 // This is called right before React yields execution, to ensure `readContext`
13019 // cannot be called outside the render phase.
13020 currentlyRenderingFiber = null;
13021 lastContextDependency = null;
13022 lastFullyObservedContext = null;
13023
13024 {
13025 isDisallowedContextReadInDEV = false;
13026 }
13027}
13028function enterDisallowedContextReadInDEV() {
13029 {
13030 isDisallowedContextReadInDEV = true;
13031 }
13032}
13033function exitDisallowedContextReadInDEV() {
13034 {
13035 isDisallowedContextReadInDEV = false;
13036 }
13037}
13038function pushProvider(providerFiber, context, nextValue) {
13039 {
13040 push(valueCursor, context._currentValue, providerFiber);
13041 context._currentValue = nextValue;
13042
13043 {
13044 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
13045 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
13046 }
13047
13048 context._currentRenderer = rendererSigil;
13049 }
13050 }
13051}
13052function popProvider(context, providerFiber) {
13053 var currentValue = valueCursor.current;
13054 pop(valueCursor, providerFiber);
13055
13056 {
13057 {
13058 context._currentValue = currentValue;
13059 }
13060 }
13061}
13062function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {
13063 // Update the child lanes of all the ancestors, including the alternates.
13064 var node = parent;
13065
13066 while (node !== null) {
13067 var alternate = node.alternate;
13068
13069 if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
13070 node.childLanes = mergeLanes(node.childLanes, renderLanes);
13071
13072 if (alternate !== null) {
13073 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
13074 }
13075 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) {
13076 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
13077 }
13078
13079 if (node === propagationRoot) {
13080 break;
13081 }
13082
13083 node = node.return;
13084 }
13085
13086 {
13087 if (node !== propagationRoot) {
13088 error('Expected to find the propagation root when scheduling context work. ' + 'This error is likely caused by a bug in React. Please file an issue.');
13089 }
13090 }
13091}
13092function propagateContextChange(workInProgress, context, renderLanes) {
13093 {
13094 propagateContextChange_eager(workInProgress, context, renderLanes);
13095 }
13096}
13097
13098function propagateContextChange_eager(workInProgress, context, renderLanes) {
13099
13100 var fiber = workInProgress.child;
13101
13102 if (fiber !== null) {
13103 // Set the return pointer of the child to the work-in-progress fiber.
13104 fiber.return = workInProgress;
13105 }
13106
13107 while (fiber !== null) {
13108 var nextFiber = void 0; // Visit this fiber.
13109
13110 var list = fiber.dependencies;
13111
13112 if (list !== null) {
13113 nextFiber = fiber.child;
13114 var dependency = list.firstContext;
13115
13116 while (dependency !== null) {
13117 // Check if the context matches.
13118 if (dependency.context === context) {
13119 // Match! Schedule an update on this fiber.
13120 if (fiber.tag === ClassComponent) {
13121 // Schedule a force update on the work-in-progress.
13122 var lane = pickArbitraryLane(renderLanes);
13123 var update = createUpdate(NoTimestamp, lane);
13124 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
13125 // update to the current fiber, too, which means it will persist even if
13126 // this render is thrown away. Since it's a race condition, not sure it's
13127 // worth fixing.
13128 // Inlined `enqueueUpdate` to remove interleaved update check
13129
13130 var updateQueue = fiber.updateQueue;
13131
13132 if (updateQueue === null) ; else {
13133 var sharedQueue = updateQueue.shared;
13134 var pending = sharedQueue.pending;
13135
13136 if (pending === null) {
13137 // This is the first update. Create a circular list.
13138 update.next = update;
13139 } else {
13140 update.next = pending.next;
13141 pending.next = update;
13142 }
13143
13144 sharedQueue.pending = update;
13145 }
13146 }
13147
13148 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
13149 var alternate = fiber.alternate;
13150
13151 if (alternate !== null) {
13152 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
13153 }
13154
13155 scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too.
13156
13157 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
13158 // dependency list.
13159
13160 break;
13161 }
13162
13163 dependency = dependency.next;
13164 }
13165 } else if (fiber.tag === ContextProvider) {
13166 // Don't scan deeper if this is a matching provider
13167 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
13168 } else if (fiber.tag === DehydratedFragment) {
13169 // If a dehydrated suspense boundary is in this subtree, we don't know
13170 // if it will have any context consumers in it. The best we can do is
13171 // mark it as having updates.
13172 var parentSuspense = fiber.return;
13173
13174 if (parentSuspense === null) {
13175 throw new Error('We just came from a parent so we must have had a parent. This is a bug in React.');
13176 }
13177
13178 parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes);
13179 var _alternate = parentSuspense.alternate;
13180
13181 if (_alternate !== null) {
13182 _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes);
13183 } // This is intentionally passing this fiber as the parent
13184 // because we want to schedule this fiber as having work
13185 // on its children. We'll use the childLanes on
13186 // this fiber to indicate that a context has changed.
13187
13188
13189 scheduleContextWorkOnParentPath(parentSuspense, renderLanes, workInProgress);
13190 nextFiber = fiber.sibling;
13191 } else {
13192 // Traverse down.
13193 nextFiber = fiber.child;
13194 }
13195
13196 if (nextFiber !== null) {
13197 // Set the return pointer of the child to the work-in-progress fiber.
13198 nextFiber.return = fiber;
13199 } else {
13200 // No child. Traverse to next sibling.
13201 nextFiber = fiber;
13202
13203 while (nextFiber !== null) {
13204 if (nextFiber === workInProgress) {
13205 // We're back to the root of this subtree. Exit.
13206 nextFiber = null;
13207 break;
13208 }
13209
13210 var sibling = nextFiber.sibling;
13211
13212 if (sibling !== null) {
13213 // Set the return pointer of the sibling to the work-in-progress fiber.
13214 sibling.return = nextFiber.return;
13215 nextFiber = sibling;
13216 break;
13217 } // No more siblings. Traverse up.
13218
13219
13220 nextFiber = nextFiber.return;
13221 }
13222 }
13223
13224 fiber = nextFiber;
13225 }
13226}
13227function prepareToReadContext(workInProgress, renderLanes) {
13228 currentlyRenderingFiber = workInProgress;
13229 lastContextDependency = null;
13230 lastFullyObservedContext = null;
13231 var dependencies = workInProgress.dependencies;
13232
13233 if (dependencies !== null) {
13234 {
13235 var firstContext = dependencies.firstContext;
13236
13237 if (firstContext !== null) {
13238 if (includesSomeLane(dependencies.lanes, renderLanes)) {
13239 // Context list has a pending update. Mark that this fiber performed work.
13240 markWorkInProgressReceivedUpdate();
13241 } // Reset the work-in-progress list
13242
13243
13244 dependencies.firstContext = null;
13245 }
13246 }
13247 }
13248}
13249function readContext(context) {
13250 {
13251 // This warning would fire if you read context inside a Hook like useMemo.
13252 // Unlike the class check below, it's not enforced in production for perf.
13253 if (isDisallowedContextReadInDEV) {
13254 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().');
13255 }
13256 }
13257
13258 var value = context._currentValue ;
13259
13260 if (lastFullyObservedContext === context) ; else {
13261 var contextItem = {
13262 context: context,
13263 memoizedValue: value,
13264 next: null
13265 };
13266
13267 if (lastContextDependency === null) {
13268 if (currentlyRenderingFiber === null) {
13269 throw new 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().');
13270 } // This is the first dependency for this component. Create a new list.
13271
13272
13273 lastContextDependency = contextItem;
13274 currentlyRenderingFiber.dependencies = {
13275 lanes: NoLanes,
13276 firstContext: contextItem
13277 };
13278 } else {
13279 // Append a new context item.
13280 lastContextDependency = lastContextDependency.next = contextItem;
13281 }
13282 }
13283
13284 return value;
13285}
13286
13287// render. When this render exits, either because it finishes or because it is
13288// interrupted, the interleaved updates will be transferred onto the main part
13289// of the queue.
13290
13291var concurrentQueues = null;
13292function pushConcurrentUpdateQueue(queue) {
13293 if (concurrentQueues === null) {
13294 concurrentQueues = [queue];
13295 } else {
13296 concurrentQueues.push(queue);
13297 }
13298}
13299function finishQueueingConcurrentUpdates() {
13300 // Transfer the interleaved updates onto the main queue. Each queue has a
13301 // `pending` field and an `interleaved` field. When they are not null, they
13302 // point to the last node in a circular linked list. We need to append the
13303 // interleaved list to the end of the pending list by joining them into a
13304 // single, circular list.
13305 if (concurrentQueues !== null) {
13306 for (var i = 0; i < concurrentQueues.length; i++) {
13307 var queue = concurrentQueues[i];
13308 var lastInterleavedUpdate = queue.interleaved;
13309
13310 if (lastInterleavedUpdate !== null) {
13311 queue.interleaved = null;
13312 var firstInterleavedUpdate = lastInterleavedUpdate.next;
13313 var lastPendingUpdate = queue.pending;
13314
13315 if (lastPendingUpdate !== null) {
13316 var firstPendingUpdate = lastPendingUpdate.next;
13317 lastPendingUpdate.next = firstInterleavedUpdate;
13318 lastInterleavedUpdate.next = firstPendingUpdate;
13319 }
13320
13321 queue.pending = lastInterleavedUpdate;
13322 }
13323 }
13324
13325 concurrentQueues = null;
13326 }
13327}
13328function enqueueConcurrentHookUpdate(fiber, queue, update, lane) {
13329 var interleaved = queue.interleaved;
13330
13331 if (interleaved === null) {
13332 // This is the first update. Create a circular list.
13333 update.next = update; // At the end of the current render, this queue's interleaved updates will
13334 // be transferred to the pending queue.
13335
13336 pushConcurrentUpdateQueue(queue);
13337 } else {
13338 update.next = interleaved.next;
13339 interleaved.next = update;
13340 }
13341
13342 queue.interleaved = update;
13343 return markUpdateLaneFromFiberToRoot(fiber, lane);
13344}
13345function enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane) {
13346 var interleaved = queue.interleaved;
13347
13348 if (interleaved === null) {
13349 // This is the first update. Create a circular list.
13350 update.next = update; // At the end of the current render, this queue's interleaved updates will
13351 // be transferred to the pending queue.
13352
13353 pushConcurrentUpdateQueue(queue);
13354 } else {
13355 update.next = interleaved.next;
13356 interleaved.next = update;
13357 }
13358
13359 queue.interleaved = update;
13360}
13361function enqueueConcurrentClassUpdate(fiber, queue, update, lane) {
13362 var interleaved = queue.interleaved;
13363
13364 if (interleaved === null) {
13365 // This is the first update. Create a circular list.
13366 update.next = update; // At the end of the current render, this queue's interleaved updates will
13367 // be transferred to the pending queue.
13368
13369 pushConcurrentUpdateQueue(queue);
13370 } else {
13371 update.next = interleaved.next;
13372 interleaved.next = update;
13373 }
13374
13375 queue.interleaved = update;
13376 return markUpdateLaneFromFiberToRoot(fiber, lane);
13377}
13378function enqueueConcurrentRenderForLane(fiber, lane) {
13379 return markUpdateLaneFromFiberToRoot(fiber, lane);
13380} // Calling this function outside this module should only be done for backwards
13381// compatibility and should always be accompanied by a warning.
13382
13383var unsafe_markUpdateLaneFromFiberToRoot = markUpdateLaneFromFiberToRoot;
13384
13385function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
13386 // Update the source fiber's lanes
13387 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
13388 var alternate = sourceFiber.alternate;
13389
13390 if (alternate !== null) {
13391 alternate.lanes = mergeLanes(alternate.lanes, lane);
13392 }
13393
13394 {
13395 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {
13396 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
13397 }
13398 } // Walk the parent path to the root and update the child lanes.
13399
13400
13401 var node = sourceFiber;
13402 var parent = sourceFiber.return;
13403
13404 while (parent !== null) {
13405 parent.childLanes = mergeLanes(parent.childLanes, lane);
13406 alternate = parent.alternate;
13407
13408 if (alternate !== null) {
13409 alternate.childLanes = mergeLanes(alternate.childLanes, lane);
13410 } else {
13411 {
13412 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {
13413 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
13414 }
13415 }
13416 }
13417
13418 node = parent;
13419 parent = parent.return;
13420 }
13421
13422 if (node.tag === HostRoot) {
13423 var root = node.stateNode;
13424 return root;
13425 } else {
13426 return null;
13427 }
13428}
13429
13430var UpdateState = 0;
13431var ReplaceState = 1;
13432var ForceUpdate = 2;
13433var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
13434// It should only be read right after calling `processUpdateQueue`, via
13435// `checkHasForceUpdateAfterProcessing`.
13436
13437var hasForceUpdate = false;
13438var didWarnUpdateInsideUpdate;
13439var currentlyProcessingQueue;
13440
13441{
13442 didWarnUpdateInsideUpdate = false;
13443 currentlyProcessingQueue = null;
13444}
13445
13446function initializeUpdateQueue(fiber) {
13447 var queue = {
13448 baseState: fiber.memoizedState,
13449 firstBaseUpdate: null,
13450 lastBaseUpdate: null,
13451 shared: {
13452 pending: null,
13453 interleaved: null,
13454 lanes: NoLanes
13455 },
13456 effects: null
13457 };
13458 fiber.updateQueue = queue;
13459}
13460function cloneUpdateQueue(current, workInProgress) {
13461 // Clone the update queue from current. Unless it's already a clone.
13462 var queue = workInProgress.updateQueue;
13463 var currentQueue = current.updateQueue;
13464
13465 if (queue === currentQueue) {
13466 var clone = {
13467 baseState: currentQueue.baseState,
13468 firstBaseUpdate: currentQueue.firstBaseUpdate,
13469 lastBaseUpdate: currentQueue.lastBaseUpdate,
13470 shared: currentQueue.shared,
13471 effects: currentQueue.effects
13472 };
13473 workInProgress.updateQueue = clone;
13474 }
13475}
13476function createUpdate(eventTime, lane) {
13477 var update = {
13478 eventTime: eventTime,
13479 lane: lane,
13480 tag: UpdateState,
13481 payload: null,
13482 callback: null,
13483 next: null
13484 };
13485 return update;
13486}
13487function enqueueUpdate(fiber, update, lane) {
13488 var updateQueue = fiber.updateQueue;
13489
13490 if (updateQueue === null) {
13491 // Only occurs if the fiber has been unmounted.
13492 return null;
13493 }
13494
13495 var sharedQueue = updateQueue.shared;
13496
13497 {
13498 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
13499 error('An update (setState, replaceState, or forceUpdate) was scheduled ' + 'from inside an update function. Update functions should be pure, ' + 'with zero side-effects. Consider using componentDidUpdate or a ' + 'callback.');
13500
13501 didWarnUpdateInsideUpdate = true;
13502 }
13503 }
13504
13505 if (isUnsafeClassRenderPhaseUpdate()) {
13506 // This is an unsafe render phase update. Add directly to the update
13507 // queue so we can process it immediately during the current render.
13508 var pending = sharedQueue.pending;
13509
13510 if (pending === null) {
13511 // This is the first update. Create a circular list.
13512 update.next = update;
13513 } else {
13514 update.next = pending.next;
13515 pending.next = update;
13516 }
13517
13518 sharedQueue.pending = update; // Update the childLanes even though we're most likely already rendering
13519 // this fiber. This is for backwards compatibility in the case where you
13520 // update a different component during render phase than the one that is
13521 // currently renderings (a pattern that is accompanied by a warning).
13522
13523 return unsafe_markUpdateLaneFromFiberToRoot(fiber, lane);
13524 } else {
13525 return enqueueConcurrentClassUpdate(fiber, sharedQueue, update, lane);
13526 }
13527}
13528function entangleTransitions(root, fiber, lane) {
13529 var updateQueue = fiber.updateQueue;
13530
13531 if (updateQueue === null) {
13532 // Only occurs if the fiber has been unmounted.
13533 return;
13534 }
13535
13536 var sharedQueue = updateQueue.shared;
13537
13538 if (isTransitionLane(lane)) {
13539 var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must
13540 // have finished. We can remove them from the shared queue, which represents
13541 // a superset of the actually pending lanes. In some cases we may entangle
13542 // more than we need to, but that's OK. In fact it's worse if we *don't*
13543 // entangle when we should.
13544
13545 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
13546
13547 var newQueueLanes = mergeLanes(queueLanes, lane);
13548 sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
13549 // the lane finished since the last time we entangled it. So we need to
13550 // entangle it again, just to be sure.
13551
13552 markRootEntangled(root, newQueueLanes);
13553 }
13554}
13555function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
13556 // Captured updates are updates that are thrown by a child during the render
13557 // phase. They should be discarded if the render is aborted. Therefore,
13558 // we should only put them on the work-in-progress queue, not the current one.
13559 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
13560
13561 var current = workInProgress.alternate;
13562
13563 if (current !== null) {
13564 var currentQueue = current.updateQueue;
13565
13566 if (queue === currentQueue) {
13567 // The work-in-progress queue is the same as current. This happens when
13568 // we bail out on a parent fiber that then captures an error thrown by
13569 // a child. Since we want to append the update only to the work-in
13570 // -progress queue, we need to clone the updates. We usually clone during
13571 // processUpdateQueue, but that didn't happen in this case because we
13572 // skipped over the parent when we bailed out.
13573 var newFirst = null;
13574 var newLast = null;
13575 var firstBaseUpdate = queue.firstBaseUpdate;
13576
13577 if (firstBaseUpdate !== null) {
13578 // Loop through the updates and clone them.
13579 var update = firstBaseUpdate;
13580
13581 do {
13582 var clone = {
13583 eventTime: update.eventTime,
13584 lane: update.lane,
13585 tag: update.tag,
13586 payload: update.payload,
13587 callback: update.callback,
13588 next: null
13589 };
13590
13591 if (newLast === null) {
13592 newFirst = newLast = clone;
13593 } else {
13594 newLast.next = clone;
13595 newLast = clone;
13596 }
13597
13598 update = update.next;
13599 } while (update !== null); // Append the captured update the end of the cloned list.
13600
13601
13602 if (newLast === null) {
13603 newFirst = newLast = capturedUpdate;
13604 } else {
13605 newLast.next = capturedUpdate;
13606 newLast = capturedUpdate;
13607 }
13608 } else {
13609 // There are no base updates.
13610 newFirst = newLast = capturedUpdate;
13611 }
13612
13613 queue = {
13614 baseState: currentQueue.baseState,
13615 firstBaseUpdate: newFirst,
13616 lastBaseUpdate: newLast,
13617 shared: currentQueue.shared,
13618 effects: currentQueue.effects
13619 };
13620 workInProgress.updateQueue = queue;
13621 return;
13622 }
13623 } // Append the update to the end of the list.
13624
13625
13626 var lastBaseUpdate = queue.lastBaseUpdate;
13627
13628 if (lastBaseUpdate === null) {
13629 queue.firstBaseUpdate = capturedUpdate;
13630 } else {
13631 lastBaseUpdate.next = capturedUpdate;
13632 }
13633
13634 queue.lastBaseUpdate = capturedUpdate;
13635}
13636
13637function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
13638 switch (update.tag) {
13639 case ReplaceState:
13640 {
13641 var payload = update.payload;
13642
13643 if (typeof payload === 'function') {
13644 // Updater function
13645 {
13646 enterDisallowedContextReadInDEV();
13647 }
13648
13649 var nextState = payload.call(instance, prevState, nextProps);
13650
13651 {
13652 if ( workInProgress.mode & StrictLegacyMode) {
13653 setIsStrictModeForDevtools(true);
13654
13655 try {
13656 payload.call(instance, prevState, nextProps);
13657 } finally {
13658 setIsStrictModeForDevtools(false);
13659 }
13660 }
13661
13662 exitDisallowedContextReadInDEV();
13663 }
13664
13665 return nextState;
13666 } // State object
13667
13668
13669 return payload;
13670 }
13671
13672 case CaptureUpdate:
13673 {
13674 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
13675 }
13676 // Intentional fallthrough
13677
13678 case UpdateState:
13679 {
13680 var _payload = update.payload;
13681 var partialState;
13682
13683 if (typeof _payload === 'function') {
13684 // Updater function
13685 {
13686 enterDisallowedContextReadInDEV();
13687 }
13688
13689 partialState = _payload.call(instance, prevState, nextProps);
13690
13691 {
13692 if ( workInProgress.mode & StrictLegacyMode) {
13693 setIsStrictModeForDevtools(true);
13694
13695 try {
13696 _payload.call(instance, prevState, nextProps);
13697 } finally {
13698 setIsStrictModeForDevtools(false);
13699 }
13700 }
13701
13702 exitDisallowedContextReadInDEV();
13703 }
13704 } else {
13705 // Partial state object
13706 partialState = _payload;
13707 }
13708
13709 if (partialState === null || partialState === undefined) {
13710 // Null and undefined are treated as no-ops.
13711 return prevState;
13712 } // Merge the partial state and the previous state.
13713
13714
13715 return assign({}, prevState, partialState);
13716 }
13717
13718 case ForceUpdate:
13719 {
13720 hasForceUpdate = true;
13721 return prevState;
13722 }
13723 }
13724
13725 return prevState;
13726}
13727
13728function processUpdateQueue(workInProgress, props, instance, renderLanes) {
13729 // This is always non-null on a ClassComponent or HostRoot
13730 var queue = workInProgress.updateQueue;
13731 hasForceUpdate = false;
13732
13733 {
13734 currentlyProcessingQueue = queue.shared;
13735 }
13736
13737 var firstBaseUpdate = queue.firstBaseUpdate;
13738 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
13739
13740 var pendingQueue = queue.shared.pending;
13741
13742 if (pendingQueue !== null) {
13743 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
13744 // and last so that it's non-circular.
13745
13746 var lastPendingUpdate = pendingQueue;
13747 var firstPendingUpdate = lastPendingUpdate.next;
13748 lastPendingUpdate.next = null; // Append pending updates to base queue
13749
13750 if (lastBaseUpdate === null) {
13751 firstBaseUpdate = firstPendingUpdate;
13752 } else {
13753 lastBaseUpdate.next = firstPendingUpdate;
13754 }
13755
13756 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
13757 // we need to transfer the updates to that queue, too. Because the base
13758 // queue is a singly-linked list with no cycles, we can append to both
13759 // lists and take advantage of structural sharing.
13760 // TODO: Pass `current` as argument
13761
13762 var current = workInProgress.alternate;
13763
13764 if (current !== null) {
13765 // This is always non-null on a ClassComponent or HostRoot
13766 var currentQueue = current.updateQueue;
13767 var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
13768
13769 if (currentLastBaseUpdate !== lastBaseUpdate) {
13770 if (currentLastBaseUpdate === null) {
13771 currentQueue.firstBaseUpdate = firstPendingUpdate;
13772 } else {
13773 currentLastBaseUpdate.next = firstPendingUpdate;
13774 }
13775
13776 currentQueue.lastBaseUpdate = lastPendingUpdate;
13777 }
13778 }
13779 } // These values may change as we process the queue.
13780
13781
13782 if (firstBaseUpdate !== null) {
13783 // Iterate through the list of updates to compute the result.
13784 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
13785 // from the original lanes.
13786
13787 var newLanes = NoLanes;
13788 var newBaseState = null;
13789 var newFirstBaseUpdate = null;
13790 var newLastBaseUpdate = null;
13791 var update = firstBaseUpdate;
13792
13793 do {
13794 var updateLane = update.lane;
13795 var updateEventTime = update.eventTime;
13796
13797 if (!isSubsetOfLanes(renderLanes, updateLane)) {
13798 // Priority is insufficient. Skip this update. If this is the first
13799 // skipped update, the previous update/state is the new base
13800 // update/state.
13801 var clone = {
13802 eventTime: updateEventTime,
13803 lane: updateLane,
13804 tag: update.tag,
13805 payload: update.payload,
13806 callback: update.callback,
13807 next: null
13808 };
13809
13810 if (newLastBaseUpdate === null) {
13811 newFirstBaseUpdate = newLastBaseUpdate = clone;
13812 newBaseState = newState;
13813 } else {
13814 newLastBaseUpdate = newLastBaseUpdate.next = clone;
13815 } // Update the remaining priority in the queue.
13816
13817
13818 newLanes = mergeLanes(newLanes, updateLane);
13819 } else {
13820 // This update does have sufficient priority.
13821 if (newLastBaseUpdate !== null) {
13822 var _clone = {
13823 eventTime: updateEventTime,
13824 // This update is going to be committed so we never want uncommit
13825 // it. Using NoLane works because 0 is a subset of all bitmasks, so
13826 // this will never be skipped by the check above.
13827 lane: NoLane,
13828 tag: update.tag,
13829 payload: update.payload,
13830 callback: update.callback,
13831 next: null
13832 };
13833 newLastBaseUpdate = newLastBaseUpdate.next = _clone;
13834 } // Process this update.
13835
13836
13837 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
13838 var callback = update.callback;
13839
13840 if (callback !== null && // If the update was already committed, we should not queue its
13841 // callback again.
13842 update.lane !== NoLane) {
13843 workInProgress.flags |= Callback;
13844 var effects = queue.effects;
13845
13846 if (effects === null) {
13847 queue.effects = [update];
13848 } else {
13849 effects.push(update);
13850 }
13851 }
13852 }
13853
13854 update = update.next;
13855
13856 if (update === null) {
13857 pendingQueue = queue.shared.pending;
13858
13859 if (pendingQueue === null) {
13860 break;
13861 } else {
13862 // An update was scheduled from inside a reducer. Add the new
13863 // pending updates to the end of the list and keep processing.
13864 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
13865 // unravel them when transferring them to the base queue.
13866
13867 var _firstPendingUpdate = _lastPendingUpdate.next;
13868 _lastPendingUpdate.next = null;
13869 update = _firstPendingUpdate;
13870 queue.lastBaseUpdate = _lastPendingUpdate;
13871 queue.shared.pending = null;
13872 }
13873 }
13874 } while (true);
13875
13876 if (newLastBaseUpdate === null) {
13877 newBaseState = newState;
13878 }
13879
13880 queue.baseState = newBaseState;
13881 queue.firstBaseUpdate = newFirstBaseUpdate;
13882 queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to
13883 // process them during this render, but we do need to track which lanes
13884 // are remaining.
13885
13886 var lastInterleaved = queue.shared.interleaved;
13887
13888 if (lastInterleaved !== null) {
13889 var interleaved = lastInterleaved;
13890
13891 do {
13892 newLanes = mergeLanes(newLanes, interleaved.lane);
13893 interleaved = interleaved.next;
13894 } while (interleaved !== lastInterleaved);
13895 } else if (firstBaseUpdate === null) {
13896 // `queue.lanes` is used for entangling transitions. We can set it back to
13897 // zero once the queue is empty.
13898 queue.shared.lanes = NoLanes;
13899 } // Set the remaining expiration time to be whatever is remaining in the queue.
13900 // This should be fine because the only two other things that contribute to
13901 // expiration time are props and context. We're already in the middle of the
13902 // begin phase by the time we start processing the queue, so we've already
13903 // dealt with the props. Context in components that specify
13904 // shouldComponentUpdate is tricky; but we'll have to account for
13905 // that regardless.
13906
13907
13908 markSkippedUpdateLanes(newLanes);
13909 workInProgress.lanes = newLanes;
13910 workInProgress.memoizedState = newState;
13911 }
13912
13913 {
13914 currentlyProcessingQueue = null;
13915 }
13916}
13917
13918function callCallback(callback, context) {
13919 if (typeof callback !== 'function') {
13920 throw new Error('Invalid argument passed as callback. Expected a function. Instead ' + ("received: " + callback));
13921 }
13922
13923 callback.call(context);
13924}
13925
13926function resetHasForceUpdateBeforeProcessing() {
13927 hasForceUpdate = false;
13928}
13929function checkHasForceUpdateAfterProcessing() {
13930 return hasForceUpdate;
13931}
13932function commitUpdateQueue(finishedWork, finishedQueue, instance) {
13933 // Commit the effects
13934 var effects = finishedQueue.effects;
13935 finishedQueue.effects = null;
13936
13937 if (effects !== null) {
13938 for (var i = 0; i < effects.length; i++) {
13939 var effect = effects[i];
13940 var callback = effect.callback;
13941
13942 if (callback !== null) {
13943 effect.callback = null;
13944 callCallback(callback, instance);
13945 }
13946 }
13947 }
13948}
13949
13950var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default.
13951// We'll use it to determine whether we need to initialize legacy refs.
13952
13953var emptyRefsObject = new React.Component().refs;
13954var didWarnAboutStateAssignmentForComponent;
13955var didWarnAboutUninitializedState;
13956var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
13957var didWarnAboutLegacyLifecyclesAndDerivedState;
13958var didWarnAboutUndefinedDerivedState;
13959var warnOnUndefinedDerivedState;
13960var warnOnInvalidCallback;
13961var didWarnAboutDirectlyAssigningPropsToState;
13962var didWarnAboutContextTypeAndContextTypes;
13963var didWarnAboutInvalidateContextType;
13964
13965{
13966 didWarnAboutStateAssignmentForComponent = new Set();
13967 didWarnAboutUninitializedState = new Set();
13968 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
13969 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
13970 didWarnAboutDirectlyAssigningPropsToState = new Set();
13971 didWarnAboutUndefinedDerivedState = new Set();
13972 didWarnAboutContextTypeAndContextTypes = new Set();
13973 didWarnAboutInvalidateContextType = new Set();
13974 var didWarnOnInvalidCallback = new Set();
13975
13976 warnOnInvalidCallback = function (callback, callerName) {
13977 if (callback === null || typeof callback === 'function') {
13978 return;
13979 }
13980
13981 var key = callerName + '_' + callback;
13982
13983 if (!didWarnOnInvalidCallback.has(key)) {
13984 didWarnOnInvalidCallback.add(key);
13985
13986 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
13987 }
13988 };
13989
13990 warnOnUndefinedDerivedState = function (type, partialState) {
13991 if (partialState === undefined) {
13992 var componentName = getComponentNameFromType(type) || 'Component';
13993
13994 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
13995 didWarnAboutUndefinedDerivedState.add(componentName);
13996
13997 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
13998 }
13999 }
14000 }; // This is so gross but it's at least non-critical and can be removed if
14001 // it causes problems. This is meant to give a nicer error message for
14002 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
14003 // ...)) which otherwise throws a "_processChildContext is not a function"
14004 // exception.
14005
14006
14007 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
14008 enumerable: false,
14009 value: function () {
14010 throw new 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).');
14011 }
14012 });
14013 Object.freeze(fakeInternalInstance);
14014}
14015
14016function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
14017 var prevState = workInProgress.memoizedState;
14018 var partialState = getDerivedStateFromProps(nextProps, prevState);
14019
14020 {
14021 if ( workInProgress.mode & StrictLegacyMode) {
14022 setIsStrictModeForDevtools(true);
14023
14024 try {
14025 // Invoke the function an extra time to help detect side-effects.
14026 partialState = getDerivedStateFromProps(nextProps, prevState);
14027 } finally {
14028 setIsStrictModeForDevtools(false);
14029 }
14030 }
14031
14032 warnOnUndefinedDerivedState(ctor, partialState);
14033 } // Merge the partial state and the previous state.
14034
14035
14036 var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState);
14037 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
14038 // base state.
14039
14040 if (workInProgress.lanes === NoLanes) {
14041 // Queue is always non-null for classes
14042 var updateQueue = workInProgress.updateQueue;
14043 updateQueue.baseState = memoizedState;
14044 }
14045}
14046
14047var classComponentUpdater = {
14048 isMounted: isMounted,
14049 enqueueSetState: function (inst, payload, callback) {
14050 var fiber = get(inst);
14051 var eventTime = requestEventTime();
14052 var lane = requestUpdateLane(fiber);
14053 var update = createUpdate(eventTime, lane);
14054 update.payload = payload;
14055
14056 if (callback !== undefined && callback !== null) {
14057 {
14058 warnOnInvalidCallback(callback, 'setState');
14059 }
14060
14061 update.callback = callback;
14062 }
14063
14064 var root = enqueueUpdate(fiber, update, lane);
14065
14066 if (root !== null) {
14067 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
14068 entangleTransitions(root, fiber, lane);
14069 }
14070
14071 {
14072 markStateUpdateScheduled(fiber, lane);
14073 }
14074 },
14075 enqueueReplaceState: function (inst, payload, callback) {
14076 var fiber = get(inst);
14077 var eventTime = requestEventTime();
14078 var lane = requestUpdateLane(fiber);
14079 var update = createUpdate(eventTime, lane);
14080 update.tag = ReplaceState;
14081 update.payload = payload;
14082
14083 if (callback !== undefined && callback !== null) {
14084 {
14085 warnOnInvalidCallback(callback, 'replaceState');
14086 }
14087
14088 update.callback = callback;
14089 }
14090
14091 var root = enqueueUpdate(fiber, update, lane);
14092
14093 if (root !== null) {
14094 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
14095 entangleTransitions(root, fiber, lane);
14096 }
14097
14098 {
14099 markStateUpdateScheduled(fiber, lane);
14100 }
14101 },
14102 enqueueForceUpdate: function (inst, callback) {
14103 var fiber = get(inst);
14104 var eventTime = requestEventTime();
14105 var lane = requestUpdateLane(fiber);
14106 var update = createUpdate(eventTime, lane);
14107 update.tag = ForceUpdate;
14108
14109 if (callback !== undefined && callback !== null) {
14110 {
14111 warnOnInvalidCallback(callback, 'forceUpdate');
14112 }
14113
14114 update.callback = callback;
14115 }
14116
14117 var root = enqueueUpdate(fiber, update, lane);
14118
14119 if (root !== null) {
14120 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
14121 entangleTransitions(root, fiber, lane);
14122 }
14123
14124 {
14125 markForceUpdateScheduled(fiber, lane);
14126 }
14127 }
14128};
14129
14130function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
14131 var instance = workInProgress.stateNode;
14132
14133 if (typeof instance.shouldComponentUpdate === 'function') {
14134 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
14135
14136 {
14137 if ( workInProgress.mode & StrictLegacyMode) {
14138 setIsStrictModeForDevtools(true);
14139
14140 try {
14141 // Invoke the function an extra time to help detect side-effects.
14142 shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
14143 } finally {
14144 setIsStrictModeForDevtools(false);
14145 }
14146 }
14147
14148 if (shouldUpdate === undefined) {
14149 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentNameFromType(ctor) || 'Component');
14150 }
14151 }
14152
14153 return shouldUpdate;
14154 }
14155
14156 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
14157 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
14158 }
14159
14160 return true;
14161}
14162
14163function checkClassInstance(workInProgress, ctor, newProps) {
14164 var instance = workInProgress.stateNode;
14165
14166 {
14167 var name = getComponentNameFromType(ctor) || 'Component';
14168 var renderPresent = instance.render;
14169
14170 if (!renderPresent) {
14171 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
14172 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
14173 } else {
14174 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
14175 }
14176 }
14177
14178 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
14179 error('getInitialState was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Did you mean to define a state property instead?', name);
14180 }
14181
14182 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
14183 error('getDefaultProps was defined on %s, a plain JavaScript class. ' + 'This is only supported for classes created using React.createClass. ' + 'Use a static property to define defaultProps instead.', name);
14184 }
14185
14186 if (instance.propTypes) {
14187 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
14188 }
14189
14190 if (instance.contextType) {
14191 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
14192 }
14193
14194 {
14195 if (instance.contextTypes) {
14196 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
14197 }
14198
14199 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
14200 didWarnAboutContextTypeAndContextTypes.add(ctor);
14201
14202 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
14203 }
14204 }
14205
14206 if (typeof instance.componentShouldUpdate === 'function') {
14207 error('%s has a method called ' + 'componentShouldUpdate(). Did you mean shouldComponentUpdate()? ' + 'The name is phrased as a question because the function is ' + 'expected to return a value.', name);
14208 }
14209
14210 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
14211 error('%s has a method called shouldComponentUpdate(). ' + 'shouldComponentUpdate should not be used when extending React.PureComponent. ' + 'Please extend React.Component if shouldComponentUpdate is used.', getComponentNameFromType(ctor) || 'A pure component');
14212 }
14213
14214 if (typeof instance.componentDidUnmount === 'function') {
14215 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
14216 }
14217
14218 if (typeof instance.componentDidReceiveProps === 'function') {
14219 error('%s has a method called ' + 'componentDidReceiveProps(). But there is no such lifecycle method. ' + 'If you meant to update the state in response to changing props, ' + 'use componentWillReceiveProps(). If you meant to fetch data or ' + 'run side-effects or mutations after React has updated the UI, use componentDidUpdate().', name);
14220 }
14221
14222 if (typeof instance.componentWillRecieveProps === 'function') {
14223 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
14224 }
14225
14226 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
14227 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
14228 }
14229
14230 var hasMutatedProps = instance.props !== newProps;
14231
14232 if (instance.props !== undefined && hasMutatedProps) {
14233 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
14234 }
14235
14236 if (instance.defaultProps) {
14237 error('Setting defaultProps as an instance property on %s is not supported and will be ignored.' + ' Instead, define defaultProps as a static property on %s.', name, name);
14238 }
14239
14240 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
14241 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
14242
14243 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentNameFromType(ctor));
14244 }
14245
14246 if (typeof instance.getDerivedStateFromProps === 'function') {
14247 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
14248 }
14249
14250 if (typeof instance.getDerivedStateFromError === 'function') {
14251 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
14252 }
14253
14254 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
14255 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
14256 }
14257
14258 var _state = instance.state;
14259
14260 if (_state && (typeof _state !== 'object' || isArray(_state))) {
14261 error('%s.state: must be set to an object or null', name);
14262 }
14263
14264 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
14265 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
14266 }
14267 }
14268}
14269
14270function adoptClassInstance(workInProgress, instance) {
14271 instance.updater = classComponentUpdater;
14272 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
14273
14274 set(instance, workInProgress);
14275
14276 {
14277 instance._reactInternalInstance = fakeInternalInstance;
14278 }
14279}
14280
14281function constructClassInstance(workInProgress, ctor, props) {
14282 var isLegacyContextConsumer = false;
14283 var unmaskedContext = emptyContextObject;
14284 var context = emptyContextObject;
14285 var contextType = ctor.contextType;
14286
14287 {
14288 if ('contextType' in ctor) {
14289 var isValid = // Allow null for conditional declaration
14290 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
14291
14292 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
14293 didWarnAboutInvalidateContextType.add(ctor);
14294 var addendum = '';
14295
14296 if (contextType === undefined) {
14297 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.';
14298 } else if (typeof contextType !== 'object') {
14299 addendum = ' However, it is set to a ' + typeof contextType + '.';
14300 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
14301 addendum = ' Did you accidentally pass the Context.Provider instead?';
14302 } else if (contextType._context !== undefined) {
14303 // <Context.Consumer>
14304 addendum = ' Did you accidentally pass the Context.Consumer instead?';
14305 } else {
14306 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
14307 }
14308
14309 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentNameFromType(ctor) || 'Component', addendum);
14310 }
14311 }
14312 }
14313
14314 if (typeof contextType === 'object' && contextType !== null) {
14315 context = readContext(contextType);
14316 } else {
14317 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
14318 var contextTypes = ctor.contextTypes;
14319 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
14320 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
14321 }
14322
14323 var instance = new ctor(props, context); // Instantiate twice to help detect side-effects.
14324
14325 {
14326 if ( workInProgress.mode & StrictLegacyMode) {
14327 setIsStrictModeForDevtools(true);
14328
14329 try {
14330 instance = new ctor(props, context); // eslint-disable-line no-new
14331 } finally {
14332 setIsStrictModeForDevtools(false);
14333 }
14334 }
14335 }
14336
14337 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
14338 adoptClassInstance(workInProgress, instance);
14339
14340 {
14341 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
14342 var componentName = getComponentNameFromType(ctor) || 'Component';
14343
14344 if (!didWarnAboutUninitializedState.has(componentName)) {
14345 didWarnAboutUninitializedState.add(componentName);
14346
14347 error('`%s` uses `getDerivedStateFromProps` but its initial state is ' + '%s. This is not recommended. Instead, define the initial state by ' + 'assigning an object to `this.state` in the constructor of `%s`. ' + 'This ensures that `getDerivedStateFromProps` arguments have a consistent shape.', componentName, instance.state === null ? 'null' : 'undefined', componentName);
14348 }
14349 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
14350 // Warn about these lifecycles if they are present.
14351 // Don't warn about react-lifecycles-compat polyfilled methods though.
14352
14353
14354 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
14355 var foundWillMountName = null;
14356 var foundWillReceivePropsName = null;
14357 var foundWillUpdateName = null;
14358
14359 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
14360 foundWillMountName = 'componentWillMount';
14361 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
14362 foundWillMountName = 'UNSAFE_componentWillMount';
14363 }
14364
14365 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
14366 foundWillReceivePropsName = 'componentWillReceiveProps';
14367 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
14368 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
14369 }
14370
14371 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
14372 foundWillUpdateName = 'componentWillUpdate';
14373 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
14374 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
14375 }
14376
14377 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
14378 var _componentName = getComponentNameFromType(ctor) || 'Component';
14379
14380 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
14381
14382 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
14383 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
14384
14385 error('Unsafe legacy lifecycles will not be called for components using new component APIs.\n\n' + '%s uses %s but also contains the following legacy lifecycles:%s%s%s\n\n' + 'The above lifecycles should be removed. Learn more about this warning here:\n' + 'https://reactjs.org/link/unsafe-component-lifecycles', _componentName, newApiName, foundWillMountName !== null ? "\n " + foundWillMountName : '', foundWillReceivePropsName !== null ? "\n " + foundWillReceivePropsName : '', foundWillUpdateName !== null ? "\n " + foundWillUpdateName : '');
14386 }
14387 }
14388 }
14389 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
14390 // ReactFiberContext usually updates this cache but can't for newly-created instances.
14391
14392
14393 if (isLegacyContextConsumer) {
14394 cacheContext(workInProgress, unmaskedContext, context);
14395 }
14396
14397 return instance;
14398}
14399
14400function callComponentWillMount(workInProgress, instance) {
14401 var oldState = instance.state;
14402
14403 if (typeof instance.componentWillMount === 'function') {
14404 instance.componentWillMount();
14405 }
14406
14407 if (typeof instance.UNSAFE_componentWillMount === 'function') {
14408 instance.UNSAFE_componentWillMount();
14409 }
14410
14411 if (oldState !== instance.state) {
14412 {
14413 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentNameFromFiber(workInProgress) || 'Component');
14414 }
14415
14416 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
14417 }
14418}
14419
14420function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
14421 var oldState = instance.state;
14422
14423 if (typeof instance.componentWillReceiveProps === 'function') {
14424 instance.componentWillReceiveProps(newProps, nextContext);
14425 }
14426
14427 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
14428 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
14429 }
14430
14431 if (instance.state !== oldState) {
14432 {
14433 var componentName = getComponentNameFromFiber(workInProgress) || 'Component';
14434
14435 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
14436 didWarnAboutStateAssignmentForComponent.add(componentName);
14437
14438 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
14439 }
14440 }
14441
14442 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
14443 }
14444} // Invokes the mount life-cycles on a previously never rendered instance.
14445
14446
14447function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
14448 {
14449 checkClassInstance(workInProgress, ctor, newProps);
14450 }
14451
14452 var instance = workInProgress.stateNode;
14453 instance.props = newProps;
14454 instance.state = workInProgress.memoizedState;
14455 instance.refs = emptyRefsObject;
14456 initializeUpdateQueue(workInProgress);
14457 var contextType = ctor.contextType;
14458
14459 if (typeof contextType === 'object' && contextType !== null) {
14460 instance.context = readContext(contextType);
14461 } else {
14462 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
14463 instance.context = getMaskedContext(workInProgress, unmaskedContext);
14464 }
14465
14466 {
14467 if (instance.state === newProps) {
14468 var componentName = getComponentNameFromType(ctor) || 'Component';
14469
14470 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
14471 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
14472
14473 error('%s: It is not recommended to assign props directly to state ' + "because updates to props won't be reflected in state. " + 'In most cases, it is better to use props directly.', componentName);
14474 }
14475 }
14476
14477 if (workInProgress.mode & StrictLegacyMode) {
14478 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
14479 }
14480
14481 {
14482 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
14483 }
14484 }
14485
14486 instance.state = workInProgress.memoizedState;
14487 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
14488
14489 if (typeof getDerivedStateFromProps === 'function') {
14490 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
14491 instance.state = workInProgress.memoizedState;
14492 } // In order to support react-lifecycles-compat polyfilled components,
14493 // Unsafe lifecycles should not be invoked for components using the new APIs.
14494
14495
14496 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
14497 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
14498 // process them now.
14499
14500 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
14501 instance.state = workInProgress.memoizedState;
14502 }
14503
14504 if (typeof instance.componentDidMount === 'function') {
14505 var fiberFlags = Update;
14506
14507 {
14508 fiberFlags |= LayoutStatic;
14509 }
14510
14511 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
14512 fiberFlags |= MountLayoutDev;
14513 }
14514
14515 workInProgress.flags |= fiberFlags;
14516 }
14517}
14518
14519function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
14520 var instance = workInProgress.stateNode;
14521 var oldProps = workInProgress.memoizedProps;
14522 instance.props = oldProps;
14523 var oldContext = instance.context;
14524 var contextType = ctor.contextType;
14525 var nextContext = emptyContextObject;
14526
14527 if (typeof contextType === 'object' && contextType !== null) {
14528 nextContext = readContext(contextType);
14529 } else {
14530 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
14531 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
14532 }
14533
14534 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
14535 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
14536 // ever the previously attempted to render - not the "current". However,
14537 // during componentDidUpdate we pass the "current" props.
14538 // In order to support react-lifecycles-compat polyfilled components,
14539 // Unsafe lifecycles should not be invoked for components using the new APIs.
14540
14541 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
14542 if (oldProps !== newProps || oldContext !== nextContext) {
14543 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
14544 }
14545 }
14546
14547 resetHasForceUpdateBeforeProcessing();
14548 var oldState = workInProgress.memoizedState;
14549 var newState = instance.state = oldState;
14550 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
14551 newState = workInProgress.memoizedState;
14552
14553 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
14554 // If an update was already in progress, we should schedule an Update
14555 // effect even though we're bailing out, so that cWU/cDU are called.
14556 if (typeof instance.componentDidMount === 'function') {
14557 var fiberFlags = Update;
14558
14559 {
14560 fiberFlags |= LayoutStatic;
14561 }
14562
14563 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
14564 fiberFlags |= MountLayoutDev;
14565 }
14566
14567 workInProgress.flags |= fiberFlags;
14568 }
14569
14570 return false;
14571 }
14572
14573 if (typeof getDerivedStateFromProps === 'function') {
14574 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
14575 newState = workInProgress.memoizedState;
14576 }
14577
14578 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
14579
14580 if (shouldUpdate) {
14581 // In order to support react-lifecycles-compat polyfilled components,
14582 // Unsafe lifecycles should not be invoked for components using the new APIs.
14583 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
14584 if (typeof instance.componentWillMount === 'function') {
14585 instance.componentWillMount();
14586 }
14587
14588 if (typeof instance.UNSAFE_componentWillMount === 'function') {
14589 instance.UNSAFE_componentWillMount();
14590 }
14591 }
14592
14593 if (typeof instance.componentDidMount === 'function') {
14594 var _fiberFlags = Update;
14595
14596 {
14597 _fiberFlags |= LayoutStatic;
14598 }
14599
14600 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
14601 _fiberFlags |= MountLayoutDev;
14602 }
14603
14604 workInProgress.flags |= _fiberFlags;
14605 }
14606 } else {
14607 // If an update was already in progress, we should schedule an Update
14608 // effect even though we're bailing out, so that cWU/cDU are called.
14609 if (typeof instance.componentDidMount === 'function') {
14610 var _fiberFlags2 = Update;
14611
14612 {
14613 _fiberFlags2 |= LayoutStatic;
14614 }
14615
14616 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
14617 _fiberFlags2 |= MountLayoutDev;
14618 }
14619
14620 workInProgress.flags |= _fiberFlags2;
14621 } // If shouldComponentUpdate returned false, we should still update the
14622 // memoized state to indicate that this work can be reused.
14623
14624
14625 workInProgress.memoizedProps = newProps;
14626 workInProgress.memoizedState = newState;
14627 } // Update the existing instance's state, props, and context pointers even
14628 // if shouldComponentUpdate returns false.
14629
14630
14631 instance.props = newProps;
14632 instance.state = newState;
14633 instance.context = nextContext;
14634 return shouldUpdate;
14635} // Invokes the update life-cycles and returns false if it shouldn't rerender.
14636
14637
14638function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
14639 var instance = workInProgress.stateNode;
14640 cloneUpdateQueue(current, workInProgress);
14641 var unresolvedOldProps = workInProgress.memoizedProps;
14642 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
14643 instance.props = oldProps;
14644 var unresolvedNewProps = workInProgress.pendingProps;
14645 var oldContext = instance.context;
14646 var contextType = ctor.contextType;
14647 var nextContext = emptyContextObject;
14648
14649 if (typeof contextType === 'object' && contextType !== null) {
14650 nextContext = readContext(contextType);
14651 } else {
14652 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
14653 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
14654 }
14655
14656 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
14657 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
14658 // ever the previously attempted to render - not the "current". However,
14659 // during componentDidUpdate we pass the "current" props.
14660 // In order to support react-lifecycles-compat polyfilled components,
14661 // Unsafe lifecycles should not be invoked for components using the new APIs.
14662
14663 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
14664 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
14665 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
14666 }
14667 }
14668
14669 resetHasForceUpdateBeforeProcessing();
14670 var oldState = workInProgress.memoizedState;
14671 var newState = instance.state = oldState;
14672 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
14673 newState = workInProgress.memoizedState;
14674
14675 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !(enableLazyContextPropagation )) {
14676 // If an update was already in progress, we should schedule an Update
14677 // effect even though we're bailing out, so that cWU/cDU are called.
14678 if (typeof instance.componentDidUpdate === 'function') {
14679 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
14680 workInProgress.flags |= Update;
14681 }
14682 }
14683
14684 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
14685 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
14686 workInProgress.flags |= Snapshot;
14687 }
14688 }
14689
14690 return false;
14691 }
14692
14693 if (typeof getDerivedStateFromProps === 'function') {
14694 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
14695 newState = workInProgress.memoizedState;
14696 }
14697
14698 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) || // TODO: In some cases, we'll end up checking if context has changed twice,
14699 // both before and after `shouldComponentUpdate` has been called. Not ideal,
14700 // but I'm loath to refactor this function. This only happens for memoized
14701 // components so it's not that common.
14702 enableLazyContextPropagation ;
14703
14704 if (shouldUpdate) {
14705 // In order to support react-lifecycles-compat polyfilled components,
14706 // Unsafe lifecycles should not be invoked for components using the new APIs.
14707 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
14708 if (typeof instance.componentWillUpdate === 'function') {
14709 instance.componentWillUpdate(newProps, newState, nextContext);
14710 }
14711
14712 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
14713 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
14714 }
14715 }
14716
14717 if (typeof instance.componentDidUpdate === 'function') {
14718 workInProgress.flags |= Update;
14719 }
14720
14721 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
14722 workInProgress.flags |= Snapshot;
14723 }
14724 } else {
14725 // If an update was already in progress, we should schedule an Update
14726 // effect even though we're bailing out, so that cWU/cDU are called.
14727 if (typeof instance.componentDidUpdate === 'function') {
14728 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
14729 workInProgress.flags |= Update;
14730 }
14731 }
14732
14733 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
14734 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
14735 workInProgress.flags |= Snapshot;
14736 }
14737 } // If shouldComponentUpdate returned false, we should still update the
14738 // memoized props/state to indicate that this work can be reused.
14739
14740
14741 workInProgress.memoizedProps = newProps;
14742 workInProgress.memoizedState = newState;
14743 } // Update the existing instance's state, props, and context pointers even
14744 // if shouldComponentUpdate returns false.
14745
14746
14747 instance.props = newProps;
14748 instance.state = newState;
14749 instance.context = nextContext;
14750 return shouldUpdate;
14751}
14752
14753var didWarnAboutMaps;
14754var didWarnAboutGenerators;
14755var didWarnAboutStringRefs;
14756var ownerHasKeyUseWarning;
14757var ownerHasFunctionTypeWarning;
14758
14759var warnForMissingKey = function (child, returnFiber) {};
14760
14761{
14762 didWarnAboutMaps = false;
14763 didWarnAboutGenerators = false;
14764 didWarnAboutStringRefs = {};
14765 /**
14766 * Warn if there's no key explicitly set on dynamic arrays of children or
14767 * object keys are not valid. This allows us to keep track of children between
14768 * updates.
14769 */
14770
14771 ownerHasKeyUseWarning = {};
14772 ownerHasFunctionTypeWarning = {};
14773
14774 warnForMissingKey = function (child, returnFiber) {
14775 if (child === null || typeof child !== 'object') {
14776 return;
14777 }
14778
14779 if (!child._store || child._store.validated || child.key != null) {
14780 return;
14781 }
14782
14783 if (typeof child._store !== 'object') {
14784 throw new Error('React Component in warnForMissingKey should have a _store. ' + 'This error is likely caused by a bug in React. Please file an issue.');
14785 }
14786
14787 child._store.validated = true;
14788 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
14789
14790 if (ownerHasKeyUseWarning[componentName]) {
14791 return;
14792 }
14793
14794 ownerHasKeyUseWarning[componentName] = true;
14795
14796 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.');
14797 };
14798}
14799
14800function coerceRef(returnFiber, current, element) {
14801 var mixedRef = element.ref;
14802
14803 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
14804 {
14805 // TODO: Clean this up once we turn on the string ref warning for
14806 // everyone, because the strict mode case will no longer be relevant
14807 if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
14808 // because these cannot be automatically converted to an arrow function
14809 // using a codemod. Therefore, we don't have to warn about string refs again.
14810 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
14811 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
14812
14813 if (!didWarnAboutStringRefs[componentName]) {
14814 {
14815 error('A string ref, "%s", has been found within a strict mode tree. ' + 'String refs are a source of potential bugs and should be avoided. ' + 'We recommend using useRef() or createRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref', mixedRef);
14816 }
14817
14818 didWarnAboutStringRefs[componentName] = true;
14819 }
14820 }
14821 }
14822
14823 if (element._owner) {
14824 var owner = element._owner;
14825 var inst;
14826
14827 if (owner) {
14828 var ownerFiber = owner;
14829
14830 if (ownerFiber.tag !== ClassComponent) {
14831 throw new Error('Function components cannot have string refs. ' + 'We recommend using useRef() instead. ' + 'Learn more about using refs safely here: ' + 'https://reactjs.org/link/strict-mode-string-ref');
14832 }
14833
14834 inst = ownerFiber.stateNode;
14835 }
14836
14837 if (!inst) {
14838 throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a " + 'bug in React. Please file an issue.');
14839 } // Assigning this to a const so Flow knows it won't change in the closure
14840
14841
14842 var resolvedInst = inst;
14843
14844 {
14845 checkPropStringCoercion(mixedRef, 'ref');
14846 }
14847
14848 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
14849
14850 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
14851 return current.ref;
14852 }
14853
14854 var ref = function (value) {
14855 var refs = resolvedInst.refs;
14856
14857 if (refs === emptyRefsObject) {
14858 // This is a lazy pooled frozen object, so we need to initialize.
14859 refs = resolvedInst.refs = {};
14860 }
14861
14862 if (value === null) {
14863 delete refs[stringRef];
14864 } else {
14865 refs[stringRef] = value;
14866 }
14867 };
14868
14869 ref._stringRef = stringRef;
14870 return ref;
14871 } else {
14872 if (typeof mixedRef !== 'string') {
14873 throw new Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.');
14874 }
14875
14876 if (!element._owner) {
14877 throw new Error("Element ref was specified as a string (" + mixedRef + ") but no owner was set. This could happen for one of" + ' the following reasons:\n' + '1. You may be adding a ref to a function component\n' + "2. You may be adding a ref to a component that was not created inside a component's render method\n" + '3. You have multiple copies of React loaded\n' + 'See https://reactjs.org/link/refs-must-have-owner for more information.');
14878 }
14879 }
14880 }
14881
14882 return mixedRef;
14883}
14884
14885function throwOnInvalidObjectType(returnFiber, newChild) {
14886 var childString = Object.prototype.toString.call(newChild);
14887 throw new Error("Objects are not valid as a React child (found: " + (childString === '[object Object]' ? 'object with keys {' + Object.keys(newChild).join(', ') + '}' : childString) + "). " + 'If you meant to render a collection of children, use an array ' + 'instead.');
14888}
14889
14890function warnOnFunctionType(returnFiber) {
14891 {
14892 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
14893
14894 if (ownerHasFunctionTypeWarning[componentName]) {
14895 return;
14896 }
14897
14898 ownerHasFunctionTypeWarning[componentName] = true;
14899
14900 error('Functions are not valid as a React child. This may happen if ' + 'you return a Component instead of <Component /> from render. ' + 'Or maybe you meant to call this function rather than return it.');
14901 }
14902}
14903
14904function resolveLazy(lazyType) {
14905 var payload = lazyType._payload;
14906 var init = lazyType._init;
14907 return init(payload);
14908} // This wrapper function exists because I expect to clone the code in each path
14909// to be able to optimize each path individually by branching early. This needs
14910// a compiler or we can do it manually. Helpers that don't need this branching
14911// live outside of this function.
14912
14913
14914function ChildReconciler(shouldTrackSideEffects) {
14915 function deleteChild(returnFiber, childToDelete) {
14916 if (!shouldTrackSideEffects) {
14917 // Noop.
14918 return;
14919 }
14920
14921 var deletions = returnFiber.deletions;
14922
14923 if (deletions === null) {
14924 returnFiber.deletions = [childToDelete];
14925 returnFiber.flags |= ChildDeletion;
14926 } else {
14927 deletions.push(childToDelete);
14928 }
14929 }
14930
14931 function deleteRemainingChildren(returnFiber, currentFirstChild) {
14932 if (!shouldTrackSideEffects) {
14933 // Noop.
14934 return null;
14935 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
14936 // assuming that after the first child we've already added everything.
14937
14938
14939 var childToDelete = currentFirstChild;
14940
14941 while (childToDelete !== null) {
14942 deleteChild(returnFiber, childToDelete);
14943 childToDelete = childToDelete.sibling;
14944 }
14945
14946 return null;
14947 }
14948
14949 function mapRemainingChildren(returnFiber, currentFirstChild) {
14950 // Add the remaining children to a temporary map so that we can find them by
14951 // keys quickly. Implicit (null) keys get added to this set with their index
14952 // instead.
14953 var existingChildren = new Map();
14954 var existingChild = currentFirstChild;
14955
14956 while (existingChild !== null) {
14957 if (existingChild.key !== null) {
14958 existingChildren.set(existingChild.key, existingChild);
14959 } else {
14960 existingChildren.set(existingChild.index, existingChild);
14961 }
14962
14963 existingChild = existingChild.sibling;
14964 }
14965
14966 return existingChildren;
14967 }
14968
14969 function useFiber(fiber, pendingProps) {
14970 // We currently set sibling to null and index to 0 here because it is easy
14971 // to forget to do before returning it. E.g. for the single child case.
14972 var clone = createWorkInProgress(fiber, pendingProps);
14973 clone.index = 0;
14974 clone.sibling = null;
14975 return clone;
14976 }
14977
14978 function placeChild(newFiber, lastPlacedIndex, newIndex) {
14979 newFiber.index = newIndex;
14980
14981 if (!shouldTrackSideEffects) {
14982 // During hydration, the useId algorithm needs to know which fibers are
14983 // part of a list of children (arrays, iterators).
14984 newFiber.flags |= Forked;
14985 return lastPlacedIndex;
14986 }
14987
14988 var current = newFiber.alternate;
14989
14990 if (current !== null) {
14991 var oldIndex = current.index;
14992
14993 if (oldIndex < lastPlacedIndex) {
14994 // This is a move.
14995 newFiber.flags |= Placement;
14996 return lastPlacedIndex;
14997 } else {
14998 // This item can stay in place.
14999 return oldIndex;
15000 }
15001 } else {
15002 // This is an insertion.
15003 newFiber.flags |= Placement;
15004 return lastPlacedIndex;
15005 }
15006 }
15007
15008 function placeSingleChild(newFiber) {
15009 // This is simpler for the single child case. We only need to do a
15010 // placement for inserting new children.
15011 if (shouldTrackSideEffects && newFiber.alternate === null) {
15012 newFiber.flags |= Placement;
15013 }
15014
15015 return newFiber;
15016 }
15017
15018 function updateTextNode(returnFiber, current, textContent, lanes) {
15019 if (current === null || current.tag !== HostText) {
15020 // Insert
15021 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
15022 created.return = returnFiber;
15023 return created;
15024 } else {
15025 // Update
15026 var existing = useFiber(current, textContent);
15027 existing.return = returnFiber;
15028 return existing;
15029 }
15030 }
15031
15032 function updateElement(returnFiber, current, element, lanes) {
15033 var elementType = element.type;
15034
15035 if (elementType === REACT_FRAGMENT_TYPE) {
15036 return updateFragment(returnFiber, current, element.props.children, lanes, element.key);
15037 }
15038
15039 if (current !== null) {
15040 if (current.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
15041 isCompatibleFamilyForHotReloading(current, element) ) || // Lazy types should reconcile their resolved type.
15042 // We need to do this after the Hot Reloading check above,
15043 // because hot reloading has different semantics than prod because
15044 // it doesn't resuspend. So we can't let the call below suspend.
15045 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current.type) {
15046 // Move based on index
15047 var existing = useFiber(current, element.props);
15048 existing.ref = coerceRef(returnFiber, current, element);
15049 existing.return = returnFiber;
15050
15051 {
15052 existing._debugSource = element._source;
15053 existing._debugOwner = element._owner;
15054 }
15055
15056 return existing;
15057 }
15058 } // Insert
15059
15060
15061 var created = createFiberFromElement(element, returnFiber.mode, lanes);
15062 created.ref = coerceRef(returnFiber, current, element);
15063 created.return = returnFiber;
15064 return created;
15065 }
15066
15067 function updatePortal(returnFiber, current, portal, lanes) {
15068 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
15069 // Insert
15070 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
15071 created.return = returnFiber;
15072 return created;
15073 } else {
15074 // Update
15075 var existing = useFiber(current, portal.children || []);
15076 existing.return = returnFiber;
15077 return existing;
15078 }
15079 }
15080
15081 function updateFragment(returnFiber, current, fragment, lanes, key) {
15082 if (current === null || current.tag !== Fragment) {
15083 // Insert
15084 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
15085 created.return = returnFiber;
15086 return created;
15087 } else {
15088 // Update
15089 var existing = useFiber(current, fragment);
15090 existing.return = returnFiber;
15091 return existing;
15092 }
15093 }
15094
15095 function createChild(returnFiber, newChild, lanes) {
15096 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
15097 // Text nodes don't have keys. If the previous node is implicitly keyed
15098 // we can continue to replace it without aborting even if it is not a text
15099 // node.
15100 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes);
15101 created.return = returnFiber;
15102 return created;
15103 }
15104
15105 if (typeof newChild === 'object' && newChild !== null) {
15106 switch (newChild.$$typeof) {
15107 case REACT_ELEMENT_TYPE:
15108 {
15109 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
15110
15111 _created.ref = coerceRef(returnFiber, null, newChild);
15112 _created.return = returnFiber;
15113 return _created;
15114 }
15115
15116 case REACT_PORTAL_TYPE:
15117 {
15118 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
15119
15120 _created2.return = returnFiber;
15121 return _created2;
15122 }
15123
15124 case REACT_LAZY_TYPE:
15125 {
15126 var payload = newChild._payload;
15127 var init = newChild._init;
15128 return createChild(returnFiber, init(payload), lanes);
15129 }
15130 }
15131
15132 if (isArray(newChild) || getIteratorFn(newChild)) {
15133 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
15134
15135 _created3.return = returnFiber;
15136 return _created3;
15137 }
15138
15139 throwOnInvalidObjectType(returnFiber, newChild);
15140 }
15141
15142 {
15143 if (typeof newChild === 'function') {
15144 warnOnFunctionType(returnFiber);
15145 }
15146 }
15147
15148 return null;
15149 }
15150
15151 function updateSlot(returnFiber, oldFiber, newChild, lanes) {
15152 // Update the fiber if the keys match, otherwise return null.
15153 var key = oldFiber !== null ? oldFiber.key : null;
15154
15155 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
15156 // Text nodes don't have keys. If the previous node is implicitly keyed
15157 // we can continue to replace it without aborting even if it is not a text
15158 // node.
15159 if (key !== null) {
15160 return null;
15161 }
15162
15163 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes);
15164 }
15165
15166 if (typeof newChild === 'object' && newChild !== null) {
15167 switch (newChild.$$typeof) {
15168 case REACT_ELEMENT_TYPE:
15169 {
15170 if (newChild.key === key) {
15171 return updateElement(returnFiber, oldFiber, newChild, lanes);
15172 } else {
15173 return null;
15174 }
15175 }
15176
15177 case REACT_PORTAL_TYPE:
15178 {
15179 if (newChild.key === key) {
15180 return updatePortal(returnFiber, oldFiber, newChild, lanes);
15181 } else {
15182 return null;
15183 }
15184 }
15185
15186 case REACT_LAZY_TYPE:
15187 {
15188 var payload = newChild._payload;
15189 var init = newChild._init;
15190 return updateSlot(returnFiber, oldFiber, init(payload), lanes);
15191 }
15192 }
15193
15194 if (isArray(newChild) || getIteratorFn(newChild)) {
15195 if (key !== null) {
15196 return null;
15197 }
15198
15199 return updateFragment(returnFiber, oldFiber, newChild, lanes, null);
15200 }
15201
15202 throwOnInvalidObjectType(returnFiber, newChild);
15203 }
15204
15205 {
15206 if (typeof newChild === 'function') {
15207 warnOnFunctionType(returnFiber);
15208 }
15209 }
15210
15211 return null;
15212 }
15213
15214 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
15215 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
15216 // Text nodes don't have keys, so we neither have to check the old nor
15217 // new node for the key. If both are text nodes, they match.
15218 var matchedFiber = existingChildren.get(newIdx) || null;
15219 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes);
15220 }
15221
15222 if (typeof newChild === 'object' && newChild !== null) {
15223 switch (newChild.$$typeof) {
15224 case REACT_ELEMENT_TYPE:
15225 {
15226 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
15227
15228 return updateElement(returnFiber, _matchedFiber, newChild, lanes);
15229 }
15230
15231 case REACT_PORTAL_TYPE:
15232 {
15233 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
15234
15235 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
15236 }
15237
15238 case REACT_LAZY_TYPE:
15239 var payload = newChild._payload;
15240 var init = newChild._init;
15241 return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes);
15242 }
15243
15244 if (isArray(newChild) || getIteratorFn(newChild)) {
15245 var _matchedFiber3 = existingChildren.get(newIdx) || null;
15246
15247 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null);
15248 }
15249
15250 throwOnInvalidObjectType(returnFiber, newChild);
15251 }
15252
15253 {
15254 if (typeof newChild === 'function') {
15255 warnOnFunctionType(returnFiber);
15256 }
15257 }
15258
15259 return null;
15260 }
15261 /**
15262 * Warns if there is a duplicate or missing key
15263 */
15264
15265
15266 function warnOnInvalidKey(child, knownKeys, returnFiber) {
15267 {
15268 if (typeof child !== 'object' || child === null) {
15269 return knownKeys;
15270 }
15271
15272 switch (child.$$typeof) {
15273 case REACT_ELEMENT_TYPE:
15274 case REACT_PORTAL_TYPE:
15275 warnForMissingKey(child, returnFiber);
15276 var key = child.key;
15277
15278 if (typeof key !== 'string') {
15279 break;
15280 }
15281
15282 if (knownKeys === null) {
15283 knownKeys = new Set();
15284 knownKeys.add(key);
15285 break;
15286 }
15287
15288 if (!knownKeys.has(key)) {
15289 knownKeys.add(key);
15290 break;
15291 }
15292
15293 error('Encountered two children with the same key, `%s`. ' + 'Keys should be unique so that components maintain their identity ' + 'across updates. Non-unique keys may cause children to be ' + 'duplicated and/or omitted — the behavior is unsupported and ' + 'could change in a future version.', key);
15294
15295 break;
15296
15297 case REACT_LAZY_TYPE:
15298 var payload = child._payload;
15299 var init = child._init;
15300 warnOnInvalidKey(init(payload), knownKeys, returnFiber);
15301 break;
15302 }
15303 }
15304
15305 return knownKeys;
15306 }
15307
15308 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
15309 // This algorithm can't optimize by searching from both ends since we
15310 // don't have backpointers on fibers. I'm trying to see how far we can get
15311 // with that model. If it ends up not being worth the tradeoffs, we can
15312 // add it later.
15313 // Even with a two ended optimization, we'd want to optimize for the case
15314 // where there are few changes and brute force the comparison instead of
15315 // going for the Map. It'd like to explore hitting that path first in
15316 // forward-only mode and only go for the Map once we notice that we need
15317 // lots of look ahead. This doesn't handle reversal as well as two ended
15318 // search but that's unusual. Besides, for the two ended optimization to
15319 // work on Iterables, we'd need to copy the whole set.
15320 // In this first iteration, we'll just live with hitting the bad case
15321 // (adding everything to a Map) in for every insert/move.
15322 // If you change this code, also update reconcileChildrenIterator() which
15323 // uses the same algorithm.
15324 {
15325 // First, validate keys.
15326 var knownKeys = null;
15327
15328 for (var i = 0; i < newChildren.length; i++) {
15329 var child = newChildren[i];
15330 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
15331 }
15332 }
15333
15334 var resultingFirstChild = null;
15335 var previousNewFiber = null;
15336 var oldFiber = currentFirstChild;
15337 var lastPlacedIndex = 0;
15338 var newIdx = 0;
15339 var nextOldFiber = null;
15340
15341 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
15342 if (oldFiber.index > newIdx) {
15343 nextOldFiber = oldFiber;
15344 oldFiber = null;
15345 } else {
15346 nextOldFiber = oldFiber.sibling;
15347 }
15348
15349 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
15350
15351 if (newFiber === null) {
15352 // TODO: This breaks on empty slots like null children. That's
15353 // unfortunate because it triggers the slow path all the time. We need
15354 // a better way to communicate whether this was a miss or null,
15355 // boolean, undefined, etc.
15356 if (oldFiber === null) {
15357 oldFiber = nextOldFiber;
15358 }
15359
15360 break;
15361 }
15362
15363 if (shouldTrackSideEffects) {
15364 if (oldFiber && newFiber.alternate === null) {
15365 // We matched the slot, but we didn't reuse the existing fiber, so we
15366 // need to delete the existing child.
15367 deleteChild(returnFiber, oldFiber);
15368 }
15369 }
15370
15371 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
15372
15373 if (previousNewFiber === null) {
15374 // TODO: Move out of the loop. This only happens for the first run.
15375 resultingFirstChild = newFiber;
15376 } else {
15377 // TODO: Defer siblings if we're not at the right index for this slot.
15378 // I.e. if we had null values before, then we want to defer this
15379 // for each null value. However, we also don't want to call updateSlot
15380 // with the previous one.
15381 previousNewFiber.sibling = newFiber;
15382 }
15383
15384 previousNewFiber = newFiber;
15385 oldFiber = nextOldFiber;
15386 }
15387
15388 if (newIdx === newChildren.length) {
15389 // We've reached the end of the new children. We can delete the rest.
15390 deleteRemainingChildren(returnFiber, oldFiber);
15391
15392 if (getIsHydrating()) {
15393 var numberOfForks = newIdx;
15394 pushTreeFork(returnFiber, numberOfForks);
15395 }
15396
15397 return resultingFirstChild;
15398 }
15399
15400 if (oldFiber === null) {
15401 // If we don't have any more existing children we can choose a fast path
15402 // since the rest will all be insertions.
15403 for (; newIdx < newChildren.length; newIdx++) {
15404 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
15405
15406 if (_newFiber === null) {
15407 continue;
15408 }
15409
15410 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
15411
15412 if (previousNewFiber === null) {
15413 // TODO: Move out of the loop. This only happens for the first run.
15414 resultingFirstChild = _newFiber;
15415 } else {
15416 previousNewFiber.sibling = _newFiber;
15417 }
15418
15419 previousNewFiber = _newFiber;
15420 }
15421
15422 if (getIsHydrating()) {
15423 var _numberOfForks = newIdx;
15424 pushTreeFork(returnFiber, _numberOfForks);
15425 }
15426
15427 return resultingFirstChild;
15428 } // Add all children to a key map for quick lookups.
15429
15430
15431 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
15432
15433 for (; newIdx < newChildren.length; newIdx++) {
15434 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
15435
15436 if (_newFiber2 !== null) {
15437 if (shouldTrackSideEffects) {
15438 if (_newFiber2.alternate !== null) {
15439 // The new fiber is a work in progress, but if there exists a
15440 // current, that means that we reused the fiber. We need to delete
15441 // it from the child list so that we don't add it to the deletion
15442 // list.
15443 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
15444 }
15445 }
15446
15447 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
15448
15449 if (previousNewFiber === null) {
15450 resultingFirstChild = _newFiber2;
15451 } else {
15452 previousNewFiber.sibling = _newFiber2;
15453 }
15454
15455 previousNewFiber = _newFiber2;
15456 }
15457 }
15458
15459 if (shouldTrackSideEffects) {
15460 // Any existing children that weren't consumed above were deleted. We need
15461 // to add them to the deletion list.
15462 existingChildren.forEach(function (child) {
15463 return deleteChild(returnFiber, child);
15464 });
15465 }
15466
15467 if (getIsHydrating()) {
15468 var _numberOfForks2 = newIdx;
15469 pushTreeFork(returnFiber, _numberOfForks2);
15470 }
15471
15472 return resultingFirstChild;
15473 }
15474
15475 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
15476 // This is the same implementation as reconcileChildrenArray(),
15477 // but using the iterator instead.
15478 var iteratorFn = getIteratorFn(newChildrenIterable);
15479
15480 if (typeof iteratorFn !== 'function') {
15481 throw new Error('An object is not an iterable. This error is likely caused by a bug in ' + 'React. Please file an issue.');
15482 }
15483
15484 {
15485 // We don't support rendering Generators because it's a mutation.
15486 // See https://github.com/facebook/react/issues/12995
15487 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
15488 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
15489 if (!didWarnAboutGenerators) {
15490 error('Using Generators as children is unsupported and will likely yield ' + 'unexpected results because enumerating a generator mutates it. ' + 'You may convert it to an array with `Array.from()` or the ' + '`[...spread]` operator before rendering. Keep in mind ' + 'you might need to polyfill these features for older browsers.');
15491 }
15492
15493 didWarnAboutGenerators = true;
15494 } // Warn about using Maps as children
15495
15496
15497 if (newChildrenIterable.entries === iteratorFn) {
15498 if (!didWarnAboutMaps) {
15499 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.');
15500 }
15501
15502 didWarnAboutMaps = true;
15503 } // First, validate keys.
15504 // We'll get a different iterator later for the main pass.
15505
15506
15507 var _newChildren = iteratorFn.call(newChildrenIterable);
15508
15509 if (_newChildren) {
15510 var knownKeys = null;
15511
15512 var _step = _newChildren.next();
15513
15514 for (; !_step.done; _step = _newChildren.next()) {
15515 var child = _step.value;
15516 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
15517 }
15518 }
15519 }
15520
15521 var newChildren = iteratorFn.call(newChildrenIterable);
15522
15523 if (newChildren == null) {
15524 throw new Error('An iterable object provided no iterator.');
15525 }
15526
15527 var resultingFirstChild = null;
15528 var previousNewFiber = null;
15529 var oldFiber = currentFirstChild;
15530 var lastPlacedIndex = 0;
15531 var newIdx = 0;
15532 var nextOldFiber = null;
15533 var step = newChildren.next();
15534
15535 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
15536 if (oldFiber.index > newIdx) {
15537 nextOldFiber = oldFiber;
15538 oldFiber = null;
15539 } else {
15540 nextOldFiber = oldFiber.sibling;
15541 }
15542
15543 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
15544
15545 if (newFiber === null) {
15546 // TODO: This breaks on empty slots like null children. That's
15547 // unfortunate because it triggers the slow path all the time. We need
15548 // a better way to communicate whether this was a miss or null,
15549 // boolean, undefined, etc.
15550 if (oldFiber === null) {
15551 oldFiber = nextOldFiber;
15552 }
15553
15554 break;
15555 }
15556
15557 if (shouldTrackSideEffects) {
15558 if (oldFiber && newFiber.alternate === null) {
15559 // We matched the slot, but we didn't reuse the existing fiber, so we
15560 // need to delete the existing child.
15561 deleteChild(returnFiber, oldFiber);
15562 }
15563 }
15564
15565 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
15566
15567 if (previousNewFiber === null) {
15568 // TODO: Move out of the loop. This only happens for the first run.
15569 resultingFirstChild = newFiber;
15570 } else {
15571 // TODO: Defer siblings if we're not at the right index for this slot.
15572 // I.e. if we had null values before, then we want to defer this
15573 // for each null value. However, we also don't want to call updateSlot
15574 // with the previous one.
15575 previousNewFiber.sibling = newFiber;
15576 }
15577
15578 previousNewFiber = newFiber;
15579 oldFiber = nextOldFiber;
15580 }
15581
15582 if (step.done) {
15583 // We've reached the end of the new children. We can delete the rest.
15584 deleteRemainingChildren(returnFiber, oldFiber);
15585
15586 if (getIsHydrating()) {
15587 var numberOfForks = newIdx;
15588 pushTreeFork(returnFiber, numberOfForks);
15589 }
15590
15591 return resultingFirstChild;
15592 }
15593
15594 if (oldFiber === null) {
15595 // If we don't have any more existing children we can choose a fast path
15596 // since the rest will all be insertions.
15597 for (; !step.done; newIdx++, step = newChildren.next()) {
15598 var _newFiber3 = createChild(returnFiber, step.value, lanes);
15599
15600 if (_newFiber3 === null) {
15601 continue;
15602 }
15603
15604 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
15605
15606 if (previousNewFiber === null) {
15607 // TODO: Move out of the loop. This only happens for the first run.
15608 resultingFirstChild = _newFiber3;
15609 } else {
15610 previousNewFiber.sibling = _newFiber3;
15611 }
15612
15613 previousNewFiber = _newFiber3;
15614 }
15615
15616 if (getIsHydrating()) {
15617 var _numberOfForks3 = newIdx;
15618 pushTreeFork(returnFiber, _numberOfForks3);
15619 }
15620
15621 return resultingFirstChild;
15622 } // Add all children to a key map for quick lookups.
15623
15624
15625 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
15626
15627 for (; !step.done; newIdx++, step = newChildren.next()) {
15628 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
15629
15630 if (_newFiber4 !== null) {
15631 if (shouldTrackSideEffects) {
15632 if (_newFiber4.alternate !== null) {
15633 // The new fiber is a work in progress, but if there exists a
15634 // current, that means that we reused the fiber. We need to delete
15635 // it from the child list so that we don't add it to the deletion
15636 // list.
15637 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
15638 }
15639 }
15640
15641 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
15642
15643 if (previousNewFiber === null) {
15644 resultingFirstChild = _newFiber4;
15645 } else {
15646 previousNewFiber.sibling = _newFiber4;
15647 }
15648
15649 previousNewFiber = _newFiber4;
15650 }
15651 }
15652
15653 if (shouldTrackSideEffects) {
15654 // Any existing children that weren't consumed above were deleted. We need
15655 // to add them to the deletion list.
15656 existingChildren.forEach(function (child) {
15657 return deleteChild(returnFiber, child);
15658 });
15659 }
15660
15661 if (getIsHydrating()) {
15662 var _numberOfForks4 = newIdx;
15663 pushTreeFork(returnFiber, _numberOfForks4);
15664 }
15665
15666 return resultingFirstChild;
15667 }
15668
15669 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
15670 // There's no need to check for keys on text nodes since we don't have a
15671 // way to define them.
15672 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
15673 // We already have an existing node so let's just update it and delete
15674 // the rest.
15675 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
15676 var existing = useFiber(currentFirstChild, textContent);
15677 existing.return = returnFiber;
15678 return existing;
15679 } // The existing first child is not a text node so we need to create one
15680 // and delete the existing ones.
15681
15682
15683 deleteRemainingChildren(returnFiber, currentFirstChild);
15684 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
15685 created.return = returnFiber;
15686 return created;
15687 }
15688
15689 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
15690 var key = element.key;
15691 var child = currentFirstChild;
15692
15693 while (child !== null) {
15694 // TODO: If key === null and child.key === null, then this only applies to
15695 // the first item in the list.
15696 if (child.key === key) {
15697 var elementType = element.type;
15698
15699 if (elementType === REACT_FRAGMENT_TYPE) {
15700 if (child.tag === Fragment) {
15701 deleteRemainingChildren(returnFiber, child.sibling);
15702 var existing = useFiber(child, element.props.children);
15703 existing.return = returnFiber;
15704
15705 {
15706 existing._debugSource = element._source;
15707 existing._debugOwner = element._owner;
15708 }
15709
15710 return existing;
15711 }
15712 } else {
15713 if (child.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
15714 isCompatibleFamilyForHotReloading(child, element) ) || // Lazy types should reconcile their resolved type.
15715 // We need to do this after the Hot Reloading check above,
15716 // because hot reloading has different semantics than prod because
15717 // it doesn't resuspend. So we can't let the call below suspend.
15718 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) {
15719 deleteRemainingChildren(returnFiber, child.sibling);
15720
15721 var _existing = useFiber(child, element.props);
15722
15723 _existing.ref = coerceRef(returnFiber, child, element);
15724 _existing.return = returnFiber;
15725
15726 {
15727 _existing._debugSource = element._source;
15728 _existing._debugOwner = element._owner;
15729 }
15730
15731 return _existing;
15732 }
15733 } // Didn't match.
15734
15735
15736 deleteRemainingChildren(returnFiber, child);
15737 break;
15738 } else {
15739 deleteChild(returnFiber, child);
15740 }
15741
15742 child = child.sibling;
15743 }
15744
15745 if (element.type === REACT_FRAGMENT_TYPE) {
15746 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
15747 created.return = returnFiber;
15748 return created;
15749 } else {
15750 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
15751
15752 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
15753 _created4.return = returnFiber;
15754 return _created4;
15755 }
15756 }
15757
15758 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
15759 var key = portal.key;
15760 var child = currentFirstChild;
15761
15762 while (child !== null) {
15763 // TODO: If key === null and child.key === null, then this only applies to
15764 // the first item in the list.
15765 if (child.key === key) {
15766 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
15767 deleteRemainingChildren(returnFiber, child.sibling);
15768 var existing = useFiber(child, portal.children || []);
15769 existing.return = returnFiber;
15770 return existing;
15771 } else {
15772 deleteRemainingChildren(returnFiber, child);
15773 break;
15774 }
15775 } else {
15776 deleteChild(returnFiber, child);
15777 }
15778
15779 child = child.sibling;
15780 }
15781
15782 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
15783 created.return = returnFiber;
15784 return created;
15785 } // This API will tag the children with the side-effect of the reconciliation
15786 // itself. They will be added to the side-effect list as we pass through the
15787 // children and the parent.
15788
15789
15790 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
15791 // This function is not recursive.
15792 // If the top level item is an array, we treat it as a set of children,
15793 // not as a fragment. Nested arrays on the other hand will be treated as
15794 // fragment nodes. Recursion happens at the normal flow.
15795 // Handle top level unkeyed fragments as if they were arrays.
15796 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
15797 // We treat the ambiguous cases above the same.
15798 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
15799
15800 if (isUnkeyedTopLevelFragment) {
15801 newChild = newChild.props.children;
15802 } // Handle object types
15803
15804
15805 if (typeof newChild === 'object' && newChild !== null) {
15806 switch (newChild.$$typeof) {
15807 case REACT_ELEMENT_TYPE:
15808 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
15809
15810 case REACT_PORTAL_TYPE:
15811 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
15812
15813 case REACT_LAZY_TYPE:
15814 var payload = newChild._payload;
15815 var init = newChild._init; // TODO: This function is supposed to be non-recursive.
15816
15817 return reconcileChildFibers(returnFiber, currentFirstChild, init(payload), lanes);
15818 }
15819
15820 if (isArray(newChild)) {
15821 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
15822 }
15823
15824 if (getIteratorFn(newChild)) {
15825 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
15826 }
15827
15828 throwOnInvalidObjectType(returnFiber, newChild);
15829 }
15830
15831 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
15832 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes));
15833 }
15834
15835 {
15836 if (typeof newChild === 'function') {
15837 warnOnFunctionType(returnFiber);
15838 }
15839 } // Remaining cases are all treated as empty.
15840
15841
15842 return deleteRemainingChildren(returnFiber, currentFirstChild);
15843 }
15844
15845 return reconcileChildFibers;
15846}
15847
15848var reconcileChildFibers = ChildReconciler(true);
15849var mountChildFibers = ChildReconciler(false);
15850function cloneChildFibers(current, workInProgress) {
15851 if (current !== null && workInProgress.child !== current.child) {
15852 throw new Error('Resuming work not yet implemented.');
15853 }
15854
15855 if (workInProgress.child === null) {
15856 return;
15857 }
15858
15859 var currentChild = workInProgress.child;
15860 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
15861 workInProgress.child = newChild;
15862 newChild.return = workInProgress;
15863
15864 while (currentChild.sibling !== null) {
15865 currentChild = currentChild.sibling;
15866 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
15867 newChild.return = workInProgress;
15868 }
15869
15870 newChild.sibling = null;
15871} // Reset a workInProgress child set to prepare it for a second pass.
15872
15873function resetChildFibers(workInProgress, lanes) {
15874 var child = workInProgress.child;
15875
15876 while (child !== null) {
15877 resetWorkInProgress(child, lanes);
15878 child = child.sibling;
15879 }
15880}
15881
15882var NO_CONTEXT = {};
15883var contextStackCursor$1 = createCursor(NO_CONTEXT);
15884var contextFiberStackCursor = createCursor(NO_CONTEXT);
15885var rootInstanceStackCursor = createCursor(NO_CONTEXT);
15886
15887function requiredContext(c) {
15888 if (c === NO_CONTEXT) {
15889 throw new Error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.');
15890 }
15891
15892 return c;
15893}
15894
15895function getRootHostContainer() {
15896 var rootInstance = requiredContext(rootInstanceStackCursor.current);
15897 return rootInstance;
15898}
15899
15900function pushHostContainer(fiber, nextRootInstance) {
15901 // Push current root instance onto the stack;
15902 // This allows us to reset root when portals are popped.
15903 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
15904 // This enables us to pop only Fibers that provide unique contexts.
15905
15906 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
15907 // However, we can't just call getRootHostContext() and push it because
15908 // we'd have a different number of entries on the stack depending on
15909 // whether getRootHostContext() throws somewhere in renderer code or not.
15910 // So we push an empty value first. This lets us safely unwind on errors.
15911
15912 push(contextStackCursor$1, NO_CONTEXT, fiber);
15913 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
15914
15915 pop(contextStackCursor$1, fiber);
15916 push(contextStackCursor$1, nextRootContext, fiber);
15917}
15918
15919function popHostContainer(fiber) {
15920 pop(contextStackCursor$1, fiber);
15921 pop(contextFiberStackCursor, fiber);
15922 pop(rootInstanceStackCursor, fiber);
15923}
15924
15925function getHostContext() {
15926 var context = requiredContext(contextStackCursor$1.current);
15927 return context;
15928}
15929
15930function pushHostContext(fiber) {
15931 var rootInstance = requiredContext(rootInstanceStackCursor.current);
15932 var context = requiredContext(contextStackCursor$1.current);
15933 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
15934
15935 if (context === nextContext) {
15936 return;
15937 } // Track the context and the Fiber that provided it.
15938 // This enables us to pop only Fibers that provide unique contexts.
15939
15940
15941 push(contextFiberStackCursor, fiber, fiber);
15942 push(contextStackCursor$1, nextContext, fiber);
15943}
15944
15945function popHostContext(fiber) {
15946 // Do not pop unless this Fiber provided the current context.
15947 // pushHostContext() only pushes Fibers that provide unique contexts.
15948 if (contextFiberStackCursor.current !== fiber) {
15949 return;
15950 }
15951
15952 pop(contextStackCursor$1, fiber);
15953 pop(contextFiberStackCursor, fiber);
15954}
15955
15956var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
15957// inherited deeply down the subtree. The upper bits only affect
15958// this immediate suspense boundary and gets reset each new
15959// boundary or suspense list.
15960
15961var SubtreeSuspenseContextMask = 1; // Subtree Flags:
15962// InvisibleParentSuspenseContext indicates that one of our parent Suspense
15963// boundaries is not currently showing visible main content.
15964// Either because it is already showing a fallback or is not mounted at all.
15965// We can use this to determine if it is desirable to trigger a fallback at
15966// the parent. If not, then we might need to trigger undesirable boundaries
15967// and/or suspend the commit to avoid hiding the parent content.
15968
15969var InvisibleParentSuspenseContext = 1; // Shallow Flags:
15970// ForceSuspenseFallback can be used by SuspenseList to force newly added
15971// items into their fallback state during one of the render passes.
15972
15973var ForceSuspenseFallback = 2;
15974var suspenseStackCursor = createCursor(DefaultSuspenseContext);
15975function hasSuspenseContext(parentContext, flag) {
15976 return (parentContext & flag) !== 0;
15977}
15978function setDefaultShallowSuspenseContext(parentContext) {
15979 return parentContext & SubtreeSuspenseContextMask;
15980}
15981function setShallowSuspenseContext(parentContext, shallowContext) {
15982 return parentContext & SubtreeSuspenseContextMask | shallowContext;
15983}
15984function addSubtreeSuspenseContext(parentContext, subtreeContext) {
15985 return parentContext | subtreeContext;
15986}
15987function pushSuspenseContext(fiber, newContext) {
15988 push(suspenseStackCursor, newContext, fiber);
15989}
15990function popSuspenseContext(fiber) {
15991 pop(suspenseStackCursor, fiber);
15992}
15993
15994function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
15995 // If it was the primary children that just suspended, capture and render the
15996 // fallback. Otherwise, don't capture and bubble to the next boundary.
15997 var nextState = workInProgress.memoizedState;
15998
15999 if (nextState !== null) {
16000 if (nextState.dehydrated !== null) {
16001 // A dehydrated boundary always captures.
16002 return true;
16003 }
16004
16005 return false;
16006 }
16007
16008 var props = workInProgress.memoizedProps; // Regular boundaries always capture.
16009
16010 {
16011 return true;
16012 } // If it's a boundary we should avoid, then we prefer to bubble up to the
16013}
16014function findFirstSuspended(row) {
16015 var node = row;
16016
16017 while (node !== null) {
16018 if (node.tag === SuspenseComponent) {
16019 var state = node.memoizedState;
16020
16021 if (state !== null) {
16022 var dehydrated = state.dehydrated;
16023
16024 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
16025 return node;
16026 }
16027 }
16028 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
16029 // keep track of whether it suspended or not.
16030 node.memoizedProps.revealOrder !== undefined) {
16031 var didSuspend = (node.flags & DidCapture) !== NoFlags;
16032
16033 if (didSuspend) {
16034 return node;
16035 }
16036 } else if (node.child !== null) {
16037 node.child.return = node;
16038 node = node.child;
16039 continue;
16040 }
16041
16042 if (node === row) {
16043 return null;
16044 }
16045
16046 while (node.sibling === null) {
16047 if (node.return === null || node.return === row) {
16048 return null;
16049 }
16050
16051 node = node.return;
16052 }
16053
16054 node.sibling.return = node.return;
16055 node = node.sibling;
16056 }
16057
16058 return null;
16059}
16060
16061var NoFlags$1 =
16062/* */
160630; // Represents whether effect should fire.
16064
16065var HasEffect =
16066/* */
160671; // Represents the phase in which the effect (not the clean-up) fires.
16068
16069var Insertion =
16070/* */
160712;
16072var Layout =
16073/* */
160744;
16075var Passive$1 =
16076/* */
160778;
16078
16079// and should be reset before starting a new render.
16080// This tracks which mutable sources need to be reset after a render.
16081
16082var workInProgressSources = [];
16083function resetWorkInProgressVersions() {
16084 for (var i = 0; i < workInProgressSources.length; i++) {
16085 var mutableSource = workInProgressSources[i];
16086
16087 {
16088 mutableSource._workInProgressVersionPrimary = null;
16089 }
16090 }
16091
16092 workInProgressSources.length = 0;
16093}
16094// This ensures that the version used for server rendering matches the one
16095// that is eventually read during hydration.
16096// If they don't match there's a potential tear and a full deopt render is required.
16097
16098function registerMutableSourceForHydration(root, mutableSource) {
16099 var getVersion = mutableSource._getVersion;
16100 var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished.
16101 // Retaining it forever may interfere with GC.
16102
16103 if (root.mutableSourceEagerHydrationData == null) {
16104 root.mutableSourceEagerHydrationData = [mutableSource, version];
16105 } else {
16106 root.mutableSourceEagerHydrationData.push(mutableSource, version);
16107 }
16108}
16109
16110var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
16111 ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig;
16112var didWarnAboutMismatchedHooksForComponent;
16113var didWarnUncachedGetSnapshot;
16114
16115{
16116 didWarnAboutMismatchedHooksForComponent = new Set();
16117}
16118
16119// These are set right before calling the component.
16120var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
16121// the work-in-progress hook.
16122
16123var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
16124// current hook list is the list that belongs to the current fiber. The
16125// work-in-progress hook list is a new list that will be added to the
16126// work-in-progress fiber.
16127
16128var currentHook = null;
16129var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
16130// does not get reset if we do another render pass; only when we're completely
16131// finished evaluating this component. This is an optimization so we know
16132// whether we need to clear render phase updates after a throw.
16133
16134var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
16135// gets reset after each attempt.
16136// TODO: Maybe there's some way to consolidate this with
16137// `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
16138
16139var didScheduleRenderPhaseUpdateDuringThisPass = false; // Counts the number of useId hooks in this component.
16140
16141var localIdCounter = 0; // Used for ids that are generated completely client-side (i.e. not during
16142// hydration). This counter is global, so client ids are not stable across
16143// render attempts.
16144
16145var globalClientIdCounter = 0;
16146var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
16147
16148var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
16149// The list stores the order of hooks used during the initial render (mount).
16150// Subsequent renders (updates) reference this list.
16151
16152var hookTypesDev = null;
16153var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
16154// the dependencies for Hooks that need them (e.g. useEffect or useMemo).
16155// When true, such Hooks will always be "remounted". Only used during hot reload.
16156
16157var ignorePreviousDependencies = false;
16158
16159function mountHookTypesDev() {
16160 {
16161 var hookName = currentHookNameInDev;
16162
16163 if (hookTypesDev === null) {
16164 hookTypesDev = [hookName];
16165 } else {
16166 hookTypesDev.push(hookName);
16167 }
16168 }
16169}
16170
16171function updateHookTypesDev() {
16172 {
16173 var hookName = currentHookNameInDev;
16174
16175 if (hookTypesDev !== null) {
16176 hookTypesUpdateIndexDev++;
16177
16178 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
16179 warnOnHookMismatchInDev(hookName);
16180 }
16181 }
16182 }
16183}
16184
16185function checkDepsAreArrayDev(deps) {
16186 {
16187 if (deps !== undefined && deps !== null && !isArray(deps)) {
16188 // Verify deps, but only on mount to avoid extra checks.
16189 // It's unlikely their type would change as usually you define them inline.
16190 error('%s received a final argument that is not an array (instead, received `%s`). When ' + 'specified, the final argument must be an array.', currentHookNameInDev, typeof deps);
16191 }
16192 }
16193}
16194
16195function warnOnHookMismatchInDev(currentHookName) {
16196 {
16197 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
16198
16199 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
16200 didWarnAboutMismatchedHooksForComponent.add(componentName);
16201
16202 if (hookTypesDev !== null) {
16203 var table = '';
16204 var secondColumnStart = 30;
16205
16206 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
16207 var oldHookName = hookTypesDev[i];
16208 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
16209 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
16210 // lol @ IE not supporting String#repeat
16211
16212 while (row.length < secondColumnStart) {
16213 row += ' ';
16214 }
16215
16216 row += newHookName + '\n';
16217 table += row;
16218 }
16219
16220 error('React has detected a change in the order of Hooks called by %s. ' + 'This will lead to bugs and errors if not fixed. ' + 'For more information, read the Rules of Hooks: https://reactjs.org/link/rules-of-hooks\n\n' + ' Previous render Next render\n' + ' ------------------------------------------------------\n' + '%s' + ' ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n', componentName, table);
16221 }
16222 }
16223 }
16224}
16225
16226function throwInvalidHookError() {
16227 throw new 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:\n' + '1. You might have mismatching versions of React and the renderer (such as React DOM)\n' + '2. You might be breaking the Rules of Hooks\n' + '3. You might have more than one copy of React in the same app\n' + 'See https://reactjs.org/link/invalid-hook-call for tips about how to debug and fix this problem.');
16228}
16229
16230function areHookInputsEqual(nextDeps, prevDeps) {
16231 {
16232 if (ignorePreviousDependencies) {
16233 // Only true when this component is being hot reloaded.
16234 return false;
16235 }
16236 }
16237
16238 if (prevDeps === null) {
16239 {
16240 error('%s received a final argument during this render, but not during ' + 'the previous render. Even though the final argument is optional, ' + 'its type cannot change between renders.', currentHookNameInDev);
16241 }
16242
16243 return false;
16244 }
16245
16246 {
16247 // Don't bother comparing lengths in prod because these arrays should be
16248 // passed inline.
16249 if (nextDeps.length !== prevDeps.length) {
16250 error('The final argument passed to %s changed size between renders. The ' + 'order and size of this array must remain constant.\n\n' + 'Previous: %s\n' + 'Incoming: %s', currentHookNameInDev, "[" + prevDeps.join(', ') + "]", "[" + nextDeps.join(', ') + "]");
16251 }
16252 }
16253
16254 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
16255 if (objectIs(nextDeps[i], prevDeps[i])) {
16256 continue;
16257 }
16258
16259 return false;
16260 }
16261
16262 return true;
16263}
16264
16265function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
16266 renderLanes = nextRenderLanes;
16267 currentlyRenderingFiber$1 = workInProgress;
16268
16269 {
16270 hookTypesDev = current !== null ? current._debugHookTypes : null;
16271 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
16272
16273 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
16274 }
16275
16276 workInProgress.memoizedState = null;
16277 workInProgress.updateQueue = null;
16278 workInProgress.lanes = NoLanes; // The following should have already been reset
16279 // currentHook = null;
16280 // workInProgressHook = null;
16281 // didScheduleRenderPhaseUpdate = false;
16282 // localIdCounter = 0;
16283 // TODO Warn if no hooks are used at all during mount, then some are used during update.
16284 // Currently we will identify the update render as a mount because memoizedState === null.
16285 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
16286 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
16287 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
16288 // so memoizedState would be null during updates and mounts.
16289
16290 {
16291 if (current !== null && current.memoizedState !== null) {
16292 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
16293 } else if (hookTypesDev !== null) {
16294 // This dispatcher handles an edge case where a component is updating,
16295 // but no stateful hooks have been used.
16296 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
16297 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
16298 // This dispatcher does that.
16299 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
16300 } else {
16301 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
16302 }
16303 }
16304
16305 var children = Component(props, secondArg); // Check if there was a render phase update
16306
16307 if (didScheduleRenderPhaseUpdateDuringThisPass) {
16308 // Keep rendering in a loop for as long as render phase updates continue to
16309 // be scheduled. Use a counter to prevent infinite loops.
16310 var numberOfReRenders = 0;
16311
16312 do {
16313 didScheduleRenderPhaseUpdateDuringThisPass = false;
16314 localIdCounter = 0;
16315
16316 if (numberOfReRenders >= RE_RENDER_LIMIT) {
16317 throw new Error('Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.');
16318 }
16319
16320 numberOfReRenders += 1;
16321
16322 {
16323 // Even when hot reloading, allow dependencies to stabilize
16324 // after first render to prevent infinite render phase updates.
16325 ignorePreviousDependencies = false;
16326 } // Start over from the beginning of the list
16327
16328
16329 currentHook = null;
16330 workInProgressHook = null;
16331 workInProgress.updateQueue = null;
16332
16333 {
16334 // Also validate hook order for cascading updates.
16335 hookTypesUpdateIndexDev = -1;
16336 }
16337
16338 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ;
16339 children = Component(props, secondArg);
16340 } while (didScheduleRenderPhaseUpdateDuringThisPass);
16341 } // We can assume the previous dispatcher is always this one, since we set it
16342 // at the beginning of the render phase and there's no re-entrance.
16343
16344
16345 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
16346
16347 {
16348 workInProgress._debugHookTypes = hookTypesDev;
16349 } // This check uses currentHook so that it works the same in DEV and prod bundles.
16350 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
16351
16352
16353 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
16354 renderLanes = NoLanes;
16355 currentlyRenderingFiber$1 = null;
16356 currentHook = null;
16357 workInProgressHook = null;
16358
16359 {
16360 currentHookNameInDev = null;
16361 hookTypesDev = null;
16362 hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last
16363 // render. If this fires, it suggests that we incorrectly reset the static
16364 // flags in some other part of the codebase. This has happened before, for
16365 // example, in the SuspenseList implementation.
16366
16367 if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird
16368 // and creates false positives. To make this work in legacy mode, we'd
16369 // need to mark fibers that commit in an incomplete state, somehow. For
16370 // now I'll disable the warning that most of the bugs that would trigger
16371 // it are either exclusive to concurrent mode or exist in both.
16372 (current.mode & ConcurrentMode) !== NoMode) {
16373 error('Internal React error: Expected static flag was missing. Please ' + 'notify the React team.');
16374 }
16375 }
16376
16377 didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook
16378 // localIdCounter = 0;
16379
16380 if (didRenderTooFewHooks) {
16381 throw new Error('Rendered fewer hooks than expected. This may be caused by an accidental ' + 'early return statement.');
16382 }
16383
16384 return children;
16385}
16386function checkDidRenderIdHook() {
16387 // This should be called immediately after every renderWithHooks call.
16388 // Conceptually, it's part of the return value of renderWithHooks; it's only a
16389 // separate function to avoid using an array tuple.
16390 var didRenderIdHook = localIdCounter !== 0;
16391 localIdCounter = 0;
16392 return didRenderIdHook;
16393}
16394function bailoutHooks(current, workInProgress, lanes) {
16395 workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the
16396 // complete phase (bubbleProperties).
16397
16398 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
16399 workInProgress.flags &= ~(MountPassiveDev | MountLayoutDev | Passive | Update);
16400 } else {
16401 workInProgress.flags &= ~(Passive | Update);
16402 }
16403
16404 current.lanes = removeLanes(current.lanes, lanes);
16405}
16406function resetHooksAfterThrow() {
16407 // We can assume the previous dispatcher is always this one, since we set it
16408 // at the beginning of the render phase and there's no re-entrance.
16409 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
16410
16411 if (didScheduleRenderPhaseUpdate) {
16412 // There were render phase updates. These are only valid for this render
16413 // phase, which we are now aborting. Remove the updates from the queues so
16414 // they do not persist to the next render. Do not remove updates from hooks
16415 // that weren't processed.
16416 //
16417 // Only reset the updates from the queue if it has a clone. If it does
16418 // not have a clone, that means it wasn't processed, and the updates were
16419 // scheduled before we entered the render phase.
16420 var hook = currentlyRenderingFiber$1.memoizedState;
16421
16422 while (hook !== null) {
16423 var queue = hook.queue;
16424
16425 if (queue !== null) {
16426 queue.pending = null;
16427 }
16428
16429 hook = hook.next;
16430 }
16431
16432 didScheduleRenderPhaseUpdate = false;
16433 }
16434
16435 renderLanes = NoLanes;
16436 currentlyRenderingFiber$1 = null;
16437 currentHook = null;
16438 workInProgressHook = null;
16439
16440 {
16441 hookTypesDev = null;
16442 hookTypesUpdateIndexDev = -1;
16443 currentHookNameInDev = null;
16444 isUpdatingOpaqueValueInRenderPhase = false;
16445 }
16446
16447 didScheduleRenderPhaseUpdateDuringThisPass = false;
16448 localIdCounter = 0;
16449}
16450
16451function mountWorkInProgressHook() {
16452 var hook = {
16453 memoizedState: null,
16454 baseState: null,
16455 baseQueue: null,
16456 queue: null,
16457 next: null
16458 };
16459
16460 if (workInProgressHook === null) {
16461 // This is the first hook in the list
16462 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
16463 } else {
16464 // Append to the end of the list
16465 workInProgressHook = workInProgressHook.next = hook;
16466 }
16467
16468 return workInProgressHook;
16469}
16470
16471function updateWorkInProgressHook() {
16472 // This function is used both for updates and for re-renders triggered by a
16473 // render phase update. It assumes there is either a current hook we can
16474 // clone, or a work-in-progress hook from a previous render pass that we can
16475 // use as a base. When we reach the end of the base list, we must switch to
16476 // the dispatcher used for mounts.
16477 var nextCurrentHook;
16478
16479 if (currentHook === null) {
16480 var current = currentlyRenderingFiber$1.alternate;
16481
16482 if (current !== null) {
16483 nextCurrentHook = current.memoizedState;
16484 } else {
16485 nextCurrentHook = null;
16486 }
16487 } else {
16488 nextCurrentHook = currentHook.next;
16489 }
16490
16491 var nextWorkInProgressHook;
16492
16493 if (workInProgressHook === null) {
16494 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
16495 } else {
16496 nextWorkInProgressHook = workInProgressHook.next;
16497 }
16498
16499 if (nextWorkInProgressHook !== null) {
16500 // There's already a work-in-progress. Reuse it.
16501 workInProgressHook = nextWorkInProgressHook;
16502 nextWorkInProgressHook = workInProgressHook.next;
16503 currentHook = nextCurrentHook;
16504 } else {
16505 // Clone from the current hook.
16506 if (nextCurrentHook === null) {
16507 throw new Error('Rendered more hooks than during the previous render.');
16508 }
16509
16510 currentHook = nextCurrentHook;
16511 var newHook = {
16512 memoizedState: currentHook.memoizedState,
16513 baseState: currentHook.baseState,
16514 baseQueue: currentHook.baseQueue,
16515 queue: currentHook.queue,
16516 next: null
16517 };
16518
16519 if (workInProgressHook === null) {
16520 // This is the first hook in the list.
16521 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
16522 } else {
16523 // Append to the end of the list.
16524 workInProgressHook = workInProgressHook.next = newHook;
16525 }
16526 }
16527
16528 return workInProgressHook;
16529}
16530
16531function createFunctionComponentUpdateQueue() {
16532 return {
16533 lastEffect: null,
16534 stores: null
16535 };
16536}
16537
16538function basicStateReducer(state, action) {
16539 // $FlowFixMe: Flow doesn't like mixed types
16540 return typeof action === 'function' ? action(state) : action;
16541}
16542
16543function mountReducer(reducer, initialArg, init) {
16544 var hook = mountWorkInProgressHook();
16545 var initialState;
16546
16547 if (init !== undefined) {
16548 initialState = init(initialArg);
16549 } else {
16550 initialState = initialArg;
16551 }
16552
16553 hook.memoizedState = hook.baseState = initialState;
16554 var queue = {
16555 pending: null,
16556 interleaved: null,
16557 lanes: NoLanes,
16558 dispatch: null,
16559 lastRenderedReducer: reducer,
16560 lastRenderedState: initialState
16561 };
16562 hook.queue = queue;
16563 var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
16564 return [hook.memoizedState, dispatch];
16565}
16566
16567function updateReducer(reducer, initialArg, init) {
16568 var hook = updateWorkInProgressHook();
16569 var queue = hook.queue;
16570
16571 if (queue === null) {
16572 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
16573 }
16574
16575 queue.lastRenderedReducer = reducer;
16576 var current = currentHook; // The last rebase update that is NOT part of the base state.
16577
16578 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
16579
16580 var pendingQueue = queue.pending;
16581
16582 if (pendingQueue !== null) {
16583 // We have new updates that haven't been processed yet.
16584 // We'll add them to the base queue.
16585 if (baseQueue !== null) {
16586 // Merge the pending queue and the base queue.
16587 var baseFirst = baseQueue.next;
16588 var pendingFirst = pendingQueue.next;
16589 baseQueue.next = pendingFirst;
16590 pendingQueue.next = baseFirst;
16591 }
16592
16593 {
16594 if (current.baseQueue !== baseQueue) {
16595 // Internal invariant that should never happen, but feasibly could in
16596 // the future if we implement resuming, or some form of that.
16597 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');
16598 }
16599 }
16600
16601 current.baseQueue = baseQueue = pendingQueue;
16602 queue.pending = null;
16603 }
16604
16605 if (baseQueue !== null) {
16606 // We have a queue to process.
16607 var first = baseQueue.next;
16608 var newState = current.baseState;
16609 var newBaseState = null;
16610 var newBaseQueueFirst = null;
16611 var newBaseQueueLast = null;
16612 var update = first;
16613
16614 do {
16615 var updateLane = update.lane;
16616
16617 if (!isSubsetOfLanes(renderLanes, updateLane)) {
16618 // Priority is insufficient. Skip this update. If this is the first
16619 // skipped update, the previous update/state is the new base
16620 // update/state.
16621 var clone = {
16622 lane: updateLane,
16623 action: update.action,
16624 hasEagerState: update.hasEagerState,
16625 eagerState: update.eagerState,
16626 next: null
16627 };
16628
16629 if (newBaseQueueLast === null) {
16630 newBaseQueueFirst = newBaseQueueLast = clone;
16631 newBaseState = newState;
16632 } else {
16633 newBaseQueueLast = newBaseQueueLast.next = clone;
16634 } // Update the remaining priority in the queue.
16635 // TODO: Don't need to accumulate this. Instead, we can remove
16636 // renderLanes from the original lanes.
16637
16638
16639 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
16640 markSkippedUpdateLanes(updateLane);
16641 } else {
16642 // This update does have sufficient priority.
16643 if (newBaseQueueLast !== null) {
16644 var _clone = {
16645 // This update is going to be committed so we never want uncommit
16646 // it. Using NoLane works because 0 is a subset of all bitmasks, so
16647 // this will never be skipped by the check above.
16648 lane: NoLane,
16649 action: update.action,
16650 hasEagerState: update.hasEagerState,
16651 eagerState: update.eagerState,
16652 next: null
16653 };
16654 newBaseQueueLast = newBaseQueueLast.next = _clone;
16655 } // Process this update.
16656
16657
16658 if (update.hasEagerState) {
16659 // If this update is a state update (not a reducer) and was processed eagerly,
16660 // we can use the eagerly computed state
16661 newState = update.eagerState;
16662 } else {
16663 var action = update.action;
16664 newState = reducer(newState, action);
16665 }
16666 }
16667
16668 update = update.next;
16669 } while (update !== null && update !== first);
16670
16671 if (newBaseQueueLast === null) {
16672 newBaseState = newState;
16673 } else {
16674 newBaseQueueLast.next = newBaseQueueFirst;
16675 } // Mark that the fiber performed work, but only if the new state is
16676 // different from the current state.
16677
16678
16679 if (!objectIs(newState, hook.memoizedState)) {
16680 markWorkInProgressReceivedUpdate();
16681 }
16682
16683 hook.memoizedState = newState;
16684 hook.baseState = newBaseState;
16685 hook.baseQueue = newBaseQueueLast;
16686 queue.lastRenderedState = newState;
16687 } // Interleaved updates are stored on a separate queue. We aren't going to
16688 // process them during this render, but we do need to track which lanes
16689 // are remaining.
16690
16691
16692 var lastInterleaved = queue.interleaved;
16693
16694 if (lastInterleaved !== null) {
16695 var interleaved = lastInterleaved;
16696
16697 do {
16698 var interleavedLane = interleaved.lane;
16699 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane);
16700 markSkippedUpdateLanes(interleavedLane);
16701 interleaved = interleaved.next;
16702 } while (interleaved !== lastInterleaved);
16703 } else if (baseQueue === null) {
16704 // `queue.lanes` is used for entangling transitions. We can set it back to
16705 // zero once the queue is empty.
16706 queue.lanes = NoLanes;
16707 }
16708
16709 var dispatch = queue.dispatch;
16710 return [hook.memoizedState, dispatch];
16711}
16712
16713function rerenderReducer(reducer, initialArg, init) {
16714 var hook = updateWorkInProgressHook();
16715 var queue = hook.queue;
16716
16717 if (queue === null) {
16718 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
16719 }
16720
16721 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
16722 // work-in-progress hook.
16723
16724 var dispatch = queue.dispatch;
16725 var lastRenderPhaseUpdate = queue.pending;
16726 var newState = hook.memoizedState;
16727
16728 if (lastRenderPhaseUpdate !== null) {
16729 // The queue doesn't persist past this render pass.
16730 queue.pending = null;
16731 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
16732 var update = firstRenderPhaseUpdate;
16733
16734 do {
16735 // Process this render phase update. We don't have to check the
16736 // priority because it will always be the same as the current
16737 // render's.
16738 var action = update.action;
16739 newState = reducer(newState, action);
16740 update = update.next;
16741 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
16742 // different from the current state.
16743
16744
16745 if (!objectIs(newState, hook.memoizedState)) {
16746 markWorkInProgressReceivedUpdate();
16747 }
16748
16749 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
16750 // the base state unless the queue is empty.
16751 // TODO: Not sure if this is the desired semantics, but it's what we
16752 // do for gDSFP. I can't remember why.
16753
16754 if (hook.baseQueue === null) {
16755 hook.baseState = newState;
16756 }
16757
16758 queue.lastRenderedState = newState;
16759 }
16760
16761 return [newState, dispatch];
16762}
16763
16764function mountMutableSource(source, getSnapshot, subscribe) {
16765 {
16766 return undefined;
16767 }
16768}
16769
16770function updateMutableSource(source, getSnapshot, subscribe) {
16771 {
16772 return undefined;
16773 }
16774}
16775
16776function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
16777 var fiber = currentlyRenderingFiber$1;
16778 var hook = mountWorkInProgressHook();
16779 var nextSnapshot;
16780 var isHydrating = getIsHydrating();
16781
16782 if (isHydrating) {
16783 if (getServerSnapshot === undefined) {
16784 throw new Error('Missing getServerSnapshot, which is required for ' + 'server-rendered content. Will revert to client rendering.');
16785 }
16786
16787 nextSnapshot = getServerSnapshot();
16788
16789 {
16790 if (!didWarnUncachedGetSnapshot) {
16791 if (nextSnapshot !== getServerSnapshot()) {
16792 error('The result of getServerSnapshot should be cached to avoid an infinite loop');
16793
16794 didWarnUncachedGetSnapshot = true;
16795 }
16796 }
16797 }
16798 } else {
16799 nextSnapshot = getSnapshot();
16800
16801 {
16802 if (!didWarnUncachedGetSnapshot) {
16803 var cachedSnapshot = getSnapshot();
16804
16805 if (!objectIs(nextSnapshot, cachedSnapshot)) {
16806 error('The result of getSnapshot should be cached to avoid an infinite loop');
16807
16808 didWarnUncachedGetSnapshot = true;
16809 }
16810 }
16811 } // Unless we're rendering a blocking lane, schedule a consistency check.
16812 // Right before committing, we will walk the tree and check if any of the
16813 // stores were mutated.
16814 //
16815 // We won't do this if we're hydrating server-rendered content, because if
16816 // the content is stale, it's already visible anyway. Instead we'll patch
16817 // it up in a passive effect.
16818
16819
16820 var root = getWorkInProgressRoot();
16821
16822 if (root === null) {
16823 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
16824 }
16825
16826 if (!includesBlockingLane(root, renderLanes)) {
16827 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
16828 }
16829 } // Read the current snapshot from the store on every render. This breaks the
16830 // normal rules of React, and only works because store updates are
16831 // always synchronous.
16832
16833
16834 hook.memoizedState = nextSnapshot;
16835 var inst = {
16836 value: nextSnapshot,
16837 getSnapshot: getSnapshot
16838 };
16839 hook.queue = inst; // Schedule an effect to subscribe to the store.
16840
16841 mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update
16842 // this whenever subscribe, getSnapshot, or value changes. Because there's no
16843 // clean-up function, and we track the deps correctly, we can call pushEffect
16844 // directly, without storing any additional state. For the same reason, we
16845 // don't need to set a static flag, either.
16846 // TODO: We can move this to the passive phase once we add a pre-commit
16847 // consistency check. See the next comment.
16848
16849 fiber.flags |= Passive;
16850 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null);
16851 return nextSnapshot;
16852}
16853
16854function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
16855 var fiber = currentlyRenderingFiber$1;
16856 var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
16857 // normal rules of React, and only works because store updates are
16858 // always synchronous.
16859
16860 var nextSnapshot = getSnapshot();
16861
16862 {
16863 if (!didWarnUncachedGetSnapshot) {
16864 var cachedSnapshot = getSnapshot();
16865
16866 if (!objectIs(nextSnapshot, cachedSnapshot)) {
16867 error('The result of getSnapshot should be cached to avoid an infinite loop');
16868
16869 didWarnUncachedGetSnapshot = true;
16870 }
16871 }
16872 }
16873
16874 var prevSnapshot = hook.memoizedState;
16875 var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
16876
16877 if (snapshotChanged) {
16878 hook.memoizedState = nextSnapshot;
16879 markWorkInProgressReceivedUpdate();
16880 }
16881
16882 var inst = hook.queue;
16883 updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Whenever getSnapshot or subscribe changes, we need to check in the
16884 // commit phase if there was an interleaved mutation. In concurrent mode
16885 // this can happen all the time, but even in synchronous mode, an earlier
16886 // effect may have mutated the store.
16887
16888 if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the susbcribe function changed. We can save some memory by
16889 // checking whether we scheduled a subscription effect above.
16890 workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) {
16891 fiber.flags |= Passive;
16892 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); // Unless we're rendering a blocking lane, schedule a consistency check.
16893 // Right before committing, we will walk the tree and check if any of the
16894 // stores were mutated.
16895
16896 var root = getWorkInProgressRoot();
16897
16898 if (root === null) {
16899 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
16900 }
16901
16902 if (!includesBlockingLane(root, renderLanes)) {
16903 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
16904 }
16905 }
16906
16907 return nextSnapshot;
16908}
16909
16910function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
16911 fiber.flags |= StoreConsistency;
16912 var check = {
16913 getSnapshot: getSnapshot,
16914 value: renderedSnapshot
16915 };
16916 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
16917
16918 if (componentUpdateQueue === null) {
16919 componentUpdateQueue = createFunctionComponentUpdateQueue();
16920 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
16921 componentUpdateQueue.stores = [check];
16922 } else {
16923 var stores = componentUpdateQueue.stores;
16924
16925 if (stores === null) {
16926 componentUpdateQueue.stores = [check];
16927 } else {
16928 stores.push(check);
16929 }
16930 }
16931}
16932
16933function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
16934 // These are updated in the passive phase
16935 inst.value = nextSnapshot;
16936 inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
16937 // have been in an event that fired before the passive effects, or it could
16938 // have been in a layout effect. In that case, we would have used the old
16939 // snapsho and getSnapshot values to bail out. We need to check one more time.
16940
16941 if (checkIfSnapshotChanged(inst)) {
16942 // Force a re-render.
16943 forceStoreRerender(fiber);
16944 }
16945}
16946
16947function subscribeToStore(fiber, inst, subscribe) {
16948 var handleStoreChange = function () {
16949 // The store changed. Check if the snapshot changed since the last time we
16950 // read from the store.
16951 if (checkIfSnapshotChanged(inst)) {
16952 // Force a re-render.
16953 forceStoreRerender(fiber);
16954 }
16955 }; // Subscribe to the store and return a clean-up function.
16956
16957
16958 return subscribe(handleStoreChange);
16959}
16960
16961function checkIfSnapshotChanged(inst) {
16962 var latestGetSnapshot = inst.getSnapshot;
16963 var prevValue = inst.value;
16964
16965 try {
16966 var nextValue = latestGetSnapshot();
16967 return !objectIs(prevValue, nextValue);
16968 } catch (error) {
16969 return true;
16970 }
16971}
16972
16973function forceStoreRerender(fiber) {
16974 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
16975
16976 if (root !== null) {
16977 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
16978 }
16979}
16980
16981function mountState(initialState) {
16982 var hook = mountWorkInProgressHook();
16983
16984 if (typeof initialState === 'function') {
16985 // $FlowFixMe: Flow doesn't like mixed types
16986 initialState = initialState();
16987 }
16988
16989 hook.memoizedState = hook.baseState = initialState;
16990 var queue = {
16991 pending: null,
16992 interleaved: null,
16993 lanes: NoLanes,
16994 dispatch: null,
16995 lastRenderedReducer: basicStateReducer,
16996 lastRenderedState: initialState
16997 };
16998 hook.queue = queue;
16999 var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
17000 return [hook.memoizedState, dispatch];
17001}
17002
17003function updateState(initialState) {
17004 return updateReducer(basicStateReducer);
17005}
17006
17007function rerenderState(initialState) {
17008 return rerenderReducer(basicStateReducer);
17009}
17010
17011function pushEffect(tag, create, destroy, deps) {
17012 var effect = {
17013 tag: tag,
17014 create: create,
17015 destroy: destroy,
17016 deps: deps,
17017 // Circular
17018 next: null
17019 };
17020 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
17021
17022 if (componentUpdateQueue === null) {
17023 componentUpdateQueue = createFunctionComponentUpdateQueue();
17024 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
17025 componentUpdateQueue.lastEffect = effect.next = effect;
17026 } else {
17027 var lastEffect = componentUpdateQueue.lastEffect;
17028
17029 if (lastEffect === null) {
17030 componentUpdateQueue.lastEffect = effect.next = effect;
17031 } else {
17032 var firstEffect = lastEffect.next;
17033 lastEffect.next = effect;
17034 effect.next = firstEffect;
17035 componentUpdateQueue.lastEffect = effect;
17036 }
17037 }
17038
17039 return effect;
17040}
17041
17042function mountRef(initialValue) {
17043 var hook = mountWorkInProgressHook();
17044
17045 {
17046 var _ref2 = {
17047 current: initialValue
17048 };
17049 hook.memoizedState = _ref2;
17050 return _ref2;
17051 }
17052}
17053
17054function updateRef(initialValue) {
17055 var hook = updateWorkInProgressHook();
17056 return hook.memoizedState;
17057}
17058
17059function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
17060 var hook = mountWorkInProgressHook();
17061 var nextDeps = deps === undefined ? null : deps;
17062 currentlyRenderingFiber$1.flags |= fiberFlags;
17063 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);
17064}
17065
17066function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
17067 var hook = updateWorkInProgressHook();
17068 var nextDeps = deps === undefined ? null : deps;
17069 var destroy = undefined;
17070
17071 if (currentHook !== null) {
17072 var prevEffect = currentHook.memoizedState;
17073 destroy = prevEffect.destroy;
17074
17075 if (nextDeps !== null) {
17076 var prevDeps = prevEffect.deps;
17077
17078 if (areHookInputsEqual(nextDeps, prevDeps)) {
17079 hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps);
17080 return;
17081 }
17082 }
17083 }
17084
17085 currentlyRenderingFiber$1.flags |= fiberFlags;
17086 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
17087}
17088
17089function mountEffect(create, deps) {
17090 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
17091 return mountEffectImpl(MountPassiveDev | Passive | PassiveStatic, Passive$1, create, deps);
17092 } else {
17093 return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps);
17094 }
17095}
17096
17097function updateEffect(create, deps) {
17098 return updateEffectImpl(Passive, Passive$1, create, deps);
17099}
17100
17101function mountInsertionEffect(create, deps) {
17102 return mountEffectImpl(Update, Insertion, create, deps);
17103}
17104
17105function updateInsertionEffect(create, deps) {
17106 return updateEffectImpl(Update, Insertion, create, deps);
17107}
17108
17109function mountLayoutEffect(create, deps) {
17110 var fiberFlags = Update;
17111
17112 {
17113 fiberFlags |= LayoutStatic;
17114 }
17115
17116 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
17117 fiberFlags |= MountLayoutDev;
17118 }
17119
17120 return mountEffectImpl(fiberFlags, Layout, create, deps);
17121}
17122
17123function updateLayoutEffect(create, deps) {
17124 return updateEffectImpl(Update, Layout, create, deps);
17125}
17126
17127function imperativeHandleEffect(create, ref) {
17128 if (typeof ref === 'function') {
17129 var refCallback = ref;
17130
17131 var _inst = create();
17132
17133 refCallback(_inst);
17134 return function () {
17135 refCallback(null);
17136 };
17137 } else if (ref !== null && ref !== undefined) {
17138 var refObject = ref;
17139
17140 {
17141 if (!refObject.hasOwnProperty('current')) {
17142 error('Expected useImperativeHandle() first argument to either be a ' + 'ref callback or React.createRef() object. Instead received: %s.', 'an object with keys {' + Object.keys(refObject).join(', ') + '}');
17143 }
17144 }
17145
17146 var _inst2 = create();
17147
17148 refObject.current = _inst2;
17149 return function () {
17150 refObject.current = null;
17151 };
17152 }
17153}
17154
17155function mountImperativeHandle(ref, create, deps) {
17156 {
17157 if (typeof create !== 'function') {
17158 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
17159 }
17160 } // TODO: If deps are provided, should we skip comparing the ref itself?
17161
17162
17163 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
17164 var fiberFlags = Update;
17165
17166 {
17167 fiberFlags |= LayoutStatic;
17168 }
17169
17170 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
17171 fiberFlags |= MountLayoutDev;
17172 }
17173
17174 return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
17175}
17176
17177function updateImperativeHandle(ref, create, deps) {
17178 {
17179 if (typeof create !== 'function') {
17180 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
17181 }
17182 } // TODO: If deps are provided, should we skip comparing the ref itself?
17183
17184
17185 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
17186 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
17187}
17188
17189function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
17190 // The react-debug-hooks package injects its own implementation
17191 // so that e.g. DevTools can display custom hook values.
17192}
17193
17194var updateDebugValue = mountDebugValue;
17195
17196function mountCallback(callback, deps) {
17197 var hook = mountWorkInProgressHook();
17198 var nextDeps = deps === undefined ? null : deps;
17199 hook.memoizedState = [callback, nextDeps];
17200 return callback;
17201}
17202
17203function updateCallback(callback, deps) {
17204 var hook = updateWorkInProgressHook();
17205 var nextDeps = deps === undefined ? null : deps;
17206 var prevState = hook.memoizedState;
17207
17208 if (prevState !== null) {
17209 if (nextDeps !== null) {
17210 var prevDeps = prevState[1];
17211
17212 if (areHookInputsEqual(nextDeps, prevDeps)) {
17213 return prevState[0];
17214 }
17215 }
17216 }
17217
17218 hook.memoizedState = [callback, nextDeps];
17219 return callback;
17220}
17221
17222function mountMemo(nextCreate, deps) {
17223 var hook = mountWorkInProgressHook();
17224 var nextDeps = deps === undefined ? null : deps;
17225 var nextValue = nextCreate();
17226 hook.memoizedState = [nextValue, nextDeps];
17227 return nextValue;
17228}
17229
17230function updateMemo(nextCreate, deps) {
17231 var hook = updateWorkInProgressHook();
17232 var nextDeps = deps === undefined ? null : deps;
17233 var prevState = hook.memoizedState;
17234
17235 if (prevState !== null) {
17236 // Assume these are defined. If they're not, areHookInputsEqual will warn.
17237 if (nextDeps !== null) {
17238 var prevDeps = prevState[1];
17239
17240 if (areHookInputsEqual(nextDeps, prevDeps)) {
17241 return prevState[0];
17242 }
17243 }
17244 }
17245
17246 var nextValue = nextCreate();
17247 hook.memoizedState = [nextValue, nextDeps];
17248 return nextValue;
17249}
17250
17251function mountDeferredValue(value) {
17252 var hook = mountWorkInProgressHook();
17253 hook.memoizedState = value;
17254 return value;
17255}
17256
17257function updateDeferredValue(value) {
17258 var hook = updateWorkInProgressHook();
17259 var resolvedCurrentHook = currentHook;
17260 var prevValue = resolvedCurrentHook.memoizedState;
17261 return updateDeferredValueImpl(hook, prevValue, value);
17262}
17263
17264function rerenderDeferredValue(value) {
17265 var hook = updateWorkInProgressHook();
17266
17267 if (currentHook === null) {
17268 // This is a rerender during a mount.
17269 hook.memoizedState = value;
17270 return value;
17271 } else {
17272 // This is a rerender during an update.
17273 var prevValue = currentHook.memoizedState;
17274 return updateDeferredValueImpl(hook, prevValue, value);
17275 }
17276}
17277
17278function updateDeferredValueImpl(hook, prevValue, value) {
17279 var shouldDeferValue = !includesOnlyNonUrgentLanes(renderLanes);
17280
17281 if (shouldDeferValue) {
17282 // This is an urgent update. If the value has changed, keep using the
17283 // previous value and spawn a deferred render to update it later.
17284 if (!objectIs(value, prevValue)) {
17285 // Schedule a deferred render
17286 var deferredLane = claimNextTransitionLane();
17287 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, deferredLane);
17288 markSkippedUpdateLanes(deferredLane); // Set this to true to indicate that the rendered value is inconsistent
17289 // from the latest value. The name "baseState" doesn't really match how we
17290 // use it because we're reusing a state hook field instead of creating a
17291 // new one.
17292
17293 hook.baseState = true;
17294 } // Reuse the previous value
17295
17296
17297 return prevValue;
17298 } else {
17299 // This is not an urgent update, so we can use the latest value regardless
17300 // of what it is. No need to defer it.
17301 // However, if we're currently inside a spawned render, then we need to mark
17302 // this as an update to prevent the fiber from bailing out.
17303 //
17304 // `baseState` is true when the current value is different from the rendered
17305 // value. The name doesn't really match how we use it because we're reusing
17306 // a state hook field instead of creating a new one.
17307 if (hook.baseState) {
17308 // Flip this back to false.
17309 hook.baseState = false;
17310 markWorkInProgressReceivedUpdate();
17311 }
17312
17313 hook.memoizedState = value;
17314 return value;
17315 }
17316}
17317
17318function startTransition(setPending, callback, options) {
17319 var previousPriority = getCurrentUpdatePriority();
17320 setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority));
17321 setPending(true);
17322 var prevTransition = ReactCurrentBatchConfig$2.transition;
17323 ReactCurrentBatchConfig$2.transition = {};
17324 var currentTransition = ReactCurrentBatchConfig$2.transition;
17325
17326 {
17327 ReactCurrentBatchConfig$2.transition._updatedFibers = new Set();
17328 }
17329
17330 try {
17331 setPending(false);
17332 callback();
17333 } finally {
17334 setCurrentUpdatePriority(previousPriority);
17335 ReactCurrentBatchConfig$2.transition = prevTransition;
17336
17337 {
17338 if (prevTransition === null && currentTransition._updatedFibers) {
17339 var updatedFibersCount = currentTransition._updatedFibers.size;
17340
17341 if (updatedFibersCount > 10) {
17342 warn('Detected a large number of updates inside startTransition. ' + 'If this is due to a subscription please re-write it to use React provided hooks. ' + 'Otherwise concurrent mode guarantees are off the table.');
17343 }
17344
17345 currentTransition._updatedFibers.clear();
17346 }
17347 }
17348 }
17349}
17350
17351function mountTransition() {
17352 var _mountState = mountState(false),
17353 isPending = _mountState[0],
17354 setPending = _mountState[1]; // The `start` method never changes.
17355
17356
17357 var start = startTransition.bind(null, setPending);
17358 var hook = mountWorkInProgressHook();
17359 hook.memoizedState = start;
17360 return [isPending, start];
17361}
17362
17363function updateTransition() {
17364 var _updateState = updateState(),
17365 isPending = _updateState[0];
17366
17367 var hook = updateWorkInProgressHook();
17368 var start = hook.memoizedState;
17369 return [isPending, start];
17370}
17371
17372function rerenderTransition() {
17373 var _rerenderState = rerenderState(),
17374 isPending = _rerenderState[0];
17375
17376 var hook = updateWorkInProgressHook();
17377 var start = hook.memoizedState;
17378 return [isPending, start];
17379}
17380
17381var isUpdatingOpaqueValueInRenderPhase = false;
17382function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
17383 {
17384 return isUpdatingOpaqueValueInRenderPhase;
17385 }
17386}
17387
17388function mountId() {
17389 var hook = mountWorkInProgressHook();
17390 var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we
17391 // should do this in Fiber, too? Deferring this decision for now because
17392 // there's no other place to store the prefix except for an internal field on
17393 // the public createRoot object, which the fiber tree does not currently have
17394 // a reference to.
17395
17396 var identifierPrefix = root.identifierPrefix;
17397 var id;
17398
17399 if (getIsHydrating()) {
17400 var treeId = getTreeId(); // Use a captial R prefix for server-generated ids.
17401
17402 id = ':' + identifierPrefix + 'R' + treeId; // Unless this is the first id at this level, append a number at the end
17403 // that represents the position of this useId hook among all the useId
17404 // hooks for this fiber.
17405
17406 var localId = localIdCounter++;
17407
17408 if (localId > 0) {
17409 id += 'H' + localId.toString(32);
17410 }
17411
17412 id += ':';
17413 } else {
17414 // Use a lowercase r prefix for client-generated ids.
17415 var globalClientId = globalClientIdCounter++;
17416 id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';
17417 }
17418
17419 hook.memoizedState = id;
17420 return id;
17421}
17422
17423function updateId() {
17424 var hook = updateWorkInProgressHook();
17425 var id = hook.memoizedState;
17426 return id;
17427}
17428
17429function dispatchReducerAction(fiber, queue, action) {
17430 {
17431 if (typeof arguments[3] === 'function') {
17432 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
17433 }
17434 }
17435
17436 var lane = requestUpdateLane(fiber);
17437 var update = {
17438 lane: lane,
17439 action: action,
17440 hasEagerState: false,
17441 eagerState: null,
17442 next: null
17443 };
17444
17445 if (isRenderPhaseUpdate(fiber)) {
17446 enqueueRenderPhaseUpdate(queue, update);
17447 } else {
17448 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
17449
17450 if (root !== null) {
17451 var eventTime = requestEventTime();
17452 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
17453 entangleTransitionUpdate(root, queue, lane);
17454 }
17455 }
17456
17457 markUpdateInDevTools(fiber, lane);
17458}
17459
17460function dispatchSetState(fiber, queue, action) {
17461 {
17462 if (typeof arguments[3] === 'function') {
17463 error("State updates from the useState() and useReducer() Hooks don't support the " + 'second callback argument. To execute a side effect after ' + 'rendering, declare it in the component body with useEffect().');
17464 }
17465 }
17466
17467 var lane = requestUpdateLane(fiber);
17468 var update = {
17469 lane: lane,
17470 action: action,
17471 hasEagerState: false,
17472 eagerState: null,
17473 next: null
17474 };
17475
17476 if (isRenderPhaseUpdate(fiber)) {
17477 enqueueRenderPhaseUpdate(queue, update);
17478 } else {
17479 var alternate = fiber.alternate;
17480
17481 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
17482 // The queue is currently empty, which means we can eagerly compute the
17483 // next state before entering the render phase. If the new state is the
17484 // same as the current state, we may be able to bail out entirely.
17485 var lastRenderedReducer = queue.lastRenderedReducer;
17486
17487 if (lastRenderedReducer !== null) {
17488 var prevDispatcher;
17489
17490 {
17491 prevDispatcher = ReactCurrentDispatcher$1.current;
17492 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17493 }
17494
17495 try {
17496 var currentState = queue.lastRenderedState;
17497 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
17498 // it, on the update object. If the reducer hasn't changed by the
17499 // time we enter the render phase, then the eager state can be used
17500 // without calling the reducer again.
17501
17502 update.hasEagerState = true;
17503 update.eagerState = eagerState;
17504
17505 if (objectIs(eagerState, currentState)) {
17506 // Fast path. We can bail out without scheduling React to re-render.
17507 // It's still possible that we'll need to rebase this update later,
17508 // if the component re-renders for a different reason and by that
17509 // time the reducer has changed.
17510 // TODO: Do we still need to entangle transitions in this case?
17511 enqueueConcurrentHookUpdateAndEagerlyBailout(fiber, queue, update, lane);
17512 return;
17513 }
17514 } catch (error) {// Suppress the error. It will throw again in the render phase.
17515 } finally {
17516 {
17517 ReactCurrentDispatcher$1.current = prevDispatcher;
17518 }
17519 }
17520 }
17521 }
17522
17523 var root = enqueueConcurrentHookUpdate(fiber, queue, update, lane);
17524
17525 if (root !== null) {
17526 var eventTime = requestEventTime();
17527 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
17528 entangleTransitionUpdate(root, queue, lane);
17529 }
17530 }
17531
17532 markUpdateInDevTools(fiber, lane);
17533}
17534
17535function isRenderPhaseUpdate(fiber) {
17536 var alternate = fiber.alternate;
17537 return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1;
17538}
17539
17540function enqueueRenderPhaseUpdate(queue, update) {
17541 // This is a render phase update. Stash it in a lazily-created map of
17542 // queue -> linked list of updates. After this render pass, we'll restart
17543 // and apply the stashed updates on top of the work-in-progress hook.
17544 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
17545 var pending = queue.pending;
17546
17547 if (pending === null) {
17548 // This is the first update. Create a circular list.
17549 update.next = update;
17550 } else {
17551 update.next = pending.next;
17552 pending.next = update;
17553 }
17554
17555 queue.pending = update;
17556} // TODO: Move to ReactFiberConcurrentUpdates?
17557
17558
17559function entangleTransitionUpdate(root, queue, lane) {
17560 if (isTransitionLane(lane)) {
17561 var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they
17562 // must have finished. We can remove them from the shared queue, which
17563 // represents a superset of the actually pending lanes. In some cases we
17564 // may entangle more than we need to, but that's OK. In fact it's worse if
17565 // we *don't* entangle when we should.
17566
17567 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
17568
17569 var newQueueLanes = mergeLanes(queueLanes, lane);
17570 queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
17571 // the lane finished since the last time we entangled it. So we need to
17572 // entangle it again, just to be sure.
17573
17574 markRootEntangled(root, newQueueLanes);
17575 }
17576}
17577
17578function markUpdateInDevTools(fiber, lane, action) {
17579
17580 {
17581 markStateUpdateScheduled(fiber, lane);
17582 }
17583}
17584
17585var ContextOnlyDispatcher = {
17586 readContext: readContext,
17587 useCallback: throwInvalidHookError,
17588 useContext: throwInvalidHookError,
17589 useEffect: throwInvalidHookError,
17590 useImperativeHandle: throwInvalidHookError,
17591 useInsertionEffect: throwInvalidHookError,
17592 useLayoutEffect: throwInvalidHookError,
17593 useMemo: throwInvalidHookError,
17594 useReducer: throwInvalidHookError,
17595 useRef: throwInvalidHookError,
17596 useState: throwInvalidHookError,
17597 useDebugValue: throwInvalidHookError,
17598 useDeferredValue: throwInvalidHookError,
17599 useTransition: throwInvalidHookError,
17600 useMutableSource: throwInvalidHookError,
17601 useSyncExternalStore: throwInvalidHookError,
17602 useId: throwInvalidHookError,
17603 unstable_isNewReconciler: enableNewReconciler
17604};
17605
17606var HooksDispatcherOnMountInDEV = null;
17607var HooksDispatcherOnMountWithHookTypesInDEV = null;
17608var HooksDispatcherOnUpdateInDEV = null;
17609var HooksDispatcherOnRerenderInDEV = null;
17610var InvalidNestedHooksDispatcherOnMountInDEV = null;
17611var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
17612var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
17613
17614{
17615 var warnInvalidContextAccess = function () {
17616 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().');
17617 };
17618
17619 var warnInvalidHookAccess = function () {
17620 error('Do not call Hooks inside useEffect(...), useMemo(...), or other built-in Hooks. ' + 'You can only call Hooks at the top level of your React function. ' + 'For more information, see ' + 'https://reactjs.org/link/rules-of-hooks');
17621 };
17622
17623 HooksDispatcherOnMountInDEV = {
17624 readContext: function (context) {
17625 return readContext(context);
17626 },
17627 useCallback: function (callback, deps) {
17628 currentHookNameInDev = 'useCallback';
17629 mountHookTypesDev();
17630 checkDepsAreArrayDev(deps);
17631 return mountCallback(callback, deps);
17632 },
17633 useContext: function (context) {
17634 currentHookNameInDev = 'useContext';
17635 mountHookTypesDev();
17636 return readContext(context);
17637 },
17638 useEffect: function (create, deps) {
17639 currentHookNameInDev = 'useEffect';
17640 mountHookTypesDev();
17641 checkDepsAreArrayDev(deps);
17642 return mountEffect(create, deps);
17643 },
17644 useImperativeHandle: function (ref, create, deps) {
17645 currentHookNameInDev = 'useImperativeHandle';
17646 mountHookTypesDev();
17647 checkDepsAreArrayDev(deps);
17648 return mountImperativeHandle(ref, create, deps);
17649 },
17650 useInsertionEffect: function (create, deps) {
17651 currentHookNameInDev = 'useInsertionEffect';
17652 mountHookTypesDev();
17653 checkDepsAreArrayDev(deps);
17654 return mountInsertionEffect(create, deps);
17655 },
17656 useLayoutEffect: function (create, deps) {
17657 currentHookNameInDev = 'useLayoutEffect';
17658 mountHookTypesDev();
17659 checkDepsAreArrayDev(deps);
17660 return mountLayoutEffect(create, deps);
17661 },
17662 useMemo: function (create, deps) {
17663 currentHookNameInDev = 'useMemo';
17664 mountHookTypesDev();
17665 checkDepsAreArrayDev(deps);
17666 var prevDispatcher = ReactCurrentDispatcher$1.current;
17667 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17668
17669 try {
17670 return mountMemo(create, deps);
17671 } finally {
17672 ReactCurrentDispatcher$1.current = prevDispatcher;
17673 }
17674 },
17675 useReducer: function (reducer, initialArg, init) {
17676 currentHookNameInDev = 'useReducer';
17677 mountHookTypesDev();
17678 var prevDispatcher = ReactCurrentDispatcher$1.current;
17679 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17680
17681 try {
17682 return mountReducer(reducer, initialArg, init);
17683 } finally {
17684 ReactCurrentDispatcher$1.current = prevDispatcher;
17685 }
17686 },
17687 useRef: function (initialValue) {
17688 currentHookNameInDev = 'useRef';
17689 mountHookTypesDev();
17690 return mountRef(initialValue);
17691 },
17692 useState: function (initialState) {
17693 currentHookNameInDev = 'useState';
17694 mountHookTypesDev();
17695 var prevDispatcher = ReactCurrentDispatcher$1.current;
17696 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17697
17698 try {
17699 return mountState(initialState);
17700 } finally {
17701 ReactCurrentDispatcher$1.current = prevDispatcher;
17702 }
17703 },
17704 useDebugValue: function (value, formatterFn) {
17705 currentHookNameInDev = 'useDebugValue';
17706 mountHookTypesDev();
17707 return mountDebugValue();
17708 },
17709 useDeferredValue: function (value) {
17710 currentHookNameInDev = 'useDeferredValue';
17711 mountHookTypesDev();
17712 return mountDeferredValue(value);
17713 },
17714 useTransition: function () {
17715 currentHookNameInDev = 'useTransition';
17716 mountHookTypesDev();
17717 return mountTransition();
17718 },
17719 useMutableSource: function (source, getSnapshot, subscribe) {
17720 currentHookNameInDev = 'useMutableSource';
17721 mountHookTypesDev();
17722 return mountMutableSource();
17723 },
17724 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17725 currentHookNameInDev = 'useSyncExternalStore';
17726 mountHookTypesDev();
17727 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
17728 },
17729 useId: function () {
17730 currentHookNameInDev = 'useId';
17731 mountHookTypesDev();
17732 return mountId();
17733 },
17734 unstable_isNewReconciler: enableNewReconciler
17735 };
17736
17737 HooksDispatcherOnMountWithHookTypesInDEV = {
17738 readContext: function (context) {
17739 return readContext(context);
17740 },
17741 useCallback: function (callback, deps) {
17742 currentHookNameInDev = 'useCallback';
17743 updateHookTypesDev();
17744 return mountCallback(callback, deps);
17745 },
17746 useContext: function (context) {
17747 currentHookNameInDev = 'useContext';
17748 updateHookTypesDev();
17749 return readContext(context);
17750 },
17751 useEffect: function (create, deps) {
17752 currentHookNameInDev = 'useEffect';
17753 updateHookTypesDev();
17754 return mountEffect(create, deps);
17755 },
17756 useImperativeHandle: function (ref, create, deps) {
17757 currentHookNameInDev = 'useImperativeHandle';
17758 updateHookTypesDev();
17759 return mountImperativeHandle(ref, create, deps);
17760 },
17761 useInsertionEffect: function (create, deps) {
17762 currentHookNameInDev = 'useInsertionEffect';
17763 updateHookTypesDev();
17764 return mountInsertionEffect(create, deps);
17765 },
17766 useLayoutEffect: function (create, deps) {
17767 currentHookNameInDev = 'useLayoutEffect';
17768 updateHookTypesDev();
17769 return mountLayoutEffect(create, deps);
17770 },
17771 useMemo: function (create, deps) {
17772 currentHookNameInDev = 'useMemo';
17773 updateHookTypesDev();
17774 var prevDispatcher = ReactCurrentDispatcher$1.current;
17775 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17776
17777 try {
17778 return mountMemo(create, deps);
17779 } finally {
17780 ReactCurrentDispatcher$1.current = prevDispatcher;
17781 }
17782 },
17783 useReducer: function (reducer, initialArg, init) {
17784 currentHookNameInDev = 'useReducer';
17785 updateHookTypesDev();
17786 var prevDispatcher = ReactCurrentDispatcher$1.current;
17787 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17788
17789 try {
17790 return mountReducer(reducer, initialArg, init);
17791 } finally {
17792 ReactCurrentDispatcher$1.current = prevDispatcher;
17793 }
17794 },
17795 useRef: function (initialValue) {
17796 currentHookNameInDev = 'useRef';
17797 updateHookTypesDev();
17798 return mountRef(initialValue);
17799 },
17800 useState: function (initialState) {
17801 currentHookNameInDev = 'useState';
17802 updateHookTypesDev();
17803 var prevDispatcher = ReactCurrentDispatcher$1.current;
17804 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17805
17806 try {
17807 return mountState(initialState);
17808 } finally {
17809 ReactCurrentDispatcher$1.current = prevDispatcher;
17810 }
17811 },
17812 useDebugValue: function (value, formatterFn) {
17813 currentHookNameInDev = 'useDebugValue';
17814 updateHookTypesDev();
17815 return mountDebugValue();
17816 },
17817 useDeferredValue: function (value) {
17818 currentHookNameInDev = 'useDeferredValue';
17819 updateHookTypesDev();
17820 return mountDeferredValue(value);
17821 },
17822 useTransition: function () {
17823 currentHookNameInDev = 'useTransition';
17824 updateHookTypesDev();
17825 return mountTransition();
17826 },
17827 useMutableSource: function (source, getSnapshot, subscribe) {
17828 currentHookNameInDev = 'useMutableSource';
17829 updateHookTypesDev();
17830 return mountMutableSource();
17831 },
17832 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17833 currentHookNameInDev = 'useSyncExternalStore';
17834 updateHookTypesDev();
17835 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
17836 },
17837 useId: function () {
17838 currentHookNameInDev = 'useId';
17839 updateHookTypesDev();
17840 return mountId();
17841 },
17842 unstable_isNewReconciler: enableNewReconciler
17843 };
17844
17845 HooksDispatcherOnUpdateInDEV = {
17846 readContext: function (context) {
17847 return readContext(context);
17848 },
17849 useCallback: function (callback, deps) {
17850 currentHookNameInDev = 'useCallback';
17851 updateHookTypesDev();
17852 return updateCallback(callback, deps);
17853 },
17854 useContext: function (context) {
17855 currentHookNameInDev = 'useContext';
17856 updateHookTypesDev();
17857 return readContext(context);
17858 },
17859 useEffect: function (create, deps) {
17860 currentHookNameInDev = 'useEffect';
17861 updateHookTypesDev();
17862 return updateEffect(create, deps);
17863 },
17864 useImperativeHandle: function (ref, create, deps) {
17865 currentHookNameInDev = 'useImperativeHandle';
17866 updateHookTypesDev();
17867 return updateImperativeHandle(ref, create, deps);
17868 },
17869 useInsertionEffect: function (create, deps) {
17870 currentHookNameInDev = 'useInsertionEffect';
17871 updateHookTypesDev();
17872 return updateInsertionEffect(create, deps);
17873 },
17874 useLayoutEffect: function (create, deps) {
17875 currentHookNameInDev = 'useLayoutEffect';
17876 updateHookTypesDev();
17877 return updateLayoutEffect(create, deps);
17878 },
17879 useMemo: function (create, deps) {
17880 currentHookNameInDev = 'useMemo';
17881 updateHookTypesDev();
17882 var prevDispatcher = ReactCurrentDispatcher$1.current;
17883 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17884
17885 try {
17886 return updateMemo(create, deps);
17887 } finally {
17888 ReactCurrentDispatcher$1.current = prevDispatcher;
17889 }
17890 },
17891 useReducer: function (reducer, initialArg, init) {
17892 currentHookNameInDev = 'useReducer';
17893 updateHookTypesDev();
17894 var prevDispatcher = ReactCurrentDispatcher$1.current;
17895 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17896
17897 try {
17898 return updateReducer(reducer, initialArg, init);
17899 } finally {
17900 ReactCurrentDispatcher$1.current = prevDispatcher;
17901 }
17902 },
17903 useRef: function (initialValue) {
17904 currentHookNameInDev = 'useRef';
17905 updateHookTypesDev();
17906 return updateRef();
17907 },
17908 useState: function (initialState) {
17909 currentHookNameInDev = 'useState';
17910 updateHookTypesDev();
17911 var prevDispatcher = ReactCurrentDispatcher$1.current;
17912 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17913
17914 try {
17915 return updateState(initialState);
17916 } finally {
17917 ReactCurrentDispatcher$1.current = prevDispatcher;
17918 }
17919 },
17920 useDebugValue: function (value, formatterFn) {
17921 currentHookNameInDev = 'useDebugValue';
17922 updateHookTypesDev();
17923 return updateDebugValue();
17924 },
17925 useDeferredValue: function (value) {
17926 currentHookNameInDev = 'useDeferredValue';
17927 updateHookTypesDev();
17928 return updateDeferredValue(value);
17929 },
17930 useTransition: function () {
17931 currentHookNameInDev = 'useTransition';
17932 updateHookTypesDev();
17933 return updateTransition();
17934 },
17935 useMutableSource: function (source, getSnapshot, subscribe) {
17936 currentHookNameInDev = 'useMutableSource';
17937 updateHookTypesDev();
17938 return updateMutableSource();
17939 },
17940 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17941 currentHookNameInDev = 'useSyncExternalStore';
17942 updateHookTypesDev();
17943 return updateSyncExternalStore(subscribe, getSnapshot);
17944 },
17945 useId: function () {
17946 currentHookNameInDev = 'useId';
17947 updateHookTypesDev();
17948 return updateId();
17949 },
17950 unstable_isNewReconciler: enableNewReconciler
17951 };
17952
17953 HooksDispatcherOnRerenderInDEV = {
17954 readContext: function (context) {
17955 return readContext(context);
17956 },
17957 useCallback: function (callback, deps) {
17958 currentHookNameInDev = 'useCallback';
17959 updateHookTypesDev();
17960 return updateCallback(callback, deps);
17961 },
17962 useContext: function (context) {
17963 currentHookNameInDev = 'useContext';
17964 updateHookTypesDev();
17965 return readContext(context);
17966 },
17967 useEffect: function (create, deps) {
17968 currentHookNameInDev = 'useEffect';
17969 updateHookTypesDev();
17970 return updateEffect(create, deps);
17971 },
17972 useImperativeHandle: function (ref, create, deps) {
17973 currentHookNameInDev = 'useImperativeHandle';
17974 updateHookTypesDev();
17975 return updateImperativeHandle(ref, create, deps);
17976 },
17977 useInsertionEffect: function (create, deps) {
17978 currentHookNameInDev = 'useInsertionEffect';
17979 updateHookTypesDev();
17980 return updateInsertionEffect(create, deps);
17981 },
17982 useLayoutEffect: function (create, deps) {
17983 currentHookNameInDev = 'useLayoutEffect';
17984 updateHookTypesDev();
17985 return updateLayoutEffect(create, deps);
17986 },
17987 useMemo: function (create, deps) {
17988 currentHookNameInDev = 'useMemo';
17989 updateHookTypesDev();
17990 var prevDispatcher = ReactCurrentDispatcher$1.current;
17991 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
17992
17993 try {
17994 return updateMemo(create, deps);
17995 } finally {
17996 ReactCurrentDispatcher$1.current = prevDispatcher;
17997 }
17998 },
17999 useReducer: function (reducer, initialArg, init) {
18000 currentHookNameInDev = 'useReducer';
18001 updateHookTypesDev();
18002 var prevDispatcher = ReactCurrentDispatcher$1.current;
18003 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
18004
18005 try {
18006 return rerenderReducer(reducer, initialArg, init);
18007 } finally {
18008 ReactCurrentDispatcher$1.current = prevDispatcher;
18009 }
18010 },
18011 useRef: function (initialValue) {
18012 currentHookNameInDev = 'useRef';
18013 updateHookTypesDev();
18014 return updateRef();
18015 },
18016 useState: function (initialState) {
18017 currentHookNameInDev = 'useState';
18018 updateHookTypesDev();
18019 var prevDispatcher = ReactCurrentDispatcher$1.current;
18020 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
18021
18022 try {
18023 return rerenderState(initialState);
18024 } finally {
18025 ReactCurrentDispatcher$1.current = prevDispatcher;
18026 }
18027 },
18028 useDebugValue: function (value, formatterFn) {
18029 currentHookNameInDev = 'useDebugValue';
18030 updateHookTypesDev();
18031 return updateDebugValue();
18032 },
18033 useDeferredValue: function (value) {
18034 currentHookNameInDev = 'useDeferredValue';
18035 updateHookTypesDev();
18036 return rerenderDeferredValue(value);
18037 },
18038 useTransition: function () {
18039 currentHookNameInDev = 'useTransition';
18040 updateHookTypesDev();
18041 return rerenderTransition();
18042 },
18043 useMutableSource: function (source, getSnapshot, subscribe) {
18044 currentHookNameInDev = 'useMutableSource';
18045 updateHookTypesDev();
18046 return updateMutableSource();
18047 },
18048 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
18049 currentHookNameInDev = 'useSyncExternalStore';
18050 updateHookTypesDev();
18051 return updateSyncExternalStore(subscribe, getSnapshot);
18052 },
18053 useId: function () {
18054 currentHookNameInDev = 'useId';
18055 updateHookTypesDev();
18056 return updateId();
18057 },
18058 unstable_isNewReconciler: enableNewReconciler
18059 };
18060
18061 InvalidNestedHooksDispatcherOnMountInDEV = {
18062 readContext: function (context) {
18063 warnInvalidContextAccess();
18064 return readContext(context);
18065 },
18066 useCallback: function (callback, deps) {
18067 currentHookNameInDev = 'useCallback';
18068 warnInvalidHookAccess();
18069 mountHookTypesDev();
18070 return mountCallback(callback, deps);
18071 },
18072 useContext: function (context) {
18073 currentHookNameInDev = 'useContext';
18074 warnInvalidHookAccess();
18075 mountHookTypesDev();
18076 return readContext(context);
18077 },
18078 useEffect: function (create, deps) {
18079 currentHookNameInDev = 'useEffect';
18080 warnInvalidHookAccess();
18081 mountHookTypesDev();
18082 return mountEffect(create, deps);
18083 },
18084 useImperativeHandle: function (ref, create, deps) {
18085 currentHookNameInDev = 'useImperativeHandle';
18086 warnInvalidHookAccess();
18087 mountHookTypesDev();
18088 return mountImperativeHandle(ref, create, deps);
18089 },
18090 useInsertionEffect: function (create, deps) {
18091 currentHookNameInDev = 'useInsertionEffect';
18092 warnInvalidHookAccess();
18093 mountHookTypesDev();
18094 return mountInsertionEffect(create, deps);
18095 },
18096 useLayoutEffect: function (create, deps) {
18097 currentHookNameInDev = 'useLayoutEffect';
18098 warnInvalidHookAccess();
18099 mountHookTypesDev();
18100 return mountLayoutEffect(create, deps);
18101 },
18102 useMemo: function (create, deps) {
18103 currentHookNameInDev = 'useMemo';
18104 warnInvalidHookAccess();
18105 mountHookTypesDev();
18106 var prevDispatcher = ReactCurrentDispatcher$1.current;
18107 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
18108
18109 try {
18110 return mountMemo(create, deps);
18111 } finally {
18112 ReactCurrentDispatcher$1.current = prevDispatcher;
18113 }
18114 },
18115 useReducer: function (reducer, initialArg, init) {
18116 currentHookNameInDev = 'useReducer';
18117 warnInvalidHookAccess();
18118 mountHookTypesDev();
18119 var prevDispatcher = ReactCurrentDispatcher$1.current;
18120 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
18121
18122 try {
18123 return mountReducer(reducer, initialArg, init);
18124 } finally {
18125 ReactCurrentDispatcher$1.current = prevDispatcher;
18126 }
18127 },
18128 useRef: function (initialValue) {
18129 currentHookNameInDev = 'useRef';
18130 warnInvalidHookAccess();
18131 mountHookTypesDev();
18132 return mountRef(initialValue);
18133 },
18134 useState: function (initialState) {
18135 currentHookNameInDev = 'useState';
18136 warnInvalidHookAccess();
18137 mountHookTypesDev();
18138 var prevDispatcher = ReactCurrentDispatcher$1.current;
18139 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
18140
18141 try {
18142 return mountState(initialState);
18143 } finally {
18144 ReactCurrentDispatcher$1.current = prevDispatcher;
18145 }
18146 },
18147 useDebugValue: function (value, formatterFn) {
18148 currentHookNameInDev = 'useDebugValue';
18149 warnInvalidHookAccess();
18150 mountHookTypesDev();
18151 return mountDebugValue();
18152 },
18153 useDeferredValue: function (value) {
18154 currentHookNameInDev = 'useDeferredValue';
18155 warnInvalidHookAccess();
18156 mountHookTypesDev();
18157 return mountDeferredValue(value);
18158 },
18159 useTransition: function () {
18160 currentHookNameInDev = 'useTransition';
18161 warnInvalidHookAccess();
18162 mountHookTypesDev();
18163 return mountTransition();
18164 },
18165 useMutableSource: function (source, getSnapshot, subscribe) {
18166 currentHookNameInDev = 'useMutableSource';
18167 warnInvalidHookAccess();
18168 mountHookTypesDev();
18169 return mountMutableSource();
18170 },
18171 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
18172 currentHookNameInDev = 'useSyncExternalStore';
18173 warnInvalidHookAccess();
18174 mountHookTypesDev();
18175 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
18176 },
18177 useId: function () {
18178 currentHookNameInDev = 'useId';
18179 warnInvalidHookAccess();
18180 mountHookTypesDev();
18181 return mountId();
18182 },
18183 unstable_isNewReconciler: enableNewReconciler
18184 };
18185
18186 InvalidNestedHooksDispatcherOnUpdateInDEV = {
18187 readContext: function (context) {
18188 warnInvalidContextAccess();
18189 return readContext(context);
18190 },
18191 useCallback: function (callback, deps) {
18192 currentHookNameInDev = 'useCallback';
18193 warnInvalidHookAccess();
18194 updateHookTypesDev();
18195 return updateCallback(callback, deps);
18196 },
18197 useContext: function (context) {
18198 currentHookNameInDev = 'useContext';
18199 warnInvalidHookAccess();
18200 updateHookTypesDev();
18201 return readContext(context);
18202 },
18203 useEffect: function (create, deps) {
18204 currentHookNameInDev = 'useEffect';
18205 warnInvalidHookAccess();
18206 updateHookTypesDev();
18207 return updateEffect(create, deps);
18208 },
18209 useImperativeHandle: function (ref, create, deps) {
18210 currentHookNameInDev = 'useImperativeHandle';
18211 warnInvalidHookAccess();
18212 updateHookTypesDev();
18213 return updateImperativeHandle(ref, create, deps);
18214 },
18215 useInsertionEffect: function (create, deps) {
18216 currentHookNameInDev = 'useInsertionEffect';
18217 warnInvalidHookAccess();
18218 updateHookTypesDev();
18219 return updateInsertionEffect(create, deps);
18220 },
18221 useLayoutEffect: function (create, deps) {
18222 currentHookNameInDev = 'useLayoutEffect';
18223 warnInvalidHookAccess();
18224 updateHookTypesDev();
18225 return updateLayoutEffect(create, deps);
18226 },
18227 useMemo: function (create, deps) {
18228 currentHookNameInDev = 'useMemo';
18229 warnInvalidHookAccess();
18230 updateHookTypesDev();
18231 var prevDispatcher = ReactCurrentDispatcher$1.current;
18232 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18233
18234 try {
18235 return updateMemo(create, deps);
18236 } finally {
18237 ReactCurrentDispatcher$1.current = prevDispatcher;
18238 }
18239 },
18240 useReducer: function (reducer, initialArg, init) {
18241 currentHookNameInDev = 'useReducer';
18242 warnInvalidHookAccess();
18243 updateHookTypesDev();
18244 var prevDispatcher = ReactCurrentDispatcher$1.current;
18245 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18246
18247 try {
18248 return updateReducer(reducer, initialArg, init);
18249 } finally {
18250 ReactCurrentDispatcher$1.current = prevDispatcher;
18251 }
18252 },
18253 useRef: function (initialValue) {
18254 currentHookNameInDev = 'useRef';
18255 warnInvalidHookAccess();
18256 updateHookTypesDev();
18257 return updateRef();
18258 },
18259 useState: function (initialState) {
18260 currentHookNameInDev = 'useState';
18261 warnInvalidHookAccess();
18262 updateHookTypesDev();
18263 var prevDispatcher = ReactCurrentDispatcher$1.current;
18264 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18265
18266 try {
18267 return updateState(initialState);
18268 } finally {
18269 ReactCurrentDispatcher$1.current = prevDispatcher;
18270 }
18271 },
18272 useDebugValue: function (value, formatterFn) {
18273 currentHookNameInDev = 'useDebugValue';
18274 warnInvalidHookAccess();
18275 updateHookTypesDev();
18276 return updateDebugValue();
18277 },
18278 useDeferredValue: function (value) {
18279 currentHookNameInDev = 'useDeferredValue';
18280 warnInvalidHookAccess();
18281 updateHookTypesDev();
18282 return updateDeferredValue(value);
18283 },
18284 useTransition: function () {
18285 currentHookNameInDev = 'useTransition';
18286 warnInvalidHookAccess();
18287 updateHookTypesDev();
18288 return updateTransition();
18289 },
18290 useMutableSource: function (source, getSnapshot, subscribe) {
18291 currentHookNameInDev = 'useMutableSource';
18292 warnInvalidHookAccess();
18293 updateHookTypesDev();
18294 return updateMutableSource();
18295 },
18296 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
18297 currentHookNameInDev = 'useSyncExternalStore';
18298 warnInvalidHookAccess();
18299 updateHookTypesDev();
18300 return updateSyncExternalStore(subscribe, getSnapshot);
18301 },
18302 useId: function () {
18303 currentHookNameInDev = 'useId';
18304 warnInvalidHookAccess();
18305 updateHookTypesDev();
18306 return updateId();
18307 },
18308 unstable_isNewReconciler: enableNewReconciler
18309 };
18310
18311 InvalidNestedHooksDispatcherOnRerenderInDEV = {
18312 readContext: function (context) {
18313 warnInvalidContextAccess();
18314 return readContext(context);
18315 },
18316 useCallback: function (callback, deps) {
18317 currentHookNameInDev = 'useCallback';
18318 warnInvalidHookAccess();
18319 updateHookTypesDev();
18320 return updateCallback(callback, deps);
18321 },
18322 useContext: function (context) {
18323 currentHookNameInDev = 'useContext';
18324 warnInvalidHookAccess();
18325 updateHookTypesDev();
18326 return readContext(context);
18327 },
18328 useEffect: function (create, deps) {
18329 currentHookNameInDev = 'useEffect';
18330 warnInvalidHookAccess();
18331 updateHookTypesDev();
18332 return updateEffect(create, deps);
18333 },
18334 useImperativeHandle: function (ref, create, deps) {
18335 currentHookNameInDev = 'useImperativeHandle';
18336 warnInvalidHookAccess();
18337 updateHookTypesDev();
18338 return updateImperativeHandle(ref, create, deps);
18339 },
18340 useInsertionEffect: function (create, deps) {
18341 currentHookNameInDev = 'useInsertionEffect';
18342 warnInvalidHookAccess();
18343 updateHookTypesDev();
18344 return updateInsertionEffect(create, deps);
18345 },
18346 useLayoutEffect: function (create, deps) {
18347 currentHookNameInDev = 'useLayoutEffect';
18348 warnInvalidHookAccess();
18349 updateHookTypesDev();
18350 return updateLayoutEffect(create, deps);
18351 },
18352 useMemo: function (create, deps) {
18353 currentHookNameInDev = 'useMemo';
18354 warnInvalidHookAccess();
18355 updateHookTypesDev();
18356 var prevDispatcher = ReactCurrentDispatcher$1.current;
18357 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18358
18359 try {
18360 return updateMemo(create, deps);
18361 } finally {
18362 ReactCurrentDispatcher$1.current = prevDispatcher;
18363 }
18364 },
18365 useReducer: function (reducer, initialArg, init) {
18366 currentHookNameInDev = 'useReducer';
18367 warnInvalidHookAccess();
18368 updateHookTypesDev();
18369 var prevDispatcher = ReactCurrentDispatcher$1.current;
18370 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18371
18372 try {
18373 return rerenderReducer(reducer, initialArg, init);
18374 } finally {
18375 ReactCurrentDispatcher$1.current = prevDispatcher;
18376 }
18377 },
18378 useRef: function (initialValue) {
18379 currentHookNameInDev = 'useRef';
18380 warnInvalidHookAccess();
18381 updateHookTypesDev();
18382 return updateRef();
18383 },
18384 useState: function (initialState) {
18385 currentHookNameInDev = 'useState';
18386 warnInvalidHookAccess();
18387 updateHookTypesDev();
18388 var prevDispatcher = ReactCurrentDispatcher$1.current;
18389 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18390
18391 try {
18392 return rerenderState(initialState);
18393 } finally {
18394 ReactCurrentDispatcher$1.current = prevDispatcher;
18395 }
18396 },
18397 useDebugValue: function (value, formatterFn) {
18398 currentHookNameInDev = 'useDebugValue';
18399 warnInvalidHookAccess();
18400 updateHookTypesDev();
18401 return updateDebugValue();
18402 },
18403 useDeferredValue: function (value) {
18404 currentHookNameInDev = 'useDeferredValue';
18405 warnInvalidHookAccess();
18406 updateHookTypesDev();
18407 return rerenderDeferredValue(value);
18408 },
18409 useTransition: function () {
18410 currentHookNameInDev = 'useTransition';
18411 warnInvalidHookAccess();
18412 updateHookTypesDev();
18413 return rerenderTransition();
18414 },
18415 useMutableSource: function (source, getSnapshot, subscribe) {
18416 currentHookNameInDev = 'useMutableSource';
18417 warnInvalidHookAccess();
18418 updateHookTypesDev();
18419 return updateMutableSource();
18420 },
18421 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
18422 currentHookNameInDev = 'useSyncExternalStore';
18423 warnInvalidHookAccess();
18424 updateHookTypesDev();
18425 return updateSyncExternalStore(subscribe, getSnapshot);
18426 },
18427 useId: function () {
18428 currentHookNameInDev = 'useId';
18429 warnInvalidHookAccess();
18430 updateHookTypesDev();
18431 return updateId();
18432 },
18433 unstable_isNewReconciler: enableNewReconciler
18434 };
18435}
18436
18437var now$1 = Scheduler.unstable_now;
18438var commitTime = 0;
18439var layoutEffectStartTime = -1;
18440var profilerStartTime = -1;
18441var passiveEffectStartTime = -1;
18442/**
18443 * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect).
18444 *
18445 * The overall sequence is:
18446 * 1. render
18447 * 2. commit (and call `onRender`, `onCommit`)
18448 * 3. check for nested updates
18449 * 4. flush passive effects (and call `onPostCommit`)
18450 *
18451 * Nested updates are identified in step 3 above,
18452 * but step 4 still applies to the work that was just committed.
18453 * We use two flags to track nested updates then:
18454 * one tracks whether the upcoming update is a nested update,
18455 * and the other tracks whether the current update was a nested update.
18456 * The first value gets synced to the second at the start of the render phase.
18457 */
18458
18459var currentUpdateIsNested = false;
18460var nestedUpdateScheduled = false;
18461
18462function isCurrentUpdateNested() {
18463 return currentUpdateIsNested;
18464}
18465
18466function markNestedUpdateScheduled() {
18467 {
18468 nestedUpdateScheduled = true;
18469 }
18470}
18471
18472function resetNestedUpdateFlag() {
18473 {
18474 currentUpdateIsNested = false;
18475 nestedUpdateScheduled = false;
18476 }
18477}
18478
18479function syncNestedUpdateFlag() {
18480 {
18481 currentUpdateIsNested = nestedUpdateScheduled;
18482 nestedUpdateScheduled = false;
18483 }
18484}
18485
18486function getCommitTime() {
18487 return commitTime;
18488}
18489
18490function recordCommitTime() {
18491
18492 commitTime = now$1();
18493}
18494
18495function startProfilerTimer(fiber) {
18496
18497 profilerStartTime = now$1();
18498
18499 if (fiber.actualStartTime < 0) {
18500 fiber.actualStartTime = now$1();
18501 }
18502}
18503
18504function stopProfilerTimerIfRunning(fiber) {
18505
18506 profilerStartTime = -1;
18507}
18508
18509function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
18510
18511 if (profilerStartTime >= 0) {
18512 var elapsedTime = now$1() - profilerStartTime;
18513 fiber.actualDuration += elapsedTime;
18514
18515 if (overrideBaseTime) {
18516 fiber.selfBaseDuration = elapsedTime;
18517 }
18518
18519 profilerStartTime = -1;
18520 }
18521}
18522
18523function recordLayoutEffectDuration(fiber) {
18524
18525 if (layoutEffectStartTime >= 0) {
18526 var elapsedTime = now$1() - layoutEffectStartTime;
18527 layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
18528 // Or the root (for the DevTools Profiler to read)
18529
18530 var parentFiber = fiber.return;
18531
18532 while (parentFiber !== null) {
18533 switch (parentFiber.tag) {
18534 case HostRoot:
18535 var root = parentFiber.stateNode;
18536 root.effectDuration += elapsedTime;
18537 return;
18538
18539 case Profiler:
18540 var parentStateNode = parentFiber.stateNode;
18541 parentStateNode.effectDuration += elapsedTime;
18542 return;
18543 }
18544
18545 parentFiber = parentFiber.return;
18546 }
18547 }
18548}
18549
18550function recordPassiveEffectDuration(fiber) {
18551
18552 if (passiveEffectStartTime >= 0) {
18553 var elapsedTime = now$1() - passiveEffectStartTime;
18554 passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
18555 // Or the root (for the DevTools Profiler to read)
18556
18557 var parentFiber = fiber.return;
18558
18559 while (parentFiber !== null) {
18560 switch (parentFiber.tag) {
18561 case HostRoot:
18562 var root = parentFiber.stateNode;
18563
18564 if (root !== null) {
18565 root.passiveEffectDuration += elapsedTime;
18566 }
18567
18568 return;
18569
18570 case Profiler:
18571 var parentStateNode = parentFiber.stateNode;
18572
18573 if (parentStateNode !== null) {
18574 // Detached fibers have their state node cleared out.
18575 // In this case, the return pointer is also cleared out,
18576 // so we won't be able to report the time spent in this Profiler's subtree.
18577 parentStateNode.passiveEffectDuration += elapsedTime;
18578 }
18579
18580 return;
18581 }
18582
18583 parentFiber = parentFiber.return;
18584 }
18585 }
18586}
18587
18588function startLayoutEffectTimer() {
18589
18590 layoutEffectStartTime = now$1();
18591}
18592
18593function startPassiveEffectTimer() {
18594
18595 passiveEffectStartTime = now$1();
18596}
18597
18598function transferActualDuration(fiber) {
18599 // Transfer time spent rendering these children so we don't lose it
18600 // after we rerender. This is used as a helper in special cases
18601 // where we should count the work of multiple passes.
18602 var child = fiber.child;
18603
18604 while (child) {
18605 fiber.actualDuration += child.actualDuration;
18606 child = child.sibling;
18607 }
18608}
18609
18610function createCapturedValueAtFiber(value, source) {
18611 // If the value is an error, call this function immediately after it is thrown
18612 // so the stack is accurate.
18613 return {
18614 value: value,
18615 source: source,
18616 stack: getStackByFiberInDevAndProd(source),
18617 digest: null
18618 };
18619}
18620function createCapturedValue(value, digest, stack) {
18621 return {
18622 value: value,
18623 source: null,
18624 stack: stack != null ? stack : null,
18625 digest: digest != null ? digest : null
18626 };
18627}
18628
18629// This module is forked in different environments.
18630// By default, return `true` to log errors to the console.
18631// Forks can return `false` if this isn't desirable.
18632function showErrorDialog(boundary, errorInfo) {
18633 return true;
18634}
18635
18636function logCapturedError(boundary, errorInfo) {
18637 try {
18638 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging.
18639 // This enables renderers like ReactNative to better manage redbox behavior.
18640
18641 if (logError === false) {
18642 return;
18643 }
18644
18645 var error = errorInfo.value;
18646
18647 if (true) {
18648 var source = errorInfo.source;
18649 var stack = errorInfo.stack;
18650 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling
18651 // `preventDefault()` in window `error` handler.
18652 // We record this information as an expando on the error.
18653
18654 if (error != null && error._suppressLogging) {
18655 if (boundary.tag === ClassComponent) {
18656 // The error is recoverable and was silenced.
18657 // Ignore it and don't print the stack addendum.
18658 // This is handy for testing error boundaries without noise.
18659 return;
18660 } // The error is fatal. Since the silencing might have
18661 // been accidental, we'll surface it anyway.
18662 // However, the browser would have silenced the original error
18663 // so we'll print it first, and then print the stack addendum.
18664
18665
18666 console['error'](error); // Don't transform to our wrapper
18667 // For a more detailed description of this block, see:
18668 // https://github.com/facebook/react/pull/13384
18669 }
18670
18671 var componentName = source ? getComponentNameFromFiber(source) : null;
18672 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
18673 var errorBoundaryMessage;
18674
18675 if (boundary.tag === HostRoot) {
18676 errorBoundaryMessage = 'Consider adding an error boundary to your tree to customize error handling behavior.\n' + 'Visit https://reactjs.org/link/error-boundaries to learn more about error boundaries.';
18677 } else {
18678 var errorBoundaryName = getComponentNameFromFiber(boundary) || 'Anonymous';
18679 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
18680 }
18681
18682 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
18683 // We don't include the original error message and JS stack because the browser
18684 // has already printed it. Even if the application swallows the error, it is still
18685 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
18686
18687 console['error'](combinedMessage); // Don't transform to our wrapper
18688 } else {
18689 // In production, we print the error directly.
18690 // This will include the message, the JS stack, and anything the browser wants to show.
18691 // We pass the error object instead of custom message so that the browser displays the error natively.
18692 console['error'](error); // Don't transform to our wrapper
18693 }
18694 } catch (e) {
18695 // This method must not throw, or React internal state will get messed up.
18696 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
18697 // we want to report this error outside of the normal stack as a last resort.
18698 // https://github.com/facebook/react/issues/13188
18699 setTimeout(function () {
18700 throw e;
18701 });
18702 }
18703}
18704
18705var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
18706
18707function createRootErrorUpdate(fiber, errorInfo, lane) {
18708 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null.
18709
18710 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
18711 // being called "element".
18712
18713 update.payload = {
18714 element: null
18715 };
18716 var error = errorInfo.value;
18717
18718 update.callback = function () {
18719 onUncaughtError(error);
18720 logCapturedError(fiber, errorInfo);
18721 };
18722
18723 return update;
18724}
18725
18726function createClassErrorUpdate(fiber, errorInfo, lane) {
18727 var update = createUpdate(NoTimestamp, lane);
18728 update.tag = CaptureUpdate;
18729 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
18730
18731 if (typeof getDerivedStateFromError === 'function') {
18732 var error$1 = errorInfo.value;
18733
18734 update.payload = function () {
18735 return getDerivedStateFromError(error$1);
18736 };
18737
18738 update.callback = function () {
18739 {
18740 markFailedErrorBoundaryForHotReloading(fiber);
18741 }
18742
18743 logCapturedError(fiber, errorInfo);
18744 };
18745 }
18746
18747 var inst = fiber.stateNode;
18748
18749 if (inst !== null && typeof inst.componentDidCatch === 'function') {
18750 update.callback = function callback() {
18751 {
18752 markFailedErrorBoundaryForHotReloading(fiber);
18753 }
18754
18755 logCapturedError(fiber, errorInfo);
18756
18757 if (typeof getDerivedStateFromError !== 'function') {
18758 // To preserve the preexisting retry behavior of error boundaries,
18759 // we keep track of which ones already failed during this batch.
18760 // This gets reset before we yield back to the browser.
18761 // TODO: Warn in strict mode if getDerivedStateFromError is
18762 // not defined.
18763 markLegacyErrorBoundaryAsFailed(this);
18764 }
18765
18766 var error$1 = errorInfo.value;
18767 var stack = errorInfo.stack;
18768 this.componentDidCatch(error$1, {
18769 componentStack: stack !== null ? stack : ''
18770 });
18771
18772 {
18773 if (typeof getDerivedStateFromError !== 'function') {
18774 // If componentDidCatch is the only error boundary method defined,
18775 // then it needs to call setState to recover from errors.
18776 // If no state update is scheduled then the boundary will swallow the error.
18777 if (!includesSomeLane(fiber.lanes, SyncLane)) {
18778 error('%s: Error boundaries should implement getDerivedStateFromError(). ' + 'In that method, return a state update to display an error message or fallback UI.', getComponentNameFromFiber(fiber) || 'Unknown');
18779 }
18780 }
18781 }
18782 };
18783 }
18784
18785 return update;
18786}
18787
18788function attachPingListener(root, wakeable, lanes) {
18789 // Attach a ping listener
18790 //
18791 // The data might resolve before we have a chance to commit the fallback. Or,
18792 // in the case of a refresh, we'll never commit a fallback. So we need to
18793 // attach a listener now. When it resolves ("pings"), we can decide whether to
18794 // try rendering the tree again.
18795 //
18796 // Only attach a listener if one does not already exist for the lanes
18797 // we're currently rendering (which acts like a "thread ID" here).
18798 //
18799 // We only need to do this in concurrent mode. Legacy Suspense always
18800 // commits fallbacks synchronously, so there are no pings.
18801 var pingCache = root.pingCache;
18802 var threadIDs;
18803
18804 if (pingCache === null) {
18805 pingCache = root.pingCache = new PossiblyWeakMap$1();
18806 threadIDs = new Set();
18807 pingCache.set(wakeable, threadIDs);
18808 } else {
18809 threadIDs = pingCache.get(wakeable);
18810
18811 if (threadIDs === undefined) {
18812 threadIDs = new Set();
18813 pingCache.set(wakeable, threadIDs);
18814 }
18815 }
18816
18817 if (!threadIDs.has(lanes)) {
18818 // Memoize using the thread ID to prevent redundant listeners.
18819 threadIDs.add(lanes);
18820 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
18821
18822 {
18823 if (isDevToolsPresent) {
18824 // If we have pending work still, restore the original updaters
18825 restorePendingUpdaters(root, lanes);
18826 }
18827 }
18828
18829 wakeable.then(ping, ping);
18830 }
18831}
18832
18833function attachRetryListener(suspenseBoundary, root, wakeable, lanes) {
18834 // Retry listener
18835 //
18836 // If the fallback does commit, we need to attach a different type of
18837 // listener. This one schedules an update on the Suspense boundary to turn
18838 // the fallback state off.
18839 //
18840 // Stash the wakeable on the boundary fiber so we can access it in the
18841 // commit phase.
18842 //
18843 // When the wakeable resolves, we'll attempt to render the boundary
18844 // again ("retry").
18845 var wakeables = suspenseBoundary.updateQueue;
18846
18847 if (wakeables === null) {
18848 var updateQueue = new Set();
18849 updateQueue.add(wakeable);
18850 suspenseBoundary.updateQueue = updateQueue;
18851 } else {
18852 wakeables.add(wakeable);
18853 }
18854}
18855
18856function resetSuspendedComponent(sourceFiber, rootRenderLanes) {
18857 // A legacy mode Suspense quirk, only relevant to hook components.
18858
18859
18860 var tag = sourceFiber.tag;
18861
18862 if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) {
18863 var currentSource = sourceFiber.alternate;
18864
18865 if (currentSource) {
18866 sourceFiber.updateQueue = currentSource.updateQueue;
18867 sourceFiber.memoizedState = currentSource.memoizedState;
18868 sourceFiber.lanes = currentSource.lanes;
18869 } else {
18870 sourceFiber.updateQueue = null;
18871 sourceFiber.memoizedState = null;
18872 }
18873 }
18874}
18875
18876function getNearestSuspenseBoundaryToCapture(returnFiber) {
18877 var node = returnFiber;
18878
18879 do {
18880 if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) {
18881 return node;
18882 } // This boundary already captured during this render. Continue to the next
18883 // boundary.
18884
18885
18886 node = node.return;
18887 } while (node !== null);
18888
18889 return null;
18890}
18891
18892function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) {
18893 // This marks a Suspense boundary so that when we're unwinding the stack,
18894 // it captures the suspended "exception" and does a second (fallback) pass.
18895 if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) {
18896 // Legacy Mode Suspense
18897 //
18898 // If the boundary is in legacy mode, we should *not*
18899 // suspend the commit. Pretend as if the suspended component rendered
18900 // null and keep rendering. When the Suspense boundary completes,
18901 // we'll do a second pass to render the fallback.
18902 if (suspenseBoundary === returnFiber) {
18903 // Special case where we suspended while reconciling the children of
18904 // a Suspense boundary's inner Offscreen wrapper fiber. This happens
18905 // when a React.lazy component is a direct child of a
18906 // Suspense boundary.
18907 //
18908 // Suspense boundaries are implemented as multiple fibers, but they
18909 // are a single conceptual unit. The legacy mode behavior where we
18910 // pretend the suspended fiber committed as `null` won't work,
18911 // because in this case the "suspended" fiber is the inner
18912 // Offscreen wrapper.
18913 //
18914 // Because the contents of the boundary haven't started rendering
18915 // yet (i.e. nothing in the tree has partially rendered) we can
18916 // switch to the regular, concurrent mode behavior: mark the
18917 // boundary with ShouldCapture and enter the unwind phase.
18918 suspenseBoundary.flags |= ShouldCapture;
18919 } else {
18920 suspenseBoundary.flags |= DidCapture;
18921 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete.
18922 // But we shouldn't call any lifecycle methods or callbacks. Remove
18923 // all lifecycle effect tags.
18924
18925 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
18926
18927 if (sourceFiber.tag === ClassComponent) {
18928 var currentSourceFiber = sourceFiber.alternate;
18929
18930 if (currentSourceFiber === null) {
18931 // This is a new mount. Change the tag so it's not mistaken for a
18932 // completed class component. For example, we should not call
18933 // componentWillUnmount if it is deleted.
18934 sourceFiber.tag = IncompleteClassComponent;
18935 } else {
18936 // When we try rendering again, we should not reuse the current fiber,
18937 // since it's known to be in an inconsistent state. Use a force update to
18938 // prevent a bail out.
18939 var update = createUpdate(NoTimestamp, SyncLane);
18940 update.tag = ForceUpdate;
18941 enqueueUpdate(sourceFiber, update, SyncLane);
18942 }
18943 } // The source fiber did not complete. Mark it with Sync priority to
18944 // indicate that it still has pending work.
18945
18946
18947 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);
18948 }
18949
18950 return suspenseBoundary;
18951 } // Confirmed that the boundary is in a concurrent mode tree. Continue
18952 // with the normal suspend path.
18953 //
18954 // After this we'll use a set of heuristics to determine whether this
18955 // render pass will run to completion or restart or "suspend" the commit.
18956 // The actual logic for this is spread out in different places.
18957 //
18958 // This first principle is that if we're going to suspend when we complete
18959 // a root, then we should also restart if we get an update or ping that
18960 // might unsuspend it, and vice versa. The only reason to suspend is
18961 // because you think you might want to restart before committing. However,
18962 // it doesn't make sense to restart only while in the period we're suspended.
18963 //
18964 // Restarting too aggressively is also not good because it starves out any
18965 // intermediate loading state. So we use heuristics to determine when.
18966 // Suspense Heuristics
18967 //
18968 // If nothing threw a Promise or all the same fallbacks are already showing,
18969 // then don't suspend/restart.
18970 //
18971 // If this is an initial render of a new tree of Suspense boundaries and
18972 // those trigger a fallback, then don't suspend/restart. We want to ensure
18973 // that we can show the initial loading state as quickly as possible.
18974 //
18975 // If we hit a "Delayed" case, such as when we'd switch from content back into
18976 // a fallback, then we should always suspend/restart. Transitions apply
18977 // to this case. If none is defined, JND is used instead.
18978 //
18979 // If we're already showing a fallback and it gets "retried", allowing us to show
18980 // another level, but there's still an inner boundary that would show a fallback,
18981 // then we suspend/restart for 500ms since the last time we showed a fallback
18982 // anywhere in the tree. This effectively throttles progressive loading into a
18983 // consistent train of commits. This also gives us an opportunity to restart to
18984 // get to the completed state slightly earlier.
18985 //
18986 // If there's ambiguity due to batching it's resolved in preference of:
18987 // 1) "delayed", 2) "initial render", 3) "retry".
18988 //
18989 // We want to ensure that a "busy" state doesn't get force committed. We want to
18990 // ensure that new initial loading states can commit as soon as possible.
18991
18992
18993 suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in
18994 // the begin phase to prevent an early bailout.
18995
18996 suspenseBoundary.lanes = rootRenderLanes;
18997 return suspenseBoundary;
18998}
18999
19000function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
19001 // The source fiber did not complete.
19002 sourceFiber.flags |= Incomplete;
19003
19004 {
19005 if (isDevToolsPresent) {
19006 // If we have pending work still, restore the original updaters
19007 restorePendingUpdaters(root, rootRenderLanes);
19008 }
19009 }
19010
19011 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
19012 // This is a wakeable. The component suspended.
19013 var wakeable = value;
19014 resetSuspendedComponent(sourceFiber);
19015
19016 {
19017 if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
19018 markDidThrowWhileHydratingDEV();
19019 }
19020 }
19021
19022
19023 var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber);
19024
19025 if (suspenseBoundary !== null) {
19026 suspenseBoundary.flags &= ~ForceClientRender;
19027 markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always
19028 // commits fallbacks synchronously, so there are no pings.
19029
19030 if (suspenseBoundary.mode & ConcurrentMode) {
19031 attachPingListener(root, wakeable, rootRenderLanes);
19032 }
19033
19034 attachRetryListener(suspenseBoundary, root, wakeable);
19035 return;
19036 } else {
19037 // No boundary was found. Unless this is a sync update, this is OK.
19038 // We can suspend and wait for more data to arrive.
19039 if (!includesSyncLane(rootRenderLanes)) {
19040 // This is not a sync update. Suspend. Since we're not activating a
19041 // Suspense boundary, this will unwind all the way to the root without
19042 // performing a second pass to render a fallback. (This is arguably how
19043 // refresh transitions should work, too, since we're not going to commit
19044 // the fallbacks anyway.)
19045 //
19046 // This case also applies to initial hydration.
19047 attachPingListener(root, wakeable, rootRenderLanes);
19048 renderDidSuspendDelayIfPossible();
19049 return;
19050 } // This is a sync/discrete update. We treat this case like an error
19051 // because discrete renders are expected to produce a complete tree
19052 // synchronously to maintain consistency with external state.
19053
19054
19055 var uncaughtSuspenseError = new Error('A component suspended while responding to synchronous input. This ' + 'will cause the UI to be replaced with a loading indicator. To ' + 'fix, updates that suspend should be wrapped ' + 'with startTransition.'); // If we're outside a transition, fall through to the regular error path.
19056 // The error will be caught by the nearest suspense boundary.
19057
19058 value = uncaughtSuspenseError;
19059 }
19060 } else {
19061 // This is a regular error, not a Suspense wakeable.
19062 if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
19063 markDidThrowWhileHydratingDEV();
19064
19065 var _suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); // If the error was thrown during hydration, we may be able to recover by
19066 // discarding the dehydrated content and switching to a client render.
19067 // Instead of surfacing the error, find the nearest Suspense boundary
19068 // and render it again without hydration.
19069
19070
19071 if (_suspenseBoundary !== null) {
19072 if ((_suspenseBoundary.flags & ShouldCapture) === NoFlags) {
19073 // Set a flag to indicate that we should try rendering the normal
19074 // children again, not the fallback.
19075 _suspenseBoundary.flags |= ForceClientRender;
19076 }
19077
19078 markSuspenseBoundaryShouldCapture(_suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // Even though the user may not be affected by this error, we should
19079 // still log it so it can be fixed.
19080
19081 queueHydrationError(createCapturedValueAtFiber(value, sourceFiber));
19082 return;
19083 }
19084 }
19085 }
19086
19087 value = createCapturedValueAtFiber(value, sourceFiber);
19088 renderDidError(value); // We didn't find a boundary that could handle this type of exception. Start
19089 // over and traverse parent path again, this time treating the exception
19090 // as an error.
19091
19092 var workInProgress = returnFiber;
19093
19094 do {
19095 switch (workInProgress.tag) {
19096 case HostRoot:
19097 {
19098 var _errorInfo = value;
19099 workInProgress.flags |= ShouldCapture;
19100 var lane = pickArbitraryLane(rootRenderLanes);
19101 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
19102 var update = createRootErrorUpdate(workInProgress, _errorInfo, lane);
19103 enqueueCapturedUpdate(workInProgress, update);
19104 return;
19105 }
19106
19107 case ClassComponent:
19108 // Capture and retry
19109 var errorInfo = value;
19110 var ctor = workInProgress.type;
19111 var instance = workInProgress.stateNode;
19112
19113 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
19114 workInProgress.flags |= ShouldCapture;
19115
19116 var _lane = pickArbitraryLane(rootRenderLanes);
19117
19118 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
19119
19120 var _update = createClassErrorUpdate(workInProgress, errorInfo, _lane);
19121
19122 enqueueCapturedUpdate(workInProgress, _update);
19123 return;
19124 }
19125
19126 break;
19127 }
19128
19129 workInProgress = workInProgress.return;
19130 } while (workInProgress !== null);
19131}
19132
19133function getSuspendedCache() {
19134 {
19135 return null;
19136 } // This function is called when a Suspense boundary suspends. It returns the
19137}
19138
19139var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
19140var didReceiveUpdate = false;
19141var didWarnAboutBadClass;
19142var didWarnAboutModulePatternComponent;
19143var didWarnAboutContextTypeOnFunctionComponent;
19144var didWarnAboutGetDerivedStateOnFunctionComponent;
19145var didWarnAboutFunctionRefs;
19146var didWarnAboutReassigningProps;
19147var didWarnAboutRevealOrder;
19148var didWarnAboutTailOptions;
19149
19150{
19151 didWarnAboutBadClass = {};
19152 didWarnAboutModulePatternComponent = {};
19153 didWarnAboutContextTypeOnFunctionComponent = {};
19154 didWarnAboutGetDerivedStateOnFunctionComponent = {};
19155 didWarnAboutFunctionRefs = {};
19156 didWarnAboutReassigningProps = false;
19157 didWarnAboutRevealOrder = {};
19158 didWarnAboutTailOptions = {};
19159}
19160
19161function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
19162 if (current === null) {
19163 // If this is a fresh new component that hasn't been rendered yet, we
19164 // won't update its child set by applying minimal side-effects. Instead,
19165 // we will add them all to the child before it gets rendered. That means
19166 // we can optimize this reconciliation pass by not tracking side-effects.
19167 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
19168 } else {
19169 // If the current child is the same as the work in progress, it means that
19170 // we haven't yet started any work on these children. Therefore, we use
19171 // the clone algorithm to create a copy of all the current children.
19172 // If we had any progressed work already, that is invalid at this point so
19173 // let's throw it out.
19174 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
19175 }
19176}
19177
19178function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
19179 // This function is fork of reconcileChildren. It's used in cases where we
19180 // want to reconcile without matching against the existing set. This has the
19181 // effect of all current children being unmounted; even if the type and key
19182 // are the same, the old child is unmounted and a new child is created.
19183 //
19184 // To do this, we're going to go through the reconcile algorithm twice. In
19185 // the first pass, we schedule a deletion for all the current children by
19186 // passing null.
19187 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
19188 // pass null in place of where we usually pass the current child set. This has
19189 // the effect of remounting all children regardless of whether their
19190 // identities match.
19191
19192 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
19193}
19194
19195function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
19196 // TODO: current can be non-null here even if the component
19197 // hasn't yet mounted. This happens after the first render suspends.
19198 // We'll need to figure out if this is fine or can cause issues.
19199 {
19200 if (workInProgress.type !== workInProgress.elementType) {
19201 // Lazy component props can't be validated in createElement
19202 // because they're only guaranteed to be resolved here.
19203 var innerPropTypes = Component.propTypes;
19204
19205 if (innerPropTypes) {
19206 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19207 'prop', getComponentNameFromType(Component));
19208 }
19209 }
19210 }
19211
19212 var render = Component.render;
19213 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
19214
19215 var nextChildren;
19216 var hasId;
19217 prepareToReadContext(workInProgress, renderLanes);
19218
19219 {
19220 markComponentRenderStarted(workInProgress);
19221 }
19222
19223 {
19224 ReactCurrentOwner$1.current = workInProgress;
19225 setIsRendering(true);
19226 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
19227 hasId = checkDidRenderIdHook();
19228
19229 if ( workInProgress.mode & StrictLegacyMode) {
19230 setIsStrictModeForDevtools(true);
19231
19232 try {
19233 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
19234 hasId = checkDidRenderIdHook();
19235 } finally {
19236 setIsStrictModeForDevtools(false);
19237 }
19238 }
19239
19240 setIsRendering(false);
19241 }
19242
19243 {
19244 markComponentRenderStopped();
19245 }
19246
19247 if (current !== null && !didReceiveUpdate) {
19248 bailoutHooks(current, workInProgress, renderLanes);
19249 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19250 }
19251
19252 if (getIsHydrating() && hasId) {
19253 pushMaterializedTreeId(workInProgress);
19254 } // React DevTools reads this flag.
19255
19256
19257 workInProgress.flags |= PerformedWork;
19258 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19259 return workInProgress.child;
19260}
19261
19262function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
19263 if (current === null) {
19264 var type = Component.type;
19265
19266 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
19267 Component.defaultProps === undefined) {
19268 var resolvedType = type;
19269
19270 {
19271 resolvedType = resolveFunctionForHotReloading(type);
19272 } // If this is a plain function component without default props,
19273 // and with only the default shallow comparison, we upgrade it
19274 // to a SimpleMemoComponent to allow fast path updates.
19275
19276
19277 workInProgress.tag = SimpleMemoComponent;
19278 workInProgress.type = resolvedType;
19279
19280 {
19281 validateFunctionComponentInDev(workInProgress, type);
19282 }
19283
19284 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes);
19285 }
19286
19287 {
19288 var innerPropTypes = type.propTypes;
19289
19290 if (innerPropTypes) {
19291 // Inner memo component props aren't currently validated in createElement.
19292 // We could move it there, but we'd still need this for lazy code path.
19293 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19294 'prop', getComponentNameFromType(type));
19295 }
19296 }
19297
19298 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
19299 child.ref = workInProgress.ref;
19300 child.return = workInProgress;
19301 workInProgress.child = child;
19302 return child;
19303 }
19304
19305 {
19306 var _type = Component.type;
19307 var _innerPropTypes = _type.propTypes;
19308
19309 if (_innerPropTypes) {
19310 // Inner memo component props aren't currently validated in createElement.
19311 // We could move it there, but we'd still need this for lazy code path.
19312 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
19313 'prop', getComponentNameFromType(_type));
19314 }
19315 }
19316
19317 var currentChild = current.child; // This is always exactly one child
19318
19319 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
19320
19321 if (!hasScheduledUpdateOrContext) {
19322 // This will be the props with resolved defaultProps,
19323 // unlike current.memoizedProps which will be the unresolved ones.
19324 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
19325
19326 var compare = Component.compare;
19327 compare = compare !== null ? compare : shallowEqual;
19328
19329 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
19330 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19331 }
19332 } // React DevTools reads this flag.
19333
19334
19335 workInProgress.flags |= PerformedWork;
19336 var newChild = createWorkInProgress(currentChild, nextProps);
19337 newChild.ref = workInProgress.ref;
19338 newChild.return = workInProgress;
19339 workInProgress.child = newChild;
19340 return newChild;
19341}
19342
19343function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
19344 // TODO: current can be non-null here even if the component
19345 // hasn't yet mounted. This happens when the inner render suspends.
19346 // We'll need to figure out if this is fine or can cause issues.
19347 {
19348 if (workInProgress.type !== workInProgress.elementType) {
19349 // Lazy component props can't be validated in createElement
19350 // because they're only guaranteed to be resolved here.
19351 var outerMemoType = workInProgress.elementType;
19352
19353 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
19354 // We warn when you define propTypes on lazy()
19355 // so let's just skip over it to find memo() outer wrapper.
19356 // Inner props for memo are validated later.
19357 var lazyComponent = outerMemoType;
19358 var payload = lazyComponent._payload;
19359 var init = lazyComponent._init;
19360
19361 try {
19362 outerMemoType = init(payload);
19363 } catch (x) {
19364 outerMemoType = null;
19365 } // Inner propTypes will be validated in the function component path.
19366
19367
19368 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
19369
19370 if (outerPropTypes) {
19371 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
19372 'prop', getComponentNameFromType(outerMemoType));
19373 }
19374 }
19375 }
19376 }
19377
19378 if (current !== null) {
19379 var prevProps = current.memoizedProps;
19380
19381 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
19382 workInProgress.type === current.type )) {
19383 didReceiveUpdate = false; // The props are shallowly equal. Reuse the previous props object, like we
19384 // would during a normal fiber bailout.
19385 //
19386 // We don't have strong guarantees that the props object is referentially
19387 // equal during updates where we can't bail out anyway — like if the props
19388 // are shallowly equal, but there's a local state or context update in the
19389 // same batch.
19390 //
19391 // However, as a principle, we should aim to make the behavior consistent
19392 // across different ways of memoizing a component. For example, React.memo
19393 // has a different internal Fiber layout if you pass a normal function
19394 // component (SimpleMemoComponent) versus if you pass a different type
19395 // like forwardRef (MemoComponent). But this is an implementation detail.
19396 // Wrapping a component in forwardRef (or React.lazy, etc) shouldn't
19397 // affect whether the props object is reused during a bailout.
19398
19399 workInProgress.pendingProps = nextProps = prevProps;
19400
19401 if (!checkScheduledUpdateOrContext(current, renderLanes)) {
19402 // The pending lanes were cleared at the beginning of beginWork. We're
19403 // about to bail out, but there might be other lanes that weren't
19404 // included in the current render. Usually, the priority level of the
19405 // remaining updates is accumulated during the evaluation of the
19406 // component (i.e. when processing the update queue). But since since
19407 // we're bailing out early *without* evaluating the component, we need
19408 // to account for it here, too. Reset to the value of the current fiber.
19409 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
19410 // because a MemoComponent fiber does not have hooks or an update queue;
19411 // rather, it wraps around an inner component, which may or may not
19412 // contains hooks.
19413 // TODO: Move the reset at in beginWork out of the common path so that
19414 // this is no longer necessary.
19415 workInProgress.lanes = current.lanes;
19416 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19417 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
19418 // This is a special case that only exists for legacy mode.
19419 // See https://github.com/facebook/react/pull/19216.
19420 didReceiveUpdate = true;
19421 }
19422 }
19423 }
19424
19425 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
19426}
19427
19428function updateOffscreenComponent(current, workInProgress, renderLanes) {
19429 var nextProps = workInProgress.pendingProps;
19430 var nextChildren = nextProps.children;
19431 var prevState = current !== null ? current.memoizedState : null;
19432
19433 if (nextProps.mode === 'hidden' || enableLegacyHidden ) {
19434 // Rendering a hidden tree.
19435 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
19436 // In legacy sync mode, don't defer the subtree. Render it now.
19437 // TODO: Consider how Offscreen should work with transitions in the future
19438 var nextState = {
19439 baseLanes: NoLanes,
19440 cachePool: null,
19441 transitions: null
19442 };
19443 workInProgress.memoizedState = nextState;
19444
19445 pushRenderLanes(workInProgress, renderLanes);
19446 } else if (!includesSomeLane(renderLanes, OffscreenLane)) {
19447 var spawnedCachePool = null; // We're hidden, and we're not rendering at Offscreen. We will bail out
19448 // and resume this tree later.
19449
19450 var nextBaseLanes;
19451
19452 if (prevState !== null) {
19453 var prevBaseLanes = prevState.baseLanes;
19454 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes);
19455 } else {
19456 nextBaseLanes = renderLanes;
19457 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
19458
19459
19460 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane);
19461 var _nextState = {
19462 baseLanes: nextBaseLanes,
19463 cachePool: spawnedCachePool,
19464 transitions: null
19465 };
19466 workInProgress.memoizedState = _nextState;
19467 workInProgress.updateQueue = null;
19468 // to avoid a push/pop misalignment.
19469
19470
19471 pushRenderLanes(workInProgress, nextBaseLanes);
19472
19473 return null;
19474 } else {
19475 // This is the second render. The surrounding visible content has already
19476 // committed. Now we resume rendering the hidden tree.
19477 // Rendering at offscreen, so we can clear the base lanes.
19478 var _nextState2 = {
19479 baseLanes: NoLanes,
19480 cachePool: null,
19481 transitions: null
19482 };
19483 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out.
19484
19485 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes;
19486
19487 pushRenderLanes(workInProgress, subtreeRenderLanes);
19488 }
19489 } else {
19490 // Rendering a visible tree.
19491 var _subtreeRenderLanes;
19492
19493 if (prevState !== null) {
19494 // We're going from hidden -> visible.
19495 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes);
19496
19497 workInProgress.memoizedState = null;
19498 } else {
19499 // We weren't previously hidden, and we still aren't, so there's nothing
19500 // special to do. Need to push to the stack regardless, though, to avoid
19501 // a push/pop misalignment.
19502 _subtreeRenderLanes = renderLanes;
19503 }
19504
19505 pushRenderLanes(workInProgress, _subtreeRenderLanes);
19506 }
19507
19508 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19509 return workInProgress.child;
19510} // Note: These happen to have identical begin phases, for now. We shouldn't hold
19511
19512function updateFragment(current, workInProgress, renderLanes) {
19513 var nextChildren = workInProgress.pendingProps;
19514 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19515 return workInProgress.child;
19516}
19517
19518function updateMode(current, workInProgress, renderLanes) {
19519 var nextChildren = workInProgress.pendingProps.children;
19520 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19521 return workInProgress.child;
19522}
19523
19524function updateProfiler(current, workInProgress, renderLanes) {
19525 {
19526 workInProgress.flags |= Update;
19527
19528 {
19529 // Reset effect durations for the next eventual effect phase.
19530 // These are reset during render to allow the DevTools commit hook a chance to read them,
19531 var stateNode = workInProgress.stateNode;
19532 stateNode.effectDuration = 0;
19533 stateNode.passiveEffectDuration = 0;
19534 }
19535 }
19536
19537 var nextProps = workInProgress.pendingProps;
19538 var nextChildren = nextProps.children;
19539 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19540 return workInProgress.child;
19541}
19542
19543function markRef(current, workInProgress) {
19544 var ref = workInProgress.ref;
19545
19546 if (current === null && ref !== null || current !== null && current.ref !== ref) {
19547 // Schedule a Ref effect
19548 workInProgress.flags |= Ref;
19549
19550 {
19551 workInProgress.flags |= RefStatic;
19552 }
19553 }
19554}
19555
19556function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
19557 {
19558 if (workInProgress.type !== workInProgress.elementType) {
19559 // Lazy component props can't be validated in createElement
19560 // because they're only guaranteed to be resolved here.
19561 var innerPropTypes = Component.propTypes;
19562
19563 if (innerPropTypes) {
19564 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19565 'prop', getComponentNameFromType(Component));
19566 }
19567 }
19568 }
19569
19570 var context;
19571
19572 {
19573 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
19574 context = getMaskedContext(workInProgress, unmaskedContext);
19575 }
19576
19577 var nextChildren;
19578 var hasId;
19579 prepareToReadContext(workInProgress, renderLanes);
19580
19581 {
19582 markComponentRenderStarted(workInProgress);
19583 }
19584
19585 {
19586 ReactCurrentOwner$1.current = workInProgress;
19587 setIsRendering(true);
19588 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
19589 hasId = checkDidRenderIdHook();
19590
19591 if ( workInProgress.mode & StrictLegacyMode) {
19592 setIsStrictModeForDevtools(true);
19593
19594 try {
19595 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
19596 hasId = checkDidRenderIdHook();
19597 } finally {
19598 setIsStrictModeForDevtools(false);
19599 }
19600 }
19601
19602 setIsRendering(false);
19603 }
19604
19605 {
19606 markComponentRenderStopped();
19607 }
19608
19609 if (current !== null && !didReceiveUpdate) {
19610 bailoutHooks(current, workInProgress, renderLanes);
19611 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19612 }
19613
19614 if (getIsHydrating() && hasId) {
19615 pushMaterializedTreeId(workInProgress);
19616 } // React DevTools reads this flag.
19617
19618
19619 workInProgress.flags |= PerformedWork;
19620 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19621 return workInProgress.child;
19622}
19623
19624function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
19625 {
19626 // This is used by DevTools to force a boundary to error.
19627 switch (shouldError(workInProgress)) {
19628 case false:
19629 {
19630 var _instance = workInProgress.stateNode;
19631 var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack.
19632 // Is there a better way to do this?
19633
19634 var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context);
19635 var state = tempInstance.state;
19636
19637 _instance.updater.enqueueSetState(_instance, state, null);
19638
19639 break;
19640 }
19641
19642 case true:
19643 {
19644 workInProgress.flags |= DidCapture;
19645 workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes
19646
19647 var error$1 = new Error('Simulated error coming from DevTools');
19648 var lane = pickArbitraryLane(renderLanes);
19649 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state
19650
19651 var update = createClassErrorUpdate(workInProgress, createCapturedValueAtFiber(error$1, workInProgress), lane);
19652 enqueueCapturedUpdate(workInProgress, update);
19653 break;
19654 }
19655 }
19656
19657 if (workInProgress.type !== workInProgress.elementType) {
19658 // Lazy component props can't be validated in createElement
19659 // because they're only guaranteed to be resolved here.
19660 var innerPropTypes = Component.propTypes;
19661
19662 if (innerPropTypes) {
19663 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19664 'prop', getComponentNameFromType(Component));
19665 }
19666 }
19667 } // Push context providers early to prevent context stack mismatches.
19668 // During mounting we don't know the child context yet as the instance doesn't exist.
19669 // We will invalidate the child context in finishClassComponent() right after rendering.
19670
19671
19672 var hasContext;
19673
19674 if (isContextProvider(Component)) {
19675 hasContext = true;
19676 pushContextProvider(workInProgress);
19677 } else {
19678 hasContext = false;
19679 }
19680
19681 prepareToReadContext(workInProgress, renderLanes);
19682 var instance = workInProgress.stateNode;
19683 var shouldUpdate;
19684
19685 if (instance === null) {
19686 resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress); // In the initial pass we might need to construct the instance.
19687
19688 constructClassInstance(workInProgress, Component, nextProps);
19689 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
19690 shouldUpdate = true;
19691 } else if (current === null) {
19692 // In a resume, we'll already have an instance we can reuse.
19693 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
19694 } else {
19695 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
19696 }
19697
19698 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
19699
19700 {
19701 var inst = workInProgress.stateNode;
19702
19703 if (shouldUpdate && inst.props !== nextProps) {
19704 if (!didWarnAboutReassigningProps) {
19705 error('It looks like %s is reassigning its own `this.props` while rendering. ' + 'This is not supported and can lead to confusing bugs.', getComponentNameFromFiber(workInProgress) || 'a component');
19706 }
19707
19708 didWarnAboutReassigningProps = true;
19709 }
19710 }
19711
19712 return nextUnitOfWork;
19713}
19714
19715function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
19716 // Refs should update even if shouldComponentUpdate returns false
19717 markRef(current, workInProgress);
19718 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags;
19719
19720 if (!shouldUpdate && !didCaptureError) {
19721 // Context providers should defer to sCU for rendering
19722 if (hasContext) {
19723 invalidateContextProvider(workInProgress, Component, false);
19724 }
19725
19726 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19727 }
19728
19729 var instance = workInProgress.stateNode; // Rerender
19730
19731 ReactCurrentOwner$1.current = workInProgress;
19732 var nextChildren;
19733
19734 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
19735 // If we captured an error, but getDerivedStateFromError is not defined,
19736 // unmount all the children. componentDidCatch will schedule an update to
19737 // re-render a fallback. This is temporary until we migrate everyone to
19738 // the new API.
19739 // TODO: Warn in a future release.
19740 nextChildren = null;
19741
19742 {
19743 stopProfilerTimerIfRunning();
19744 }
19745 } else {
19746 {
19747 markComponentRenderStarted(workInProgress);
19748 }
19749
19750 {
19751 setIsRendering(true);
19752 nextChildren = instance.render();
19753
19754 if ( workInProgress.mode & StrictLegacyMode) {
19755 setIsStrictModeForDevtools(true);
19756
19757 try {
19758 instance.render();
19759 } finally {
19760 setIsStrictModeForDevtools(false);
19761 }
19762 }
19763
19764 setIsRendering(false);
19765 }
19766
19767 {
19768 markComponentRenderStopped();
19769 }
19770 } // React DevTools reads this flag.
19771
19772
19773 workInProgress.flags |= PerformedWork;
19774
19775 if (current !== null && didCaptureError) {
19776 // If we're recovering from an error, reconcile without reusing any of
19777 // the existing children. Conceptually, the normal children and the children
19778 // that are shown on error are two different sets, so we shouldn't reuse
19779 // normal children even if their identities match.
19780 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
19781 } else {
19782 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19783 } // Memoize state using the values we just used to render.
19784 // TODO: Restructure so we never read values from the instance.
19785
19786
19787 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
19788
19789 if (hasContext) {
19790 invalidateContextProvider(workInProgress, Component, true);
19791 }
19792
19793 return workInProgress.child;
19794}
19795
19796function pushHostRootContext(workInProgress) {
19797 var root = workInProgress.stateNode;
19798
19799 if (root.pendingContext) {
19800 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
19801 } else if (root.context) {
19802 // Should always be set
19803 pushTopLevelContextObject(workInProgress, root.context, false);
19804 }
19805
19806 pushHostContainer(workInProgress, root.containerInfo);
19807}
19808
19809function updateHostRoot(current, workInProgress, renderLanes) {
19810 pushHostRootContext(workInProgress);
19811
19812 if (current === null) {
19813 throw new Error('Should have a current fiber. This is a bug in React.');
19814 }
19815
19816 var nextProps = workInProgress.pendingProps;
19817 var prevState = workInProgress.memoizedState;
19818 var prevChildren = prevState.element;
19819 cloneUpdateQueue(current, workInProgress);
19820 processUpdateQueue(workInProgress, nextProps, null, renderLanes);
19821 var nextState = workInProgress.memoizedState;
19822 var root = workInProgress.stateNode;
19823 // being called "element".
19824
19825
19826 var nextChildren = nextState.element;
19827
19828 if ( prevState.isDehydrated) {
19829 // This is a hydration root whose shell has not yet hydrated. We should
19830 // attempt to hydrate.
19831 // Flip isDehydrated to false to indicate that when this render
19832 // finishes, the root will no longer be dehydrated.
19833 var overrideState = {
19834 element: nextChildren,
19835 isDehydrated: false,
19836 cache: nextState.cache,
19837 pendingSuspenseBoundaries: nextState.pendingSuspenseBoundaries,
19838 transitions: nextState.transitions
19839 };
19840 var updateQueue = workInProgress.updateQueue; // `baseState` can always be the last state because the root doesn't
19841 // have reducer functions so it doesn't need rebasing.
19842
19843 updateQueue.baseState = overrideState;
19844 workInProgress.memoizedState = overrideState;
19845
19846 if (workInProgress.flags & ForceClientRender) {
19847 // Something errored during a previous attempt to hydrate the shell, so we
19848 // forced a client render.
19849 var recoverableError = createCapturedValueAtFiber(new Error('There was an error while hydrating. Because the error happened outside ' + 'of a Suspense boundary, the entire root will switch to ' + 'client rendering.'), workInProgress);
19850 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError);
19851 } else if (nextChildren !== prevChildren) {
19852 var _recoverableError = createCapturedValueAtFiber(new Error('This root received an early update, before anything was able ' + 'hydrate. Switched the entire root to client rendering.'), workInProgress);
19853
19854 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, _recoverableError);
19855 } else {
19856 // The outermost shell has not hydrated yet. Start hydrating.
19857 enterHydrationState(workInProgress);
19858
19859 var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
19860 workInProgress.child = child;
19861 var node = child;
19862
19863 while (node) {
19864 // Mark each child as hydrating. This is a fast path to know whether this
19865 // tree is part of a hydrating tree. This is used to determine if a child
19866 // node has fully mounted yet, and for scheduling event replaying.
19867 // Conceptually this is similar to Placement in that a new subtree is
19868 // inserted into the React tree here. It just happens to not need DOM
19869 // mutations because it already exists.
19870 node.flags = node.flags & ~Placement | Hydrating;
19871 node = node.sibling;
19872 }
19873 }
19874 } else {
19875 // Root is not dehydrated. Either this is a client-only root, or it
19876 // already hydrated.
19877 resetHydrationState();
19878
19879 if (nextChildren === prevChildren) {
19880 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
19881 }
19882
19883 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19884 }
19885
19886 return workInProgress.child;
19887}
19888
19889function mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError) {
19890 // Revert to client rendering.
19891 resetHydrationState();
19892 queueHydrationError(recoverableError);
19893 workInProgress.flags |= ForceClientRender;
19894 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19895 return workInProgress.child;
19896}
19897
19898function updateHostComponent(current, workInProgress, renderLanes) {
19899 pushHostContext(workInProgress);
19900
19901 if (current === null) {
19902 tryToClaimNextHydratableInstance(workInProgress);
19903 }
19904
19905 var type = workInProgress.type;
19906 var nextProps = workInProgress.pendingProps;
19907 var prevProps = current !== null ? current.memoizedProps : null;
19908 var nextChildren = nextProps.children;
19909 var isDirectTextChild = shouldSetTextContent(type, nextProps);
19910
19911 if (isDirectTextChild) {
19912 // We special case a direct text child of a host node. This is a common
19913 // case. We won't handle it as a reified child. We will instead handle
19914 // this in the host environment that also has access to this prop. That
19915 // avoids allocating another HostText fiber and traversing it.
19916 nextChildren = null;
19917 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
19918 // If we're switching from a direct text child to a normal child, or to
19919 // empty, we need to schedule the text content to be reset.
19920 workInProgress.flags |= ContentReset;
19921 }
19922
19923 markRef(current, workInProgress);
19924 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
19925 return workInProgress.child;
19926}
19927
19928function updateHostText(current, workInProgress) {
19929 if (current === null) {
19930 tryToClaimNextHydratableInstance(workInProgress);
19931 } // Nothing to do here. This is terminal. We'll do the completion step
19932 // immediately after.
19933
19934
19935 return null;
19936}
19937
19938function mountLazyComponent(_current, workInProgress, elementType, renderLanes) {
19939 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
19940 var props = workInProgress.pendingProps;
19941 var lazyComponent = elementType;
19942 var payload = lazyComponent._payload;
19943 var init = lazyComponent._init;
19944 var Component = init(payload); // Store the unwrapped component in the type.
19945
19946 workInProgress.type = Component;
19947 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
19948 var resolvedProps = resolveDefaultProps(Component, props);
19949 var child;
19950
19951 switch (resolvedTag) {
19952 case FunctionComponent:
19953 {
19954 {
19955 validateFunctionComponentInDev(workInProgress, Component);
19956 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
19957 }
19958
19959 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes);
19960 return child;
19961 }
19962
19963 case ClassComponent:
19964 {
19965 {
19966 workInProgress.type = Component = resolveClassForHotReloading(Component);
19967 }
19968
19969 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
19970 return child;
19971 }
19972
19973 case ForwardRef:
19974 {
19975 {
19976 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
19977 }
19978
19979 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes);
19980 return child;
19981 }
19982
19983 case MemoComponent:
19984 {
19985 {
19986 if (workInProgress.type !== workInProgress.elementType) {
19987 var outerPropTypes = Component.propTypes;
19988
19989 if (outerPropTypes) {
19990 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
19991 'prop', getComponentNameFromType(Component));
19992 }
19993 }
19994 }
19995
19996 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
19997 renderLanes);
19998 return child;
19999 }
20000 }
20001
20002 var hint = '';
20003
20004 {
20005 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
20006 hint = ' Did you wrap a component in React.lazy() more than once?';
20007 }
20008 } // This message intentionally doesn't mention ForwardRef or MemoComponent
20009 // because the fact that it's a separate type of work is an
20010 // implementation detail.
20011
20012
20013 throw new Error("Element type is invalid. Received a promise that resolves to: " + Component + ". " + ("Lazy element type must resolve to a class or function." + hint));
20014}
20015
20016function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) {
20017 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress); // Promote the fiber to a class and try rendering again.
20018
20019 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
20020 // Push context providers early to prevent context stack mismatches.
20021 // During mounting we don't know the child context yet as the instance doesn't exist.
20022 // We will invalidate the child context in finishClassComponent() right after rendering.
20023
20024 var hasContext;
20025
20026 if (isContextProvider(Component)) {
20027 hasContext = true;
20028 pushContextProvider(workInProgress);
20029 } else {
20030 hasContext = false;
20031 }
20032
20033 prepareToReadContext(workInProgress, renderLanes);
20034 constructClassInstance(workInProgress, Component, nextProps);
20035 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
20036 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
20037}
20038
20039function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) {
20040 resetSuspendedCurrentOnMountInLegacyMode(_current, workInProgress);
20041 var props = workInProgress.pendingProps;
20042 var context;
20043
20044 {
20045 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
20046 context = getMaskedContext(workInProgress, unmaskedContext);
20047 }
20048
20049 prepareToReadContext(workInProgress, renderLanes);
20050 var value;
20051 var hasId;
20052
20053 {
20054 markComponentRenderStarted(workInProgress);
20055 }
20056
20057 {
20058 if (Component.prototype && typeof Component.prototype.render === 'function') {
20059 var componentName = getComponentNameFromType(Component) || 'Unknown';
20060
20061 if (!didWarnAboutBadClass[componentName]) {
20062 error("The <%s /> component appears to have a render method, but doesn't extend React.Component. " + 'This is likely to cause errors. Change %s to extend React.Component instead.', componentName, componentName);
20063
20064 didWarnAboutBadClass[componentName] = true;
20065 }
20066 }
20067
20068 if (workInProgress.mode & StrictLegacyMode) {
20069 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
20070 }
20071
20072 setIsRendering(true);
20073 ReactCurrentOwner$1.current = workInProgress;
20074 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
20075 hasId = checkDidRenderIdHook();
20076 setIsRendering(false);
20077 }
20078
20079 {
20080 markComponentRenderStopped();
20081 } // React DevTools reads this flag.
20082
20083
20084 workInProgress.flags |= PerformedWork;
20085
20086 {
20087 // Support for module components is deprecated and is removed behind a flag.
20088 // Whether or not it would crash later, we want to show a good message in DEV first.
20089 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
20090 var _componentName = getComponentNameFromType(Component) || 'Unknown';
20091
20092 if (!didWarnAboutModulePatternComponent[_componentName]) {
20093 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName, _componentName, _componentName);
20094
20095 didWarnAboutModulePatternComponent[_componentName] = true;
20096 }
20097 }
20098 }
20099
20100 if ( // Run these checks in production only if the flag is off.
20101 // Eventually we'll delete this branch altogether.
20102 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
20103 {
20104 var _componentName2 = getComponentNameFromType(Component) || 'Unknown';
20105
20106 if (!didWarnAboutModulePatternComponent[_componentName2]) {
20107 error('The <%s /> component appears to be a function component that returns a class instance. ' + 'Change %s to a class that extends React.Component instead. ' + "If you can't use a class try assigning the prototype on the function as a workaround. " + "`%s.prototype = React.Component.prototype`. Don't use an arrow function since it " + 'cannot be called with `new` by React.', _componentName2, _componentName2, _componentName2);
20108
20109 didWarnAboutModulePatternComponent[_componentName2] = true;
20110 }
20111 } // Proceed under the assumption that this is a class instance
20112
20113
20114 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
20115
20116 workInProgress.memoizedState = null;
20117 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
20118 // During mounting we don't know the child context yet as the instance doesn't exist.
20119 // We will invalidate the child context in finishClassComponent() right after rendering.
20120
20121 var hasContext = false;
20122
20123 if (isContextProvider(Component)) {
20124 hasContext = true;
20125 pushContextProvider(workInProgress);
20126 } else {
20127 hasContext = false;
20128 }
20129
20130 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
20131 initializeUpdateQueue(workInProgress);
20132 adoptClassInstance(workInProgress, value);
20133 mountClassInstance(workInProgress, Component, props, renderLanes);
20134 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
20135 } else {
20136 // Proceed under the assumption that this is a function component
20137 workInProgress.tag = FunctionComponent;
20138
20139 {
20140
20141 if ( workInProgress.mode & StrictLegacyMode) {
20142 setIsStrictModeForDevtools(true);
20143
20144 try {
20145 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
20146 hasId = checkDidRenderIdHook();
20147 } finally {
20148 setIsStrictModeForDevtools(false);
20149 }
20150 }
20151 }
20152
20153 if (getIsHydrating() && hasId) {
20154 pushMaterializedTreeId(workInProgress);
20155 }
20156
20157 reconcileChildren(null, workInProgress, value, renderLanes);
20158
20159 {
20160 validateFunctionComponentInDev(workInProgress, Component);
20161 }
20162
20163 return workInProgress.child;
20164 }
20165}
20166
20167function validateFunctionComponentInDev(workInProgress, Component) {
20168 {
20169 if (Component) {
20170 if (Component.childContextTypes) {
20171 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
20172 }
20173 }
20174
20175 if (workInProgress.ref !== null) {
20176 var info = '';
20177 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
20178
20179 if (ownerName) {
20180 info += '\n\nCheck the render method of `' + ownerName + '`.';
20181 }
20182
20183 var warningKey = ownerName || '';
20184 var debugSource = workInProgress._debugSource;
20185
20186 if (debugSource) {
20187 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
20188 }
20189
20190 if (!didWarnAboutFunctionRefs[warningKey]) {
20191 didWarnAboutFunctionRefs[warningKey] = true;
20192
20193 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
20194 }
20195 }
20196
20197 if (typeof Component.getDerivedStateFromProps === 'function') {
20198 var _componentName3 = getComponentNameFromType(Component) || 'Unknown';
20199
20200 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
20201 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3);
20202
20203 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
20204 }
20205 }
20206
20207 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
20208 var _componentName4 = getComponentNameFromType(Component) || 'Unknown';
20209
20210 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
20211 error('%s: Function components do not support contextType.', _componentName4);
20212
20213 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
20214 }
20215 }
20216 }
20217}
20218
20219var SUSPENDED_MARKER = {
20220 dehydrated: null,
20221 treeContext: null,
20222 retryLane: NoLane
20223};
20224
20225function mountSuspenseOffscreenState(renderLanes) {
20226 return {
20227 baseLanes: renderLanes,
20228 cachePool: getSuspendedCache(),
20229 transitions: null
20230 };
20231}
20232
20233function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
20234 var cachePool = null;
20235
20236 return {
20237 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes),
20238 cachePool: cachePool,
20239 transitions: prevOffscreenState.transitions
20240 };
20241} // TODO: Probably should inline this back
20242
20243
20244function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
20245 // If we're already showing a fallback, there are cases where we need to
20246 // remain on that fallback regardless of whether the content has resolved.
20247 // For example, SuspenseList coordinates when nested content appears.
20248 if (current !== null) {
20249 var suspenseState = current.memoizedState;
20250
20251 if (suspenseState === null) {
20252 // Currently showing content. Don't hide it, even if ForceSuspenseFallback
20253 // is true. More precise name might be "ForceRemainSuspenseFallback".
20254 // Note: This is a factoring smell. Can't remain on a fallback if there's
20255 // no fallback to remain on.
20256 return false;
20257 }
20258 } // Not currently showing content. Consult the Suspense context.
20259
20260
20261 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
20262}
20263
20264function getRemainingWorkInPrimaryTree(current, renderLanes) {
20265 // TODO: Should not remove render lanes that were pinged during this render
20266 return removeLanes(current.childLanes, renderLanes);
20267}
20268
20269function updateSuspenseComponent(current, workInProgress, renderLanes) {
20270 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
20271
20272 {
20273 if (shouldSuspend(workInProgress)) {
20274 workInProgress.flags |= DidCapture;
20275 }
20276 }
20277
20278 var suspenseContext = suspenseStackCursor.current;
20279 var showFallback = false;
20280 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags;
20281
20282 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
20283 // Something in this boundary's subtree already suspended. Switch to
20284 // rendering the fallback children.
20285 showFallback = true;
20286 workInProgress.flags &= ~DidCapture;
20287 } else {
20288 // Attempting the main content
20289 if (current === null || current.memoizedState !== null) {
20290 // This is a new mount or this boundary is already showing a fallback state.
20291 // Mark this subtree context as having at least one invisible parent that could
20292 // handle the fallback state.
20293 // Avoided boundaries are not considered since they cannot handle preferred fallback states.
20294 {
20295 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
20296 }
20297 }
20298 }
20299
20300 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
20301 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense
20302 // boundary's children. This involves some custom reconciliation logic. Two
20303 // main reasons this is so complicated.
20304 //
20305 // First, Legacy Mode has different semantics for backwards compatibility. The
20306 // primary tree will commit in an inconsistent state, so when we do the
20307 // second pass to render the fallback, we do some exceedingly, uh, clever
20308 // hacks to make that not totally break. Like transferring effects and
20309 // deletions from hidden tree. In Concurrent Mode, it's much simpler,
20310 // because we bailout on the primary tree completely and leave it in its old
20311 // state, no effects. Same as what we do for Offscreen (except that
20312 // Offscreen doesn't have the first render pass).
20313 //
20314 // Second is hydration. During hydration, the Suspense fiber has a slightly
20315 // different layout, where the child points to a dehydrated fragment, which
20316 // contains the DOM rendered by the server.
20317 //
20318 // Third, even if you set all that aside, Suspense is like error boundaries in
20319 // that we first we try to render one tree, and if that fails, we render again
20320 // and switch to a different tree. Like a try/catch block. So we have to track
20321 // which branch we're currently rendering. Ideally we would model this using
20322 // a stack.
20323
20324 if (current === null) {
20325 // Initial mount
20326 // Special path for hydration
20327 // If we're currently hydrating, try to hydrate this boundary.
20328 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
20329
20330 var suspenseState = workInProgress.memoizedState;
20331
20332 if (suspenseState !== null) {
20333 var dehydrated = suspenseState.dehydrated;
20334
20335 if (dehydrated !== null) {
20336 return mountDehydratedSuspenseComponent(workInProgress, dehydrated);
20337 }
20338 }
20339
20340 var nextPrimaryChildren = nextProps.children;
20341 var nextFallbackChildren = nextProps.fallback;
20342
20343 if (showFallback) {
20344 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
20345 var primaryChildFragment = workInProgress.child;
20346 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
20347 workInProgress.memoizedState = SUSPENDED_MARKER;
20348
20349 return fallbackFragment;
20350 } else {
20351 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);
20352 }
20353 } else {
20354 // This is an update.
20355 // Special path for hydration
20356 var prevState = current.memoizedState;
20357
20358 if (prevState !== null) {
20359 var _dehydrated = prevState.dehydrated;
20360
20361 if (_dehydrated !== null) {
20362 return updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, _dehydrated, prevState, renderLanes);
20363 }
20364 }
20365
20366 if (showFallback) {
20367 var _nextFallbackChildren = nextProps.fallback;
20368 var _nextPrimaryChildren = nextProps.children;
20369 var fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren, _nextFallbackChildren, renderLanes);
20370 var _primaryChildFragment2 = workInProgress.child;
20371 var prevOffscreenState = current.child.memoizedState;
20372 _primaryChildFragment2.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
20373
20374 _primaryChildFragment2.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
20375 workInProgress.memoizedState = SUSPENDED_MARKER;
20376 return fallbackChildFragment;
20377 } else {
20378 var _nextPrimaryChildren2 = nextProps.children;
20379
20380 var _primaryChildFragment3 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren2, renderLanes);
20381
20382 workInProgress.memoizedState = null;
20383 return _primaryChildFragment3;
20384 }
20385 }
20386}
20387
20388function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
20389 var mode = workInProgress.mode;
20390 var primaryChildProps = {
20391 mode: 'visible',
20392 children: primaryChildren
20393 };
20394 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
20395 primaryChildFragment.return = workInProgress;
20396 workInProgress.child = primaryChildFragment;
20397 return primaryChildFragment;
20398}
20399
20400function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
20401 var mode = workInProgress.mode;
20402 var progressedPrimaryFragment = workInProgress.child;
20403 var primaryChildProps = {
20404 mode: 'hidden',
20405 children: primaryChildren
20406 };
20407 var primaryChildFragment;
20408 var fallbackChildFragment;
20409
20410 if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) {
20411 // In legacy mode, we commit the primary tree as if it successfully
20412 // completed, even though it's in an inconsistent state.
20413 primaryChildFragment = progressedPrimaryFragment;
20414 primaryChildFragment.childLanes = NoLanes;
20415 primaryChildFragment.pendingProps = primaryChildProps;
20416
20417 if ( workInProgress.mode & ProfileMode) {
20418 // Reset the durations from the first pass so they aren't included in the
20419 // final amounts. This seems counterintuitive, since we're intentionally
20420 // not measuring part of the render phase, but this makes it match what we
20421 // do in Concurrent Mode.
20422 primaryChildFragment.actualDuration = 0;
20423 primaryChildFragment.actualStartTime = -1;
20424 primaryChildFragment.selfBaseDuration = 0;
20425 primaryChildFragment.treeBaseDuration = 0;
20426 }
20427
20428 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
20429 } else {
20430 primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
20431 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
20432 }
20433
20434 primaryChildFragment.return = workInProgress;
20435 fallbackChildFragment.return = workInProgress;
20436 primaryChildFragment.sibling = fallbackChildFragment;
20437 workInProgress.child = primaryChildFragment;
20438 return fallbackChildFragment;
20439}
20440
20441function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) {
20442 // The props argument to `createFiberFromOffscreen` is `any` typed, so we use
20443 // this wrapper function to constrain it.
20444 return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null);
20445}
20446
20447function updateWorkInProgressOffscreenFiber(current, offscreenProps) {
20448 // The props argument to `createWorkInProgress` is `any` typed, so we use this
20449 // wrapper function to constrain it.
20450 return createWorkInProgress(current, offscreenProps);
20451}
20452
20453function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
20454 var currentPrimaryChildFragment = current.child;
20455 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
20456 var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
20457 mode: 'visible',
20458 children: primaryChildren
20459 });
20460
20461 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
20462 primaryChildFragment.lanes = renderLanes;
20463 }
20464
20465 primaryChildFragment.return = workInProgress;
20466 primaryChildFragment.sibling = null;
20467
20468 if (currentFallbackChildFragment !== null) {
20469 // Delete the fallback child fragment
20470 var deletions = workInProgress.deletions;
20471
20472 if (deletions === null) {
20473 workInProgress.deletions = [currentFallbackChildFragment];
20474 workInProgress.flags |= ChildDeletion;
20475 } else {
20476 deletions.push(currentFallbackChildFragment);
20477 }
20478 }
20479
20480 workInProgress.child = primaryChildFragment;
20481 return primaryChildFragment;
20482}
20483
20484function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
20485 var mode = workInProgress.mode;
20486 var currentPrimaryChildFragment = current.child;
20487 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
20488 var primaryChildProps = {
20489 mode: 'hidden',
20490 children: primaryChildren
20491 };
20492 var primaryChildFragment;
20493
20494 if ( // In legacy mode, we commit the primary tree as if it successfully
20495 // completed, even though it's in an inconsistent state.
20496 (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was
20497 // already cloned. In legacy mode, the only case where this isn't true is
20498 // when DevTools forces us to display a fallback; we skip the first render
20499 // pass entirely and go straight to rendering the fallback. (In Concurrent
20500 // Mode, SuspenseList can also trigger this scenario, but this is a legacy-
20501 // only codepath.)
20502 workInProgress.child !== currentPrimaryChildFragment) {
20503 var progressedPrimaryFragment = workInProgress.child;
20504 primaryChildFragment = progressedPrimaryFragment;
20505 primaryChildFragment.childLanes = NoLanes;
20506 primaryChildFragment.pendingProps = primaryChildProps;
20507
20508 if ( workInProgress.mode & ProfileMode) {
20509 // Reset the durations from the first pass so they aren't included in the
20510 // final amounts. This seems counterintuitive, since we're intentionally
20511 // not measuring part of the render phase, but this makes it match what we
20512 // do in Concurrent Mode.
20513 primaryChildFragment.actualDuration = 0;
20514 primaryChildFragment.actualStartTime = -1;
20515 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
20516 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
20517 } // The fallback fiber was added as a deletion during the first pass.
20518 // However, since we're going to remain on the fallback, we no longer want
20519 // to delete it.
20520
20521
20522 workInProgress.deletions = null;
20523 } else {
20524 primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps); // Since we're reusing a current tree, we need to reuse the flags, too.
20525 // (We don't do this in legacy mode, because in legacy mode we don't re-use
20526 // the current tree; see previous branch.)
20527
20528 primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
20529 }
20530
20531 var fallbackChildFragment;
20532
20533 if (currentFallbackChildFragment !== null) {
20534 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
20535 } else {
20536 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
20537 // mounted but this is a new fiber.
20538
20539 fallbackChildFragment.flags |= Placement;
20540 }
20541
20542 fallbackChildFragment.return = workInProgress;
20543 primaryChildFragment.return = workInProgress;
20544 primaryChildFragment.sibling = fallbackChildFragment;
20545 workInProgress.child = primaryChildFragment;
20546 return fallbackChildFragment;
20547}
20548
20549function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, recoverableError) {
20550 // Falling back to client rendering. Because this has performance
20551 // implications, it's considered a recoverable error, even though the user
20552 // likely won't observe anything wrong with the UI.
20553 //
20554 // The error is passed in as an argument to enforce that every caller provide
20555 // a custom message, or explicitly opt out (currently the only path that opts
20556 // out is legacy mode; every concurrent path provides an error).
20557 if (recoverableError !== null) {
20558 queueHydrationError(recoverableError);
20559 } // This will add the old fiber to the deletion list
20560
20561
20562 reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
20563
20564 var nextProps = workInProgress.pendingProps;
20565 var primaryChildren = nextProps.children;
20566 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Needs a placement effect because the parent (the Suspense boundary) already
20567 // mounted but this is a new fiber.
20568
20569 primaryChildFragment.flags |= Placement;
20570 workInProgress.memoizedState = null;
20571 return primaryChildFragment;
20572}
20573
20574function mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
20575 var fiberMode = workInProgress.mode;
20576 var primaryChildProps = {
20577 mode: 'visible',
20578 children: primaryChildren
20579 };
20580 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode);
20581 var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes, null); // Needs a placement effect because the parent (the Suspense
20582 // boundary) already mounted but this is a new fiber.
20583
20584 fallbackChildFragment.flags |= Placement;
20585 primaryChildFragment.return = workInProgress;
20586 fallbackChildFragment.return = workInProgress;
20587 primaryChildFragment.sibling = fallbackChildFragment;
20588 workInProgress.child = primaryChildFragment;
20589
20590 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
20591 // We will have dropped the effect list which contains the
20592 // deletion. We need to reconcile to delete the current child.
20593 reconcileChildFibers(workInProgress, current.child, null, renderLanes);
20594 }
20595
20596 return fallbackChildFragment;
20597}
20598
20599function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderLanes) {
20600 // During the first pass, we'll bail out and not drill into the children.
20601 // Instead, we'll leave the content in place and try to hydrate it later.
20602 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
20603 {
20604 error('Cannot hydrate Suspense in legacy mode. Switch from ' + 'ReactDOM.hydrate(element, container) to ' + 'ReactDOMClient.hydrateRoot(container, <App />)' + '.render(element) or remove the Suspense components from ' + 'the server rendered components.');
20605 }
20606
20607 workInProgress.lanes = laneToLanes(SyncLane);
20608 } else if (isSuspenseInstanceFallback(suspenseInstance)) {
20609 // This is a client-only boundary. Since we won't get any content from the server
20610 // for this, we need to schedule that at a higher priority based on when it would
20611 // have timed out. In theory we could render it in this pass but it would have the
20612 // wrong priority associated with it and will prevent hydration of parent path.
20613 // Instead, we'll leave work left on it to render it in a separate commit.
20614 // TODO This time should be the time at which the server rendered response that is
20615 // a parent to this boundary was displayed. However, since we currently don't have
20616 // a protocol to transfer that time, we'll just estimate it by using the current
20617 // time. This will mean that Suspense timeouts are slightly shifted to later than
20618 // they should be.
20619 // Schedule a normal pri update to render this content.
20620 workInProgress.lanes = laneToLanes(DefaultHydrationLane);
20621 } else {
20622 // We'll continue hydrating the rest at offscreen priority since we'll already
20623 // be showing the right content coming from the server, it is no rush.
20624 workInProgress.lanes = laneToLanes(OffscreenLane);
20625 }
20626
20627 return null;
20628}
20629
20630function updateDehydratedSuspenseComponent(current, workInProgress, didSuspend, nextProps, suspenseInstance, suspenseState, renderLanes) {
20631 if (!didSuspend) {
20632 // This is the first render pass. Attempt to hydrate.
20633 // We should never be hydrating at this point because it is the first pass,
20634 // but after we've already committed once.
20635 warnIfHydrating();
20636
20637 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
20638 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, // TODO: When we delete legacy mode, we should make this error argument
20639 // required — every concurrent mode path that causes hydration to
20640 // de-opt to client rendering should have an error message.
20641 null);
20642 }
20643
20644 if (isSuspenseInstanceFallback(suspenseInstance)) {
20645 // This boundary is in a permanent fallback state. In this case, we'll never
20646 // get an update and we'll never be able to hydrate the final content. Let's just try the
20647 // client side render instead.
20648 var digest, message, stack;
20649
20650 {
20651 var _getSuspenseInstanceF = getSuspenseInstanceFallbackErrorDetails(suspenseInstance);
20652
20653 digest = _getSuspenseInstanceF.digest;
20654 message = _getSuspenseInstanceF.message;
20655 stack = _getSuspenseInstanceF.stack;
20656 }
20657
20658 var error;
20659
20660 if (message) {
20661 // eslint-disable-next-line react-internal/prod-error-codes
20662 error = new Error(message);
20663 } else {
20664 error = new Error('The server could not finish this Suspense boundary, likely ' + 'due to an error during server rendering. Switched to ' + 'client rendering.');
20665 }
20666
20667 var capturedValue = createCapturedValue(error, digest, stack);
20668 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, capturedValue);
20669 }
20670 // any context has changed, we need to treat is as if the input might have changed.
20671
20672
20673 var hasContextChanged = includesSomeLane(renderLanes, current.childLanes);
20674
20675 if (didReceiveUpdate || hasContextChanged) {
20676 // This boundary has changed since the first render. This means that we are now unable to
20677 // hydrate it. We might still be able to hydrate it using a higher priority lane.
20678 var root = getWorkInProgressRoot();
20679
20680 if (root !== null) {
20681 var attemptHydrationAtLane = getBumpedLaneForHydration(root, renderLanes);
20682
20683 if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) {
20684 // Intentionally mutating since this render will get interrupted. This
20685 // is one of the very rare times where we mutate the current tree
20686 // during the render phase.
20687 suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render
20688
20689 var eventTime = NoTimestamp;
20690 enqueueConcurrentRenderForLane(current, attemptHydrationAtLane);
20691 scheduleUpdateOnFiber(root, current, attemptHydrationAtLane, eventTime);
20692 }
20693 } // If we have scheduled higher pri work above, this will probably just abort the render
20694 // since we now have higher priority work, but in case it doesn't, we need to prepare to
20695 // render something, if we time out. Even if that requires us to delete everything and
20696 // skip hydration.
20697 // Delay having to do this as long as the suspense timeout allows us.
20698
20699
20700 renderDidSuspendDelayIfPossible();
20701
20702 var _capturedValue = createCapturedValue(new Error('This Suspense boundary received an update before it finished ' + 'hydrating. This caused the boundary to switch to client rendering. ' + 'The usual way to fix this is to wrap the original update ' + 'in startTransition.'));
20703
20704 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue);
20705 } else if (isSuspenseInstancePending(suspenseInstance)) {
20706 // This component is still pending more data from the server, so we can't hydrate its
20707 // content. We treat it as if this component suspended itself. It might seem as if
20708 // we could just try to render it client-side instead. However, this will perform a
20709 // lot of unnecessary work and is unlikely to complete since it often will suspend
20710 // on missing data anyway. Additionally, the server might be able to render more
20711 // than we can on the client yet. In that case we'd end up with more fallback states
20712 // on the client than if we just leave it alone. If the server times out or errors
20713 // these should update this boundary to the permanent Fallback state instead.
20714 // Mark it as having captured (i.e. suspended).
20715 workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
20716
20717 workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result.
20718
20719 var retry = retryDehydratedSuspenseBoundary.bind(null, current);
20720 registerSuspenseInstanceRetry(suspenseInstance, retry);
20721 return null;
20722 } else {
20723 // This is the first attempt.
20724 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance, suspenseState.treeContext);
20725 var primaryChildren = nextProps.children;
20726 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Mark the children as hydrating. This is a fast path to know whether this
20727 // tree is part of a hydrating tree. This is used to determine if a child
20728 // node has fully mounted yet, and for scheduling event replaying.
20729 // Conceptually this is similar to Placement in that a new subtree is
20730 // inserted into the React tree here. It just happens to not need DOM
20731 // mutations because it already exists.
20732
20733 primaryChildFragment.flags |= Hydrating;
20734 return primaryChildFragment;
20735 }
20736 } else {
20737 // This is the second render pass. We already attempted to hydrated, but
20738 // something either suspended or errored.
20739 if (workInProgress.flags & ForceClientRender) {
20740 // Something errored during hydration. Try again without hydrating.
20741 workInProgress.flags &= ~ForceClientRender;
20742
20743 var _capturedValue2 = createCapturedValue(new Error('There was an error while hydrating this Suspense boundary. ' + 'Switched to client rendering.'));
20744
20745 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, _capturedValue2);
20746 } else if (workInProgress.memoizedState !== null) {
20747 // Something suspended and we should still be in dehydrated mode.
20748 // Leave the existing child in place.
20749 workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there
20750 // but the normal suspense pass doesn't.
20751
20752 workInProgress.flags |= DidCapture;
20753 return null;
20754 } else {
20755 // Suspended but we should no longer be in dehydrated mode.
20756 // Therefore we now have to render the fallback.
20757 var nextPrimaryChildren = nextProps.children;
20758 var nextFallbackChildren = nextProps.fallback;
20759 var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
20760 var _primaryChildFragment4 = workInProgress.child;
20761 _primaryChildFragment4.memoizedState = mountSuspenseOffscreenState(renderLanes);
20762 workInProgress.memoizedState = SUSPENDED_MARKER;
20763 return fallbackChildFragment;
20764 }
20765 }
20766}
20767
20768function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {
20769 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
20770 var alternate = fiber.alternate;
20771
20772 if (alternate !== null) {
20773 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
20774 }
20775
20776 scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);
20777}
20778
20779function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
20780 // Mark any Suspense boundaries with fallbacks as having work to do.
20781 // If they were previously forced into fallbacks, they may now be able
20782 // to unblock.
20783 var node = firstChild;
20784
20785 while (node !== null) {
20786 if (node.tag === SuspenseComponent) {
20787 var state = node.memoizedState;
20788
20789 if (state !== null) {
20790 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
20791 }
20792 } else if (node.tag === SuspenseListComponent) {
20793 // If the tail is hidden there might not be an Suspense boundaries
20794 // to schedule work on. In this case we have to schedule it on the
20795 // list itself.
20796 // We don't have to traverse to the children of the list since
20797 // the list will propagate the change when it rerenders.
20798 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
20799 } else if (node.child !== null) {
20800 node.child.return = node;
20801 node = node.child;
20802 continue;
20803 }
20804
20805 if (node === workInProgress) {
20806 return;
20807 }
20808
20809 while (node.sibling === null) {
20810 if (node.return === null || node.return === workInProgress) {
20811 return;
20812 }
20813
20814 node = node.return;
20815 }
20816
20817 node.sibling.return = node.return;
20818 node = node.sibling;
20819 }
20820}
20821
20822function findLastContentRow(firstChild) {
20823 // This is going to find the last row among these children that is already
20824 // showing content on the screen, as opposed to being in fallback state or
20825 // new. If a row has multiple Suspense boundaries, any of them being in the
20826 // fallback state, counts as the whole row being in a fallback state.
20827 // Note that the "rows" will be workInProgress, but any nested children
20828 // will still be current since we haven't rendered them yet. The mounted
20829 // order may not be the same as the new order. We use the new order.
20830 var row = firstChild;
20831 var lastContentRow = null;
20832
20833 while (row !== null) {
20834 var currentRow = row.alternate; // New rows can't be content rows.
20835
20836 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
20837 lastContentRow = row;
20838 }
20839
20840 row = row.sibling;
20841 }
20842
20843 return lastContentRow;
20844}
20845
20846function validateRevealOrder(revealOrder) {
20847 {
20848 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
20849 didWarnAboutRevealOrder[revealOrder] = true;
20850
20851 if (typeof revealOrder === 'string') {
20852 switch (revealOrder.toLowerCase()) {
20853 case 'together':
20854 case 'forwards':
20855 case 'backwards':
20856 {
20857 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
20858
20859 break;
20860 }
20861
20862 case 'forward':
20863 case 'backward':
20864 {
20865 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'React uses the -s suffix in the spelling. Use "%ss" instead.', revealOrder, revealOrder.toLowerCase());
20866
20867 break;
20868 }
20869
20870 default:
20871 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
20872
20873 break;
20874 }
20875 } else {
20876 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
20877 }
20878 }
20879 }
20880}
20881
20882function validateTailOptions(tailMode, revealOrder) {
20883 {
20884 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
20885 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
20886 didWarnAboutTailOptions[tailMode] = true;
20887
20888 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
20889 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
20890 didWarnAboutTailOptions[tailMode] = true;
20891
20892 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
20893 }
20894 }
20895 }
20896}
20897
20898function validateSuspenseListNestedChild(childSlot, index) {
20899 {
20900 var isAnArray = isArray(childSlot);
20901 var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === 'function';
20902
20903 if (isAnArray || isIterable) {
20904 var type = isAnArray ? 'array' : 'iterable';
20905
20906 error('A nested %s was passed to row #%s in <SuspenseList />. Wrap it in ' + 'an additional SuspenseList to configure its revealOrder: ' + '<SuspenseList revealOrder=...> ... ' + '<SuspenseList revealOrder=...>{%s}</SuspenseList> ... ' + '</SuspenseList>', type, index, type);
20907
20908 return false;
20909 }
20910 }
20911
20912 return true;
20913}
20914
20915function validateSuspenseListChildren(children, revealOrder) {
20916 {
20917 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
20918 if (isArray(children)) {
20919 for (var i = 0; i < children.length; i++) {
20920 if (!validateSuspenseListNestedChild(children[i], i)) {
20921 return;
20922 }
20923 }
20924 } else {
20925 var iteratorFn = getIteratorFn(children);
20926
20927 if (typeof iteratorFn === 'function') {
20928 var childrenIterator = iteratorFn.call(children);
20929
20930 if (childrenIterator) {
20931 var step = childrenIterator.next();
20932 var _i = 0;
20933
20934 for (; !step.done; step = childrenIterator.next()) {
20935 if (!validateSuspenseListNestedChild(step.value, _i)) {
20936 return;
20937 }
20938
20939 _i++;
20940 }
20941 }
20942 } else {
20943 error('A single row was passed to a <SuspenseList revealOrder="%s" />. ' + 'This is not useful since it needs multiple rows. ' + 'Did you mean to pass multiple children or an array?', revealOrder);
20944 }
20945 }
20946 }
20947 }
20948}
20949
20950function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
20951 var renderState = workInProgress.memoizedState;
20952
20953 if (renderState === null) {
20954 workInProgress.memoizedState = {
20955 isBackwards: isBackwards,
20956 rendering: null,
20957 renderingStartTime: 0,
20958 last: lastContentRow,
20959 tail: tail,
20960 tailMode: tailMode
20961 };
20962 } else {
20963 // We can reuse the existing object from previous renders.
20964 renderState.isBackwards = isBackwards;
20965 renderState.rendering = null;
20966 renderState.renderingStartTime = 0;
20967 renderState.last = lastContentRow;
20968 renderState.tail = tail;
20969 renderState.tailMode = tailMode;
20970 }
20971} // This can end up rendering this component multiple passes.
20972// The first pass splits the children fibers into two sets. A head and tail.
20973// We first render the head. If anything is in fallback state, we do another
20974// pass through beginWork to rerender all children (including the tail) with
20975// the force suspend context. If the first render didn't have anything in
20976// in fallback state. Then we render each row in the tail one-by-one.
20977// That happens in the completeWork phase without going back to beginWork.
20978
20979
20980function updateSuspenseListComponent(current, workInProgress, renderLanes) {
20981 var nextProps = workInProgress.pendingProps;
20982 var revealOrder = nextProps.revealOrder;
20983 var tailMode = nextProps.tail;
20984 var newChildren = nextProps.children;
20985 validateRevealOrder(revealOrder);
20986 validateTailOptions(tailMode, revealOrder);
20987 validateSuspenseListChildren(newChildren, revealOrder);
20988 reconcileChildren(current, workInProgress, newChildren, renderLanes);
20989 var suspenseContext = suspenseStackCursor.current;
20990 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
20991
20992 if (shouldForceFallback) {
20993 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
20994 workInProgress.flags |= DidCapture;
20995 } else {
20996 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags;
20997
20998 if (didSuspendBefore) {
20999 // If we previously forced a fallback, we need to schedule work
21000 // on any nested boundaries to let them know to try to render
21001 // again. This is the same as context updating.
21002 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
21003 }
21004
21005 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
21006 }
21007
21008 pushSuspenseContext(workInProgress, suspenseContext);
21009
21010 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
21011 // In legacy mode, SuspenseList doesn't work so we just
21012 // use make it a noop by treating it as the default revealOrder.
21013 workInProgress.memoizedState = null;
21014 } else {
21015 switch (revealOrder) {
21016 case 'forwards':
21017 {
21018 var lastContentRow = findLastContentRow(workInProgress.child);
21019 var tail;
21020
21021 if (lastContentRow === null) {
21022 // The whole list is part of the tail.
21023 // TODO: We could fast path by just rendering the tail now.
21024 tail = workInProgress.child;
21025 workInProgress.child = null;
21026 } else {
21027 // Disconnect the tail rows after the content row.
21028 // We're going to render them separately later.
21029 tail = lastContentRow.sibling;
21030 lastContentRow.sibling = null;
21031 }
21032
21033 initSuspenseListRenderState(workInProgress, false, // isBackwards
21034 tail, lastContentRow, tailMode);
21035 break;
21036 }
21037
21038 case 'backwards':
21039 {
21040 // We're going to find the first row that has existing content.
21041 // At the same time we're going to reverse the list of everything
21042 // we pass in the meantime. That's going to be our tail in reverse
21043 // order.
21044 var _tail = null;
21045 var row = workInProgress.child;
21046 workInProgress.child = null;
21047
21048 while (row !== null) {
21049 var currentRow = row.alternate; // New rows can't be content rows.
21050
21051 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
21052 // This is the beginning of the main content.
21053 workInProgress.child = row;
21054 break;
21055 }
21056
21057 var nextRow = row.sibling;
21058 row.sibling = _tail;
21059 _tail = row;
21060 row = nextRow;
21061 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
21062
21063
21064 initSuspenseListRenderState(workInProgress, true, // isBackwards
21065 _tail, null, // last
21066 tailMode);
21067 break;
21068 }
21069
21070 case 'together':
21071 {
21072 initSuspenseListRenderState(workInProgress, false, // isBackwards
21073 null, // tail
21074 null, // last
21075 undefined);
21076 break;
21077 }
21078
21079 default:
21080 {
21081 // The default reveal order is the same as not having
21082 // a boundary.
21083 workInProgress.memoizedState = null;
21084 }
21085 }
21086 }
21087
21088 return workInProgress.child;
21089}
21090
21091function updatePortalComponent(current, workInProgress, renderLanes) {
21092 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
21093 var nextChildren = workInProgress.pendingProps;
21094
21095 if (current === null) {
21096 // Portals are special because we don't append the children during mount
21097 // but at commit. Therefore we need to track insertions which the normal
21098 // flow doesn't do during mount. This doesn't happen at the root because
21099 // the root always starts with a "current" with a null child.
21100 // TODO: Consider unifying this with how the root works.
21101 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
21102 } else {
21103 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21104 }
21105
21106 return workInProgress.child;
21107}
21108
21109var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
21110
21111function updateContextProvider(current, workInProgress, renderLanes) {
21112 var providerType = workInProgress.type;
21113 var context = providerType._context;
21114 var newProps = workInProgress.pendingProps;
21115 var oldProps = workInProgress.memoizedProps;
21116 var newValue = newProps.value;
21117
21118 {
21119 if (!('value' in newProps)) {
21120 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
21121 hasWarnedAboutUsingNoValuePropOnContextProvider = true;
21122
21123 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?');
21124 }
21125 }
21126
21127 var providerPropTypes = workInProgress.type.propTypes;
21128
21129 if (providerPropTypes) {
21130 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
21131 }
21132 }
21133
21134 pushProvider(workInProgress, context, newValue);
21135
21136 {
21137 if (oldProps !== null) {
21138 var oldValue = oldProps.value;
21139
21140 if (objectIs(oldValue, newValue)) {
21141 // No change. Bailout early if children are the same.
21142 if (oldProps.children === newProps.children && !hasContextChanged()) {
21143 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21144 }
21145 } else {
21146 // The context value changed. Search for matching consumers and schedule
21147 // them to update.
21148 propagateContextChange(workInProgress, context, renderLanes);
21149 }
21150 }
21151 }
21152
21153 var newChildren = newProps.children;
21154 reconcileChildren(current, workInProgress, newChildren, renderLanes);
21155 return workInProgress.child;
21156}
21157
21158var hasWarnedAboutUsingContextAsConsumer = false;
21159
21160function updateContextConsumer(current, workInProgress, renderLanes) {
21161 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
21162 // DEV mode, we create a separate object for Context.Consumer that acts
21163 // like a proxy to Context. This proxy object adds unnecessary code in PROD
21164 // so we use the old behaviour (Context.Consumer references Context) to
21165 // reduce size and overhead. The separate object references context via
21166 // a property called "_context", which also gives us the ability to check
21167 // in DEV mode if this property exists or not and warn if it does not.
21168
21169 {
21170 if (context._context === undefined) {
21171 // This may be because it's a Context (rather than a Consumer).
21172 // Or it may be because it's older React where they're the same thing.
21173 // We only want to warn if we're sure it's a new React.
21174 if (context !== context.Consumer) {
21175 if (!hasWarnedAboutUsingContextAsConsumer) {
21176 hasWarnedAboutUsingContextAsConsumer = true;
21177
21178 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
21179 }
21180 }
21181 } else {
21182 context = context._context;
21183 }
21184 }
21185
21186 var newProps = workInProgress.pendingProps;
21187 var render = newProps.children;
21188
21189 {
21190 if (typeof render !== 'function') {
21191 error('A context consumer was rendered with multiple children, or a child ' + "that isn't a function. A context consumer expects a single child " + 'that is a function. If you did pass a function, make sure there ' + 'is no trailing or leading whitespace around it.');
21192 }
21193 }
21194
21195 prepareToReadContext(workInProgress, renderLanes);
21196 var newValue = readContext(context);
21197
21198 {
21199 markComponentRenderStarted(workInProgress);
21200 }
21201
21202 var newChildren;
21203
21204 {
21205 ReactCurrentOwner$1.current = workInProgress;
21206 setIsRendering(true);
21207 newChildren = render(newValue);
21208 setIsRendering(false);
21209 }
21210
21211 {
21212 markComponentRenderStopped();
21213 } // React DevTools reads this flag.
21214
21215
21216 workInProgress.flags |= PerformedWork;
21217 reconcileChildren(current, workInProgress, newChildren, renderLanes);
21218 return workInProgress.child;
21219}
21220
21221function markWorkInProgressReceivedUpdate() {
21222 didReceiveUpdate = true;
21223}
21224
21225function resetSuspendedCurrentOnMountInLegacyMode(current, workInProgress) {
21226 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
21227 if (current !== null) {
21228 // A lazy component only mounts if it suspended inside a non-
21229 // concurrent tree, in an inconsistent state. We want to treat it like
21230 // a new mount, even though an empty version of it already committed.
21231 // Disconnect the alternate pointers.
21232 current.alternate = null;
21233 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
21234
21235 workInProgress.flags |= Placement;
21236 }
21237 }
21238}
21239
21240function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
21241 if (current !== null) {
21242 // Reuse previous dependencies
21243 workInProgress.dependencies = current.dependencies;
21244 }
21245
21246 {
21247 // Don't update "base" render times for bailouts.
21248 stopProfilerTimerIfRunning();
21249 }
21250
21251 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
21252
21253 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) {
21254 // The children don't have any work either. We can skip them.
21255 // TODO: Once we add back resuming, we should check if the children are
21256 // a work-in-progress set. If so, we need to transfer their effects.
21257 {
21258 return null;
21259 }
21260 } // This fiber doesn't have work, but its subtree does. Clone the child
21261 // fibers and continue.
21262
21263
21264 cloneChildFibers(current, workInProgress);
21265 return workInProgress.child;
21266}
21267
21268function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
21269 {
21270 var returnFiber = oldWorkInProgress.return;
21271
21272 if (returnFiber === null) {
21273 // eslint-disable-next-line react-internal/prod-error-codes
21274 throw new Error('Cannot swap the root fiber.');
21275 } // Disconnect from the old current.
21276 // It will get deleted.
21277
21278
21279 current.alternate = null;
21280 oldWorkInProgress.alternate = null; // Connect to the new tree.
21281
21282 newWorkInProgress.index = oldWorkInProgress.index;
21283 newWorkInProgress.sibling = oldWorkInProgress.sibling;
21284 newWorkInProgress.return = oldWorkInProgress.return;
21285 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
21286
21287 if (oldWorkInProgress === returnFiber.child) {
21288 returnFiber.child = newWorkInProgress;
21289 } else {
21290 var prevSibling = returnFiber.child;
21291
21292 if (prevSibling === null) {
21293 // eslint-disable-next-line react-internal/prod-error-codes
21294 throw new Error('Expected parent to have a child.');
21295 }
21296
21297 while (prevSibling.sibling !== oldWorkInProgress) {
21298 prevSibling = prevSibling.sibling;
21299
21300 if (prevSibling === null) {
21301 // eslint-disable-next-line react-internal/prod-error-codes
21302 throw new Error('Expected to find the previous sibling.');
21303 }
21304 }
21305
21306 prevSibling.sibling = newWorkInProgress;
21307 } // Delete the old fiber and place the new one.
21308 // Since the old fiber is disconnected, we have to schedule it manually.
21309
21310
21311 var deletions = returnFiber.deletions;
21312
21313 if (deletions === null) {
21314 returnFiber.deletions = [current];
21315 returnFiber.flags |= ChildDeletion;
21316 } else {
21317 deletions.push(current);
21318 }
21319
21320 newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
21321
21322 return newWorkInProgress;
21323 }
21324}
21325
21326function checkScheduledUpdateOrContext(current, renderLanes) {
21327 // Before performing an early bailout, we must check if there are pending
21328 // updates or context.
21329 var updateLanes = current.lanes;
21330
21331 if (includesSomeLane(updateLanes, renderLanes)) {
21332 return true;
21333 } // No pending update, but because context is propagated lazily, we need
21334
21335 return false;
21336}
21337
21338function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) {
21339 // This fiber does not have any pending work. Bailout without entering
21340 // the begin phase. There's still some bookkeeping we that needs to be done
21341 // in this optimized path, mostly pushing stuff onto the stack.
21342 switch (workInProgress.tag) {
21343 case HostRoot:
21344 pushHostRootContext(workInProgress);
21345 var root = workInProgress.stateNode;
21346
21347 resetHydrationState();
21348 break;
21349
21350 case HostComponent:
21351 pushHostContext(workInProgress);
21352 break;
21353
21354 case ClassComponent:
21355 {
21356 var Component = workInProgress.type;
21357
21358 if (isContextProvider(Component)) {
21359 pushContextProvider(workInProgress);
21360 }
21361
21362 break;
21363 }
21364
21365 case HostPortal:
21366 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
21367 break;
21368
21369 case ContextProvider:
21370 {
21371 var newValue = workInProgress.memoizedProps.value;
21372 var context = workInProgress.type._context;
21373 pushProvider(workInProgress, context, newValue);
21374 break;
21375 }
21376
21377 case Profiler:
21378 {
21379 // Profiler should only call onRender when one of its descendants actually rendered.
21380 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
21381
21382 if (hasChildWork) {
21383 workInProgress.flags |= Update;
21384 }
21385
21386 {
21387 // Reset effect durations for the next eventual effect phase.
21388 // These are reset during render to allow the DevTools commit hook a chance to read them,
21389 var stateNode = workInProgress.stateNode;
21390 stateNode.effectDuration = 0;
21391 stateNode.passiveEffectDuration = 0;
21392 }
21393 }
21394
21395 break;
21396
21397 case SuspenseComponent:
21398 {
21399 var state = workInProgress.memoizedState;
21400
21401 if (state !== null) {
21402 if (state.dehydrated !== null) {
21403 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has
21404 // been unsuspended it has committed as a resolved Suspense component.
21405 // If it needs to be retried, it should have work scheduled on it.
21406
21407 workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we
21408 // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork.
21409
21410 return null;
21411 } // If this boundary is currently timed out, we need to decide
21412 // whether to retry the primary children, or to skip over it and
21413 // go straight to the fallback. Check the priority of the primary
21414 // child fragment.
21415
21416
21417 var primaryChildFragment = workInProgress.child;
21418 var primaryChildLanes = primaryChildFragment.childLanes;
21419
21420 if (includesSomeLane(renderLanes, primaryChildLanes)) {
21421 // The primary children have pending work. Use the normal path
21422 // to attempt to render the primary children again.
21423 return updateSuspenseComponent(current, workInProgress, renderLanes);
21424 } else {
21425 // The primary child fragment does not have pending work marked
21426 // on it
21427 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
21428 // priority. Bailout.
21429
21430 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21431
21432 if (child !== null) {
21433 // The fallback children have pending work. Skip over the
21434 // primary children and work on the fallback.
21435 return child.sibling;
21436 } else {
21437 // Note: We can return `null` here because we already checked
21438 // whether there were nested context consumers, via the call to
21439 // `bailoutOnAlreadyFinishedWork` above.
21440 return null;
21441 }
21442 }
21443 } else {
21444 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
21445 }
21446
21447 break;
21448 }
21449
21450 case SuspenseListComponent:
21451 {
21452 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags;
21453
21454 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
21455
21456 if (didSuspendBefore) {
21457 if (_hasChildWork) {
21458 // If something was in fallback state last time, and we have all the
21459 // same children then we're still in progressive loading state.
21460 // Something might get unblocked by state updates or retries in the
21461 // tree which will affect the tail. So we need to use the normal
21462 // path to compute the correct tail.
21463 return updateSuspenseListComponent(current, workInProgress, renderLanes);
21464 } // If none of the children had any work, that means that none of
21465 // them got retried so they'll still be blocked in the same way
21466 // as before. We can fast bail out.
21467
21468
21469 workInProgress.flags |= DidCapture;
21470 } // If nothing suspended before and we're rendering the same children,
21471 // then the tail doesn't matter. Anything new that suspends will work
21472 // in the "together" mode, so we can continue from the state we had.
21473
21474
21475 var renderState = workInProgress.memoizedState;
21476
21477 if (renderState !== null) {
21478 // Reset to the "together" mode in case we've started a different
21479 // update in the past but didn't complete it.
21480 renderState.rendering = null;
21481 renderState.tail = null;
21482 renderState.lastEffect = null;
21483 }
21484
21485 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
21486
21487 if (_hasChildWork) {
21488 break;
21489 } else {
21490 // If none of the children had any work, that means that none of
21491 // them got retried so they'll still be blocked in the same way
21492 // as before. We can fast bail out.
21493 return null;
21494 }
21495 }
21496
21497 case OffscreenComponent:
21498 case LegacyHiddenComponent:
21499 {
21500 // Need to check if the tree still needs to be deferred. This is
21501 // almost identical to the logic used in the normal update path,
21502 // so we'll just enter that. The only difference is we'll bail out
21503 // at the next level instead of this one, because the child props
21504 // have not changed. Which is fine.
21505 // TODO: Probably should refactor `beginWork` to split the bailout
21506 // path from the normal path. I'm tempted to do a labeled break here
21507 // but I won't :)
21508 workInProgress.lanes = NoLanes;
21509 return updateOffscreenComponent(current, workInProgress, renderLanes);
21510 }
21511 }
21512
21513 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21514}
21515
21516function beginWork(current, workInProgress, renderLanes) {
21517 {
21518 if (workInProgress._debugNeedsRemount && current !== null) {
21519 // This will restart the begin phase with a new fiber.
21520 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
21521 }
21522 }
21523
21524 if (current !== null) {
21525 var oldProps = current.memoizedProps;
21526 var newProps = workInProgress.pendingProps;
21527
21528 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
21529 workInProgress.type !== current.type )) {
21530 // If props or context changed, mark the fiber as having performed work.
21531 // This may be unset if the props are determined to be equal later (memo).
21532 didReceiveUpdate = true;
21533 } else {
21534 // Neither props nor legacy context changes. Check if there's a pending
21535 // update or context change.
21536 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
21537
21538 if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there
21539 // may not be work scheduled on `current`, so we check for this flag.
21540 (workInProgress.flags & DidCapture) === NoFlags) {
21541 // No pending updates or context. Bail out now.
21542 didReceiveUpdate = false;
21543 return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes);
21544 }
21545
21546 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
21547 // This is a special case that only exists for legacy mode.
21548 // See https://github.com/facebook/react/pull/19216.
21549 didReceiveUpdate = true;
21550 } else {
21551 // An update was scheduled on this fiber, but there are no new props
21552 // nor legacy context. Set this to false. If an update queue or context
21553 // consumer produces a changed value, it will set this to true. Otherwise,
21554 // the component will assume the children have not changed and bail out.
21555 didReceiveUpdate = false;
21556 }
21557 }
21558 } else {
21559 didReceiveUpdate = false;
21560
21561 if (getIsHydrating() && isForkedChild(workInProgress)) {
21562 // Check if this child belongs to a list of muliple children in
21563 // its parent.
21564 //
21565 // In a true multi-threaded implementation, we would render children on
21566 // parallel threads. This would represent the beginning of a new render
21567 // thread for this subtree.
21568 //
21569 // We only use this for id generation during hydration, which is why the
21570 // logic is located in this special branch.
21571 var slotIndex = workInProgress.index;
21572 var numberOfForks = getForksAtLevel();
21573 pushTreeId(workInProgress, numberOfForks, slotIndex);
21574 }
21575 } // Before entering the begin phase, clear pending update priority.
21576 // TODO: This assumes that we're about to evaluate the component and process
21577 // the update queue. However, there's an exception: SimpleMemoComponent
21578 // sometimes bails out later in the begin phase. This indicates that we should
21579 // move this assignment out of the common path and into each branch.
21580
21581
21582 workInProgress.lanes = NoLanes;
21583
21584 switch (workInProgress.tag) {
21585 case IndeterminateComponent:
21586 {
21587 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes);
21588 }
21589
21590 case LazyComponent:
21591 {
21592 var elementType = workInProgress.elementType;
21593 return mountLazyComponent(current, workInProgress, elementType, renderLanes);
21594 }
21595
21596 case FunctionComponent:
21597 {
21598 var Component = workInProgress.type;
21599 var unresolvedProps = workInProgress.pendingProps;
21600 var resolvedProps = workInProgress.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps);
21601 return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes);
21602 }
21603
21604 case ClassComponent:
21605 {
21606 var _Component = workInProgress.type;
21607 var _unresolvedProps = workInProgress.pendingProps;
21608
21609 var _resolvedProps = workInProgress.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps);
21610
21611 return updateClassComponent(current, workInProgress, _Component, _resolvedProps, renderLanes);
21612 }
21613
21614 case HostRoot:
21615 return updateHostRoot(current, workInProgress, renderLanes);
21616
21617 case HostComponent:
21618 return updateHostComponent(current, workInProgress, renderLanes);
21619
21620 case HostText:
21621 return updateHostText(current, workInProgress);
21622
21623 case SuspenseComponent:
21624 return updateSuspenseComponent(current, workInProgress, renderLanes);
21625
21626 case HostPortal:
21627 return updatePortalComponent(current, workInProgress, renderLanes);
21628
21629 case ForwardRef:
21630 {
21631 var type = workInProgress.type;
21632 var _unresolvedProps2 = workInProgress.pendingProps;
21633
21634 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
21635
21636 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);
21637 }
21638
21639 case Fragment:
21640 return updateFragment(current, workInProgress, renderLanes);
21641
21642 case Mode:
21643 return updateMode(current, workInProgress, renderLanes);
21644
21645 case Profiler:
21646 return updateProfiler(current, workInProgress, renderLanes);
21647
21648 case ContextProvider:
21649 return updateContextProvider(current, workInProgress, renderLanes);
21650
21651 case ContextConsumer:
21652 return updateContextConsumer(current, workInProgress, renderLanes);
21653
21654 case MemoComponent:
21655 {
21656 var _type2 = workInProgress.type;
21657 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
21658
21659 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
21660
21661 {
21662 if (workInProgress.type !== workInProgress.elementType) {
21663 var outerPropTypes = _type2.propTypes;
21664
21665 if (outerPropTypes) {
21666 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
21667 'prop', getComponentNameFromType(_type2));
21668 }
21669 }
21670 }
21671
21672 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
21673 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, renderLanes);
21674 }
21675
21676 case SimpleMemoComponent:
21677 {
21678 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes);
21679 }
21680
21681 case IncompleteClassComponent:
21682 {
21683 var _Component2 = workInProgress.type;
21684 var _unresolvedProps4 = workInProgress.pendingProps;
21685
21686 var _resolvedProps4 = workInProgress.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4);
21687
21688 return mountIncompleteClassComponent(current, workInProgress, _Component2, _resolvedProps4, renderLanes);
21689 }
21690
21691 case SuspenseListComponent:
21692 {
21693 return updateSuspenseListComponent(current, workInProgress, renderLanes);
21694 }
21695
21696 case ScopeComponent:
21697 {
21698
21699 break;
21700 }
21701
21702 case OffscreenComponent:
21703 {
21704 return updateOffscreenComponent(current, workInProgress, renderLanes);
21705 }
21706 }
21707
21708 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
21709}
21710
21711function markUpdate(workInProgress) {
21712 // Tag the fiber with an update effect. This turns a Placement into
21713 // a PlacementAndUpdate.
21714 workInProgress.flags |= Update;
21715}
21716
21717function markRef$1(workInProgress) {
21718 workInProgress.flags |= Ref;
21719
21720 {
21721 workInProgress.flags |= RefStatic;
21722 }
21723}
21724
21725var appendAllChildren;
21726var updateHostContainer;
21727var updateHostComponent$1;
21728var updateHostText$1;
21729
21730{
21731 // Mutation mode
21732 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
21733 // We only have the top Fiber that was created but we need recurse down its
21734 // children to find all the terminal nodes.
21735 var node = workInProgress.child;
21736
21737 while (node !== null) {
21738 if (node.tag === HostComponent || node.tag === HostText) {
21739 appendInitialChild(parent, node.stateNode);
21740 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
21741 node.child.return = node;
21742 node = node.child;
21743 continue;
21744 }
21745
21746 if (node === workInProgress) {
21747 return;
21748 }
21749
21750 while (node.sibling === null) {
21751 if (node.return === null || node.return === workInProgress) {
21752 return;
21753 }
21754
21755 node = node.return;
21756 }
21757
21758 node.sibling.return = node.return;
21759 node = node.sibling;
21760 }
21761 };
21762
21763 updateHostContainer = function (current, workInProgress) {// Noop
21764 };
21765
21766 updateHostComponent$1 = function (current, workInProgress, type, newProps, rootContainerInstance) {
21767 // If we have an alternate, that means this is an update and we need to
21768 // schedule a side-effect to do the updates.
21769 var oldProps = current.memoizedProps;
21770
21771 if (oldProps === newProps) {
21772 // In mutation mode, this is sufficient for a bailout because
21773 // we won't touch this node even if children changed.
21774 return;
21775 } // If we get updated because one of our children updated, we don't
21776 // have newProps so we'll have to reuse them.
21777 // TODO: Split the update API as separate for the props vs. children.
21778 // Even better would be if children weren't special cased at all tho.
21779
21780
21781 var instance = workInProgress.stateNode;
21782 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
21783 // component is hitting the resume path. Figure out why. Possibly
21784 // related to `hidden`.
21785
21786 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
21787
21788 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
21789 // is a new ref we mark this as an update. All the work is done in commitWork.
21790
21791 if (updatePayload) {
21792 markUpdate(workInProgress);
21793 }
21794 };
21795
21796 updateHostText$1 = function (current, workInProgress, oldText, newText) {
21797 // If the text differs, mark it as an update. All the work in done in commitWork.
21798 if (oldText !== newText) {
21799 markUpdate(workInProgress);
21800 }
21801 };
21802}
21803
21804function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
21805 if (getIsHydrating()) {
21806 // If we're hydrating, we should consume as many items as we can
21807 // so we don't leave any behind.
21808 return;
21809 }
21810
21811 switch (renderState.tailMode) {
21812 case 'hidden':
21813 {
21814 // Any insertions at the end of the tail list after this point
21815 // should be invisible. If there are already mounted boundaries
21816 // anything before them are not considered for collapsing.
21817 // Therefore we need to go through the whole tail to find if
21818 // there are any.
21819 var tailNode = renderState.tail;
21820 var lastTailNode = null;
21821
21822 while (tailNode !== null) {
21823 if (tailNode.alternate !== null) {
21824 lastTailNode = tailNode;
21825 }
21826
21827 tailNode = tailNode.sibling;
21828 } // Next we're simply going to delete all insertions after the
21829 // last rendered item.
21830
21831
21832 if (lastTailNode === null) {
21833 // All remaining items in the tail are insertions.
21834 renderState.tail = null;
21835 } else {
21836 // Detach the insertion after the last node that was already
21837 // inserted.
21838 lastTailNode.sibling = null;
21839 }
21840
21841 break;
21842 }
21843
21844 case 'collapsed':
21845 {
21846 // Any insertions at the end of the tail list after this point
21847 // should be invisible. If there are already mounted boundaries
21848 // anything before them are not considered for collapsing.
21849 // Therefore we need to go through the whole tail to find if
21850 // there are any.
21851 var _tailNode = renderState.tail;
21852 var _lastTailNode = null;
21853
21854 while (_tailNode !== null) {
21855 if (_tailNode.alternate !== null) {
21856 _lastTailNode = _tailNode;
21857 }
21858
21859 _tailNode = _tailNode.sibling;
21860 } // Next we're simply going to delete all insertions after the
21861 // last rendered item.
21862
21863
21864 if (_lastTailNode === null) {
21865 // All remaining items in the tail are insertions.
21866 if (!hasRenderedATailFallback && renderState.tail !== null) {
21867 // We suspended during the head. We want to show at least one
21868 // row at the tail. So we'll keep on and cut off the rest.
21869 renderState.tail.sibling = null;
21870 } else {
21871 renderState.tail = null;
21872 }
21873 } else {
21874 // Detach the insertion after the last node that was already
21875 // inserted.
21876 _lastTailNode.sibling = null;
21877 }
21878
21879 break;
21880 }
21881 }
21882}
21883
21884function bubbleProperties(completedWork) {
21885 var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
21886 var newChildLanes = NoLanes;
21887 var subtreeFlags = NoFlags;
21888
21889 if (!didBailout) {
21890 // Bubble up the earliest expiration time.
21891 if ( (completedWork.mode & ProfileMode) !== NoMode) {
21892 // In profiling mode, resetChildExpirationTime is also used to reset
21893 // profiler durations.
21894 var actualDuration = completedWork.actualDuration;
21895 var treeBaseDuration = completedWork.selfBaseDuration;
21896 var child = completedWork.child;
21897
21898 while (child !== null) {
21899 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
21900 subtreeFlags |= child.subtreeFlags;
21901 subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will
21902 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
21903 // When work is done, it should bubble to the parent's actualDuration. If
21904 // the fiber has not been cloned though, (meaning no work was done), then
21905 // this value will reflect the amount of time spent working on a previous
21906 // render. In that case it should not bubble. We determine whether it was
21907 // cloned by comparing the child pointer.
21908
21909 actualDuration += child.actualDuration;
21910 treeBaseDuration += child.treeBaseDuration;
21911 child = child.sibling;
21912 }
21913
21914 completedWork.actualDuration = actualDuration;
21915 completedWork.treeBaseDuration = treeBaseDuration;
21916 } else {
21917 var _child = completedWork.child;
21918
21919 while (_child !== null) {
21920 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
21921 subtreeFlags |= _child.subtreeFlags;
21922 subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code
21923 // smell because it assumes the commit phase is never concurrent with
21924 // the render phase. Will address during refactor to alternate model.
21925
21926 _child.return = completedWork;
21927 _child = _child.sibling;
21928 }
21929 }
21930
21931 completedWork.subtreeFlags |= subtreeFlags;
21932 } else {
21933 // Bubble up the earliest expiration time.
21934 if ( (completedWork.mode & ProfileMode) !== NoMode) {
21935 // In profiling mode, resetChildExpirationTime is also used to reset
21936 // profiler durations.
21937 var _treeBaseDuration = completedWork.selfBaseDuration;
21938 var _child2 = completedWork.child;
21939
21940 while (_child2 !== null) {
21941 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
21942 // so we should bubble those up even during a bailout. All the other
21943 // flags have a lifetime only of a single render + commit, so we should
21944 // ignore them.
21945
21946 subtreeFlags |= _child2.subtreeFlags & StaticMask;
21947 subtreeFlags |= _child2.flags & StaticMask;
21948 _treeBaseDuration += _child2.treeBaseDuration;
21949 _child2 = _child2.sibling;
21950 }
21951
21952 completedWork.treeBaseDuration = _treeBaseDuration;
21953 } else {
21954 var _child3 = completedWork.child;
21955
21956 while (_child3 !== null) {
21957 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
21958 // so we should bubble those up even during a bailout. All the other
21959 // flags have a lifetime only of a single render + commit, so we should
21960 // ignore them.
21961
21962 subtreeFlags |= _child3.subtreeFlags & StaticMask;
21963 subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code
21964 // smell because it assumes the commit phase is never concurrent with
21965 // the render phase. Will address during refactor to alternate model.
21966
21967 _child3.return = completedWork;
21968 _child3 = _child3.sibling;
21969 }
21970 }
21971
21972 completedWork.subtreeFlags |= subtreeFlags;
21973 }
21974
21975 completedWork.childLanes = newChildLanes;
21976 return didBailout;
21977}
21978
21979function completeDehydratedSuspenseBoundary(current, workInProgress, nextState) {
21980 if (hasUnhydratedTailNodes() && (workInProgress.mode & ConcurrentMode) !== NoMode && (workInProgress.flags & DidCapture) === NoFlags) {
21981 warnIfUnhydratedTailNodes(workInProgress);
21982 resetHydrationState();
21983 workInProgress.flags |= ForceClientRender | Incomplete | ShouldCapture;
21984 return false;
21985 }
21986
21987 var wasHydrated = popHydrationState(workInProgress);
21988
21989 if (nextState !== null && nextState.dehydrated !== null) {
21990 // We might be inside a hydration state the first time we're picking up this
21991 // Suspense boundary, and also after we've reentered it for further hydration.
21992 if (current === null) {
21993 if (!wasHydrated) {
21994 throw new Error('A dehydrated suspense component was completed without a hydrated node. ' + 'This is probably a bug in React.');
21995 }
21996
21997 prepareToHydrateHostSuspenseInstance(workInProgress);
21998 bubbleProperties(workInProgress);
21999
22000 {
22001 if ((workInProgress.mode & ProfileMode) !== NoMode) {
22002 var isTimedOutSuspense = nextState !== null;
22003
22004 if (isTimedOutSuspense) {
22005 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22006 var primaryChildFragment = workInProgress.child;
22007
22008 if (primaryChildFragment !== null) {
22009 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
22010 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
22011 }
22012 }
22013 }
22014 }
22015
22016 return false;
22017 } else {
22018 // We might have reentered this boundary to hydrate it. If so, we need to reset the hydration
22019 // state since we're now exiting out of it. popHydrationState doesn't do that for us.
22020 resetHydrationState();
22021
22022 if ((workInProgress.flags & DidCapture) === NoFlags) {
22023 // This boundary did not suspend so it's now hydrated and unsuspended.
22024 workInProgress.memoizedState = null;
22025 } // If nothing suspended, we need to schedule an effect to mark this boundary
22026 // as having hydrated so events know that they're free to be invoked.
22027 // It's also a signal to replay events and the suspense callback.
22028 // If something suspended, schedule an effect to attach retry listeners.
22029 // So we might as well always mark this.
22030
22031
22032 workInProgress.flags |= Update;
22033 bubbleProperties(workInProgress);
22034
22035 {
22036 if ((workInProgress.mode & ProfileMode) !== NoMode) {
22037 var _isTimedOutSuspense = nextState !== null;
22038
22039 if (_isTimedOutSuspense) {
22040 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22041 var _primaryChildFragment = workInProgress.child;
22042
22043 if (_primaryChildFragment !== null) {
22044 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
22045 workInProgress.treeBaseDuration -= _primaryChildFragment.treeBaseDuration;
22046 }
22047 }
22048 }
22049 }
22050
22051 return false;
22052 }
22053 } else {
22054 // Successfully completed this tree. If this was a forced client render,
22055 // there may have been recoverable errors during first hydration
22056 // attempt. If so, add them to a queue so we can log them in the
22057 // commit phase.
22058 upgradeHydrationErrorsToRecoverable(); // Fall through to normal Suspense path
22059
22060 return true;
22061 }
22062}
22063
22064function completeWork(current, workInProgress, renderLanes) {
22065 var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing
22066 // to the current tree provider fiber is just as fast and less error-prone.
22067 // Ideally we would have a special version of the work loop only
22068 // for hydration.
22069
22070 popTreeContext(workInProgress);
22071
22072 switch (workInProgress.tag) {
22073 case IndeterminateComponent:
22074 case LazyComponent:
22075 case SimpleMemoComponent:
22076 case FunctionComponent:
22077 case ForwardRef:
22078 case Fragment:
22079 case Mode:
22080 case Profiler:
22081 case ContextConsumer:
22082 case MemoComponent:
22083 bubbleProperties(workInProgress);
22084 return null;
22085
22086 case ClassComponent:
22087 {
22088 var Component = workInProgress.type;
22089
22090 if (isContextProvider(Component)) {
22091 popContext(workInProgress);
22092 }
22093
22094 bubbleProperties(workInProgress);
22095 return null;
22096 }
22097
22098 case HostRoot:
22099 {
22100 var fiberRoot = workInProgress.stateNode;
22101 popHostContainer(workInProgress);
22102 popTopLevelContextObject(workInProgress);
22103 resetWorkInProgressVersions();
22104
22105 if (fiberRoot.pendingContext) {
22106 fiberRoot.context = fiberRoot.pendingContext;
22107 fiberRoot.pendingContext = null;
22108 }
22109
22110 if (current === null || current.child === null) {
22111 // If we hydrated, pop so that we can delete any remaining children
22112 // that weren't hydrated.
22113 var wasHydrated = popHydrationState(workInProgress);
22114
22115 if (wasHydrated) {
22116 // If we hydrated, then we'll need to schedule an update for
22117 // the commit side-effects on the root.
22118 markUpdate(workInProgress);
22119 } else {
22120 if (current !== null) {
22121 var prevState = current.memoizedState;
22122
22123 if ( // Check if this is a client root
22124 !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error)
22125 (workInProgress.flags & ForceClientRender) !== NoFlags) {
22126 // Schedule an effect to clear this container at the start of the
22127 // next commit. This handles the case of React rendering into a
22128 // container with previous children. It's also safe to do for
22129 // updates too, because current.child would only be null if the
22130 // previous render was null (so the container would already
22131 // be empty).
22132 workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been
22133 // recoverable errors during first hydration attempt. If so, add
22134 // them to a queue so we can log them in the commit phase.
22135
22136 upgradeHydrationErrorsToRecoverable();
22137 }
22138 }
22139 }
22140 }
22141
22142 updateHostContainer(current, workInProgress);
22143 bubbleProperties(workInProgress);
22144
22145 return null;
22146 }
22147
22148 case HostComponent:
22149 {
22150 popHostContext(workInProgress);
22151 var rootContainerInstance = getRootHostContainer();
22152 var type = workInProgress.type;
22153
22154 if (current !== null && workInProgress.stateNode != null) {
22155 updateHostComponent$1(current, workInProgress, type, newProps, rootContainerInstance);
22156
22157 if (current.ref !== workInProgress.ref) {
22158 markRef$1(workInProgress);
22159 }
22160 } else {
22161 if (!newProps) {
22162 if (workInProgress.stateNode === null) {
22163 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
22164 } // This can happen when we abort work.
22165
22166
22167 bubbleProperties(workInProgress);
22168 return null;
22169 }
22170
22171 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
22172 // "stack" as the parent. Then append children as we go in beginWork
22173 // or completeWork depending on whether we want to add them top->down or
22174 // bottom->up. Top->down is faster in IE11.
22175
22176 var _wasHydrated = popHydrationState(workInProgress);
22177
22178 if (_wasHydrated) {
22179 // TODO: Move this and createInstance step into the beginPhase
22180 // to consolidate.
22181 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
22182 // If changes to the hydrated node need to be applied at the
22183 // commit-phase we mark this as such.
22184 markUpdate(workInProgress);
22185 }
22186 } else {
22187 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
22188 appendAllChildren(instance, workInProgress, false, false);
22189 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount.
22190 // (eg DOM renderer supports auto-focus for certain elements).
22191 // Make sure such renderers get scheduled for later work.
22192
22193 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
22194 markUpdate(workInProgress);
22195 }
22196 }
22197
22198 if (workInProgress.ref !== null) {
22199 // If there is a ref on a host node we need to schedule a callback
22200 markRef$1(workInProgress);
22201 }
22202 }
22203
22204 bubbleProperties(workInProgress);
22205 return null;
22206 }
22207
22208 case HostText:
22209 {
22210 var newText = newProps;
22211
22212 if (current && workInProgress.stateNode != null) {
22213 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
22214 // to schedule a side-effect to do the updates.
22215
22216 updateHostText$1(current, workInProgress, oldText, newText);
22217 } else {
22218 if (typeof newText !== 'string') {
22219 if (workInProgress.stateNode === null) {
22220 throw new Error('We must have new props for new mounts. This error is likely ' + 'caused by a bug in React. Please file an issue.');
22221 } // This can happen when we abort work.
22222
22223 }
22224
22225 var _rootContainerInstance = getRootHostContainer();
22226
22227 var _currentHostContext = getHostContext();
22228
22229 var _wasHydrated2 = popHydrationState(workInProgress);
22230
22231 if (_wasHydrated2) {
22232 if (prepareToHydrateHostTextInstance(workInProgress)) {
22233 markUpdate(workInProgress);
22234 }
22235 } else {
22236 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
22237 }
22238 }
22239
22240 bubbleProperties(workInProgress);
22241 return null;
22242 }
22243
22244 case SuspenseComponent:
22245 {
22246 popSuspenseContext(workInProgress);
22247 var nextState = workInProgress.memoizedState; // Special path for dehydrated boundaries. We may eventually move this
22248 // to its own fiber type so that we can add other kinds of hydration
22249 // boundaries that aren't associated with a Suspense tree. In anticipation
22250 // of such a refactor, all the hydration logic is contained in
22251 // this branch.
22252
22253 if (current === null || current.memoizedState !== null && current.memoizedState.dehydrated !== null) {
22254 var fallthroughToNormalSuspensePath = completeDehydratedSuspenseBoundary(current, workInProgress, nextState);
22255
22256 if (!fallthroughToNormalSuspensePath) {
22257 if (workInProgress.flags & ShouldCapture) {
22258 // Special case. There were remaining unhydrated nodes. We treat
22259 // this as a mismatch. Revert to client rendering.
22260 return workInProgress;
22261 } else {
22262 // Did not finish hydrating, either because this is the initial
22263 // render or because something suspended.
22264 return null;
22265 }
22266 } // Continue with the normal Suspense path.
22267
22268 }
22269
22270 if ((workInProgress.flags & DidCapture) !== NoFlags) {
22271 // Something suspended. Re-render with the fallback children.
22272 workInProgress.lanes = renderLanes; // Do not reset the effect list.
22273
22274 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22275 transferActualDuration(workInProgress);
22276 } // Don't bubble properties in this case.
22277
22278
22279 return workInProgress;
22280 }
22281
22282 var nextDidTimeout = nextState !== null;
22283 var prevDidTimeout = current !== null && current.memoizedState !== null;
22284 // a passive effect, which is when we process the transitions
22285
22286
22287 if (nextDidTimeout !== prevDidTimeout) {
22288 // an effect to toggle the subtree's visibility. When we switch from
22289 // fallback -> primary, the inner Offscreen fiber schedules this effect
22290 // as part of its normal complete phase. But when we switch from
22291 // primary -> fallback, the inner Offscreen fiber does not have a complete
22292 // phase. So we need to schedule its effect here.
22293 //
22294 // We also use this flag to connect/disconnect the effects, but the same
22295 // logic applies: when re-connecting, the Offscreen fiber's complete
22296 // phase will handle scheduling the effect. It's only when the fallback
22297 // is active that we have to do anything special.
22298
22299
22300 if (nextDidTimeout) {
22301 var _offscreenFiber2 = workInProgress.child;
22302 _offscreenFiber2.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything
22303 // in the concurrent tree already suspended during this render.
22304 // This is a known bug.
22305
22306 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
22307 // TODO: Move this back to throwException because this is too late
22308 // if this is a large tree which is common for initial loads. We
22309 // don't know if we should restart a render or not until we get
22310 // this marker, and this is too late.
22311 // If this render already had a ping or lower pri updates,
22312 // and this is the first time we know we're going to suspend we
22313 // should be able to immediately restart from within throwException.
22314 var hasInvisibleChildContext = current === null && (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback);
22315
22316 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
22317 // If this was in an invisible tree or a new render, then showing
22318 // this boundary is ok.
22319 renderDidSuspend();
22320 } else {
22321 // Otherwise, we're going to have to hide content so we should
22322 // suspend for longer if possible.
22323 renderDidSuspendDelayIfPossible();
22324 }
22325 }
22326 }
22327 }
22328
22329 var wakeables = workInProgress.updateQueue;
22330
22331 if (wakeables !== null) {
22332 // Schedule an effect to attach a retry listener to the promise.
22333 // TODO: Move to passive phase
22334 workInProgress.flags |= Update;
22335 }
22336
22337 bubbleProperties(workInProgress);
22338
22339 {
22340 if ((workInProgress.mode & ProfileMode) !== NoMode) {
22341 if (nextDidTimeout) {
22342 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
22343 var primaryChildFragment = workInProgress.child;
22344
22345 if (primaryChildFragment !== null) {
22346 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
22347 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
22348 }
22349 }
22350 }
22351 }
22352
22353 return null;
22354 }
22355
22356 case HostPortal:
22357 popHostContainer(workInProgress);
22358 updateHostContainer(current, workInProgress);
22359
22360 if (current === null) {
22361 preparePortalMount(workInProgress.stateNode.containerInfo);
22362 }
22363
22364 bubbleProperties(workInProgress);
22365 return null;
22366
22367 case ContextProvider:
22368 // Pop provider fiber
22369 var context = workInProgress.type._context;
22370 popProvider(context, workInProgress);
22371 bubbleProperties(workInProgress);
22372 return null;
22373
22374 case IncompleteClassComponent:
22375 {
22376 // Same as class component case. I put it down here so that the tags are
22377 // sequential to ensure this switch is compiled to a jump table.
22378 var _Component = workInProgress.type;
22379
22380 if (isContextProvider(_Component)) {
22381 popContext(workInProgress);
22382 }
22383
22384 bubbleProperties(workInProgress);
22385 return null;
22386 }
22387
22388 case SuspenseListComponent:
22389 {
22390 popSuspenseContext(workInProgress);
22391 var renderState = workInProgress.memoizedState;
22392
22393 if (renderState === null) {
22394 // We're running in the default, "independent" mode.
22395 // We don't do anything in this mode.
22396 bubbleProperties(workInProgress);
22397 return null;
22398 }
22399
22400 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags;
22401 var renderedTail = renderState.rendering;
22402
22403 if (renderedTail === null) {
22404 // We just rendered the head.
22405 if (!didSuspendAlready) {
22406 // This is the first pass. We need to figure out if anything is still
22407 // suspended in the rendered set.
22408 // If new content unsuspended, but there's still some content that
22409 // didn't. Then we need to do a second pass that forces everything
22410 // to keep showing their fallbacks.
22411 // We might be suspended if something in this render pass suspended, or
22412 // something in the previous committed pass suspended. Otherwise,
22413 // there's no chance so we can skip the expensive call to
22414 // findFirstSuspended.
22415 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags);
22416
22417 if (!cannotBeSuspended) {
22418 var row = workInProgress.child;
22419
22420 while (row !== null) {
22421 var suspended = findFirstSuspended(row);
22422
22423 if (suspended !== null) {
22424 didSuspendAlready = true;
22425 workInProgress.flags |= DidCapture;
22426 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
22427 // part of the second pass. In that case nothing will subscribe to
22428 // its thenables. Instead, we'll transfer its thenables to the
22429 // SuspenseList so that it can retry if they resolve.
22430 // There might be multiple of these in the list but since we're
22431 // going to wait for all of them anyway, it doesn't really matter
22432 // which ones gets to ping. In theory we could get clever and keep
22433 // track of how many dependencies remain but it gets tricky because
22434 // in the meantime, we can add/remove/change items and dependencies.
22435 // We might bail out of the loop before finding any but that
22436 // doesn't matter since that means that the other boundaries that
22437 // we did find already has their listeners attached.
22438
22439 var newThenables = suspended.updateQueue;
22440
22441 if (newThenables !== null) {
22442 workInProgress.updateQueue = newThenables;
22443 workInProgress.flags |= Update;
22444 } // Rerender the whole list, but this time, we'll force fallbacks
22445 // to stay in place.
22446 // Reset the effect flags before doing the second pass since that's now invalid.
22447 // Reset the child fibers to their original state.
22448
22449
22450 workInProgress.subtreeFlags = NoFlags;
22451 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
22452 // rerender the children.
22453
22454 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case.
22455
22456 return workInProgress.child;
22457 }
22458
22459 row = row.sibling;
22460 }
22461 }
22462
22463 if (renderState.tail !== null && now() > getRenderTargetTime()) {
22464 // We have already passed our CPU deadline but we still have rows
22465 // left in the tail. We'll just give up further attempts to render
22466 // the main content and only render fallbacks.
22467 workInProgress.flags |= DidCapture;
22468 didSuspendAlready = true;
22469 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
22470 // to get it started back up to attempt the next item. While in terms
22471 // of priority this work has the same priority as this current render,
22472 // it's not part of the same transition once the transition has
22473 // committed. If it's sync, we still want to yield so that it can be
22474 // painted. Conceptually, this is really the same as pinging.
22475 // We can use any RetryLane even if it's the one currently rendering
22476 // since we're leaving it behind on this node.
22477
22478 workInProgress.lanes = SomeRetryLane;
22479 }
22480 } else {
22481 cutOffTailIfNeeded(renderState, false);
22482 } // Next we're going to render the tail.
22483
22484 } else {
22485 // Append the rendered row to the child list.
22486 if (!didSuspendAlready) {
22487 var _suspended = findFirstSuspended(renderedTail);
22488
22489 if (_suspended !== null) {
22490 workInProgress.flags |= DidCapture;
22491 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
22492 // get lost if this row ends up dropped during a second pass.
22493
22494 var _newThenables = _suspended.updateQueue;
22495
22496 if (_newThenables !== null) {
22497 workInProgress.updateQueue = _newThenables;
22498 workInProgress.flags |= Update;
22499 }
22500
22501 cutOffTailIfNeeded(renderState, true); // This might have been modified.
22502
22503 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
22504 ) {
22505 // We're done.
22506 bubbleProperties(workInProgress);
22507 return null;
22508 }
22509 } else if ( // The time it took to render last row is greater than the remaining
22510 // time we have to render. So rendering one more row would likely
22511 // exceed it.
22512 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
22513 // We have now passed our CPU deadline and we'll just give up further
22514 // attempts to render the main content and only render fallbacks.
22515 // The assumption is that this is usually faster.
22516 workInProgress.flags |= DidCapture;
22517 didSuspendAlready = true;
22518 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
22519 // to get it started back up to attempt the next item. While in terms
22520 // of priority this work has the same priority as this current render,
22521 // it's not part of the same transition once the transition has
22522 // committed. If it's sync, we still want to yield so that it can be
22523 // painted. Conceptually, this is really the same as pinging.
22524 // We can use any RetryLane even if it's the one currently rendering
22525 // since we're leaving it behind on this node.
22526
22527 workInProgress.lanes = SomeRetryLane;
22528 }
22529 }
22530
22531 if (renderState.isBackwards) {
22532 // The effect list of the backwards tail will have been added
22533 // to the end. This breaks the guarantee that life-cycles fire in
22534 // sibling order but that isn't a strong guarantee promised by React.
22535 // Especially since these might also just pop in during future commits.
22536 // Append to the beginning of the list.
22537 renderedTail.sibling = workInProgress.child;
22538 workInProgress.child = renderedTail;
22539 } else {
22540 var previousSibling = renderState.last;
22541
22542 if (previousSibling !== null) {
22543 previousSibling.sibling = renderedTail;
22544 } else {
22545 workInProgress.child = renderedTail;
22546 }
22547
22548 renderState.last = renderedTail;
22549 }
22550 }
22551
22552 if (renderState.tail !== null) {
22553 // We still have tail rows to render.
22554 // Pop a row.
22555 var next = renderState.tail;
22556 renderState.rendering = next;
22557 renderState.tail = next.sibling;
22558 renderState.renderingStartTime = now();
22559 next.sibling = null; // Restore the context.
22560 // TODO: We can probably just avoid popping it instead and only
22561 // setting it the first time we go from not suspended to suspended.
22562
22563 var suspenseContext = suspenseStackCursor.current;
22564
22565 if (didSuspendAlready) {
22566 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
22567 } else {
22568 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
22569 }
22570
22571 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
22572 // Don't bubble properties in this case.
22573
22574 return next;
22575 }
22576
22577 bubbleProperties(workInProgress);
22578 return null;
22579 }
22580
22581 case ScopeComponent:
22582 {
22583
22584 break;
22585 }
22586
22587 case OffscreenComponent:
22588 case LegacyHiddenComponent:
22589 {
22590 popRenderLanes(workInProgress);
22591 var _nextState = workInProgress.memoizedState;
22592 var nextIsHidden = _nextState !== null;
22593
22594 if (current !== null) {
22595 var _prevState = current.memoizedState;
22596 var prevIsHidden = _prevState !== null;
22597
22598 if (prevIsHidden !== nextIsHidden && ( // LegacyHidden doesn't do any hiding — it only pre-renders.
22599 !enableLegacyHidden )) {
22600 workInProgress.flags |= Visibility;
22601 }
22602 }
22603
22604 if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) {
22605 bubbleProperties(workInProgress);
22606 } else {
22607 // Don't bubble properties for hidden children unless we're rendering
22608 // at offscreen priority.
22609 if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) {
22610 bubbleProperties(workInProgress);
22611
22612 {
22613 // Check if there was an insertion or update in the hidden subtree.
22614 // If so, we need to hide those nodes in the commit phase, so
22615 // schedule a visibility effect.
22616 if ( workInProgress.subtreeFlags & (Placement | Update)) {
22617 workInProgress.flags |= Visibility;
22618 }
22619 }
22620 }
22621 }
22622 return null;
22623 }
22624
22625 case CacheComponent:
22626 {
22627
22628 return null;
22629 }
22630
22631 case TracingMarkerComponent:
22632 {
22633
22634 return null;
22635 }
22636 }
22637
22638 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
22639}
22640
22641function unwindWork(current, workInProgress, renderLanes) {
22642 // Note: This intentionally doesn't check if we're hydrating because comparing
22643 // to the current tree provider fiber is just as fast and less error-prone.
22644 // Ideally we would have a special version of the work loop only
22645 // for hydration.
22646 popTreeContext(workInProgress);
22647
22648 switch (workInProgress.tag) {
22649 case ClassComponent:
22650 {
22651 var Component = workInProgress.type;
22652
22653 if (isContextProvider(Component)) {
22654 popContext(workInProgress);
22655 }
22656
22657 var flags = workInProgress.flags;
22658
22659 if (flags & ShouldCapture) {
22660 workInProgress.flags = flags & ~ShouldCapture | DidCapture;
22661
22662 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22663 transferActualDuration(workInProgress);
22664 }
22665
22666 return workInProgress;
22667 }
22668
22669 return null;
22670 }
22671
22672 case HostRoot:
22673 {
22674 var root = workInProgress.stateNode;
22675 popHostContainer(workInProgress);
22676 popTopLevelContextObject(workInProgress);
22677 resetWorkInProgressVersions();
22678 var _flags = workInProgress.flags;
22679
22680 if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) {
22681 // There was an error during render that wasn't captured by a suspense
22682 // boundary. Do a second pass on the root to unmount the children.
22683 workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
22684 return workInProgress;
22685 } // We unwound to the root without completing it. Exit.
22686
22687
22688 return null;
22689 }
22690
22691 case HostComponent:
22692 {
22693 // TODO: popHydrationState
22694 popHostContext(workInProgress);
22695 return null;
22696 }
22697
22698 case SuspenseComponent:
22699 {
22700 popSuspenseContext(workInProgress);
22701 var suspenseState = workInProgress.memoizedState;
22702
22703 if (suspenseState !== null && suspenseState.dehydrated !== null) {
22704 if (workInProgress.alternate === null) {
22705 throw new Error('Threw in newly mounted dehydrated component. This is likely a bug in ' + 'React. Please file an issue.');
22706 }
22707
22708 resetHydrationState();
22709 }
22710
22711 var _flags2 = workInProgress.flags;
22712
22713 if (_flags2 & ShouldCapture) {
22714 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
22715
22716 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22717 transferActualDuration(workInProgress);
22718 }
22719
22720 return workInProgress;
22721 }
22722
22723 return null;
22724 }
22725
22726 case SuspenseListComponent:
22727 {
22728 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
22729 // caught by a nested boundary. If not, it should bubble through.
22730
22731 return null;
22732 }
22733
22734 case HostPortal:
22735 popHostContainer(workInProgress);
22736 return null;
22737
22738 case ContextProvider:
22739 var context = workInProgress.type._context;
22740 popProvider(context, workInProgress);
22741 return null;
22742
22743 case OffscreenComponent:
22744 case LegacyHiddenComponent:
22745 popRenderLanes(workInProgress);
22746 return null;
22747
22748 case CacheComponent:
22749
22750 return null;
22751
22752 default:
22753 return null;
22754 }
22755}
22756
22757function unwindInterruptedWork(current, interruptedWork, renderLanes) {
22758 // Note: This intentionally doesn't check if we're hydrating because comparing
22759 // to the current tree provider fiber is just as fast and less error-prone.
22760 // Ideally we would have a special version of the work loop only
22761 // for hydration.
22762 popTreeContext(interruptedWork);
22763
22764 switch (interruptedWork.tag) {
22765 case ClassComponent:
22766 {
22767 var childContextTypes = interruptedWork.type.childContextTypes;
22768
22769 if (childContextTypes !== null && childContextTypes !== undefined) {
22770 popContext(interruptedWork);
22771 }
22772
22773 break;
22774 }
22775
22776 case HostRoot:
22777 {
22778 var root = interruptedWork.stateNode;
22779 popHostContainer(interruptedWork);
22780 popTopLevelContextObject(interruptedWork);
22781 resetWorkInProgressVersions();
22782 break;
22783 }
22784
22785 case HostComponent:
22786 {
22787 popHostContext(interruptedWork);
22788 break;
22789 }
22790
22791 case HostPortal:
22792 popHostContainer(interruptedWork);
22793 break;
22794
22795 case SuspenseComponent:
22796 popSuspenseContext(interruptedWork);
22797 break;
22798
22799 case SuspenseListComponent:
22800 popSuspenseContext(interruptedWork);
22801 break;
22802
22803 case ContextProvider:
22804 var context = interruptedWork.type._context;
22805 popProvider(context, interruptedWork);
22806 break;
22807
22808 case OffscreenComponent:
22809 case LegacyHiddenComponent:
22810 popRenderLanes(interruptedWork);
22811 break;
22812 }
22813}
22814
22815var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
22816
22817{
22818 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
22819} // Used during the commit phase to track the state of the Offscreen component stack.
22820// Allows us to avoid traversing the return path to find the nearest Offscreen ancestor.
22821// Only used when enableSuspenseLayoutEffectSemantics is enabled.
22822
22823
22824var offscreenSubtreeIsHidden = false;
22825var offscreenSubtreeWasHidden = false;
22826var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
22827var nextEffect = null; // Used for Profiling builds to track updaters.
22828
22829var inProgressLanes = null;
22830var inProgressRoot = null;
22831function reportUncaughtErrorInDEV(error) {
22832 // Wrapping each small part of the commit phase into a guarded
22833 // callback is a bit too slow (https://github.com/facebook/react/pull/21666).
22834 // But we rely on it to surface errors to DEV tools like overlays
22835 // (https://github.com/facebook/react/issues/21712).
22836 // As a compromise, rethrow only caught errors in a guard.
22837 {
22838 invokeGuardedCallback(null, function () {
22839 throw error;
22840 });
22841 clearCaughtError();
22842 }
22843}
22844
22845var callComponentWillUnmountWithTimer = function (current, instance) {
22846 instance.props = current.memoizedProps;
22847 instance.state = current.memoizedState;
22848
22849 if ( current.mode & ProfileMode) {
22850 try {
22851 startLayoutEffectTimer();
22852 instance.componentWillUnmount();
22853 } finally {
22854 recordLayoutEffectDuration(current);
22855 }
22856 } else {
22857 instance.componentWillUnmount();
22858 }
22859}; // Capture errors so they don't interrupt mounting.
22860
22861
22862function safelyCallCommitHookLayoutEffectListMount(current, nearestMountedAncestor) {
22863 try {
22864 commitHookEffectListMount(Layout, current);
22865 } catch (error) {
22866 captureCommitPhaseError(current, nearestMountedAncestor, error);
22867 }
22868} // Capture errors so they don't interrupt unmounting.
22869
22870
22871function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) {
22872 try {
22873 callComponentWillUnmountWithTimer(current, instance);
22874 } catch (error) {
22875 captureCommitPhaseError(current, nearestMountedAncestor, error);
22876 }
22877} // Capture errors so they don't interrupt mounting.
22878
22879
22880function safelyCallComponentDidMount(current, nearestMountedAncestor, instance) {
22881 try {
22882 instance.componentDidMount();
22883 } catch (error) {
22884 captureCommitPhaseError(current, nearestMountedAncestor, error);
22885 }
22886} // Capture errors so they don't interrupt mounting.
22887
22888
22889function safelyAttachRef(current, nearestMountedAncestor) {
22890 try {
22891 commitAttachRef(current);
22892 } catch (error) {
22893 captureCommitPhaseError(current, nearestMountedAncestor, error);
22894 }
22895}
22896
22897function safelyDetachRef(current, nearestMountedAncestor) {
22898 var ref = current.ref;
22899
22900 if (ref !== null) {
22901 if (typeof ref === 'function') {
22902 var retVal;
22903
22904 try {
22905 if (enableProfilerTimer && enableProfilerCommitHooks && current.mode & ProfileMode) {
22906 try {
22907 startLayoutEffectTimer();
22908 retVal = ref(null);
22909 } finally {
22910 recordLayoutEffectDuration(current);
22911 }
22912 } else {
22913 retVal = ref(null);
22914 }
22915 } catch (error) {
22916 captureCommitPhaseError(current, nearestMountedAncestor, error);
22917 }
22918
22919 {
22920 if (typeof retVal === 'function') {
22921 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(current));
22922 }
22923 }
22924 } else {
22925 ref.current = null;
22926 }
22927 }
22928}
22929
22930function safelyCallDestroy(current, nearestMountedAncestor, destroy) {
22931 try {
22932 destroy();
22933 } catch (error) {
22934 captureCommitPhaseError(current, nearestMountedAncestor, error);
22935 }
22936}
22937
22938var focusedInstanceHandle = null;
22939var shouldFireAfterActiveInstanceBlur = false;
22940function commitBeforeMutationEffects(root, firstChild) {
22941 focusedInstanceHandle = prepareForCommit(root.containerInfo);
22942 nextEffect = firstChild;
22943 commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber
22944
22945 var shouldFire = shouldFireAfterActiveInstanceBlur;
22946 shouldFireAfterActiveInstanceBlur = false;
22947 focusedInstanceHandle = null;
22948 return shouldFire;
22949}
22950
22951function commitBeforeMutationEffects_begin() {
22952 while (nextEffect !== null) {
22953 var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur.
22954
22955 var child = fiber.child;
22956
22957 if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) {
22958 child.return = fiber;
22959 nextEffect = child;
22960 } else {
22961 commitBeforeMutationEffects_complete();
22962 }
22963 }
22964}
22965
22966function commitBeforeMutationEffects_complete() {
22967 while (nextEffect !== null) {
22968 var fiber = nextEffect;
22969 setCurrentFiber(fiber);
22970
22971 try {
22972 commitBeforeMutationEffectsOnFiber(fiber);
22973 } catch (error) {
22974 captureCommitPhaseError(fiber, fiber.return, error);
22975 }
22976
22977 resetCurrentFiber();
22978 var sibling = fiber.sibling;
22979
22980 if (sibling !== null) {
22981 sibling.return = fiber.return;
22982 nextEffect = sibling;
22983 return;
22984 }
22985
22986 nextEffect = fiber.return;
22987 }
22988}
22989
22990function commitBeforeMutationEffectsOnFiber(finishedWork) {
22991 var current = finishedWork.alternate;
22992 var flags = finishedWork.flags;
22993
22994 if ((flags & Snapshot) !== NoFlags) {
22995 setCurrentFiber(finishedWork);
22996
22997 switch (finishedWork.tag) {
22998 case FunctionComponent:
22999 case ForwardRef:
23000 case SimpleMemoComponent:
23001 {
23002 break;
23003 }
23004
23005 case ClassComponent:
23006 {
23007 if (current !== null) {
23008 var prevProps = current.memoizedProps;
23009 var prevState = current.memoizedState;
23010 var instance = finishedWork.stateNode; // We could update instance props and state here,
23011 // but instead we rely on them being set during last render.
23012 // TODO: revisit this when we implement resuming.
23013
23014 {
23015 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23016 if (instance.props !== finishedWork.memoizedProps) {
23017 error('Expected %s props to match memoized props before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23018 }
23019
23020 if (instance.state !== finishedWork.memoizedState) {
23021 error('Expected %s state to match memoized state before ' + 'getSnapshotBeforeUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23022 }
23023 }
23024 }
23025
23026 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
23027
23028 {
23029 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
23030
23031 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
23032 didWarnSet.add(finishedWork.type);
23033
23034 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentNameFromFiber(finishedWork));
23035 }
23036 }
23037
23038 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
23039 }
23040
23041 break;
23042 }
23043
23044 case HostRoot:
23045 {
23046 {
23047 var root = finishedWork.stateNode;
23048 clearContainer(root.containerInfo);
23049 }
23050
23051 break;
23052 }
23053
23054 case HostComponent:
23055 case HostText:
23056 case HostPortal:
23057 case IncompleteClassComponent:
23058 // Nothing to do for these component types
23059 break;
23060
23061 default:
23062 {
23063 throw new 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.');
23064 }
23065 }
23066
23067 resetCurrentFiber();
23068 }
23069}
23070
23071function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) {
23072 var updateQueue = finishedWork.updateQueue;
23073 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
23074
23075 if (lastEffect !== null) {
23076 var firstEffect = lastEffect.next;
23077 var effect = firstEffect;
23078
23079 do {
23080 if ((effect.tag & flags) === flags) {
23081 // Unmount
23082 var destroy = effect.destroy;
23083 effect.destroy = undefined;
23084
23085 if (destroy !== undefined) {
23086 {
23087 if ((flags & Passive$1) !== NoFlags$1) {
23088 markComponentPassiveEffectUnmountStarted(finishedWork);
23089 } else if ((flags & Layout) !== NoFlags$1) {
23090 markComponentLayoutEffectUnmountStarted(finishedWork);
23091 }
23092 }
23093
23094 {
23095 if ((flags & Insertion) !== NoFlags$1) {
23096 setIsRunningInsertionEffect(true);
23097 }
23098 }
23099
23100 safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
23101
23102 {
23103 if ((flags & Insertion) !== NoFlags$1) {
23104 setIsRunningInsertionEffect(false);
23105 }
23106 }
23107
23108 {
23109 if ((flags & Passive$1) !== NoFlags$1) {
23110 markComponentPassiveEffectUnmountStopped();
23111 } else if ((flags & Layout) !== NoFlags$1) {
23112 markComponentLayoutEffectUnmountStopped();
23113 }
23114 }
23115 }
23116 }
23117
23118 effect = effect.next;
23119 } while (effect !== firstEffect);
23120 }
23121}
23122
23123function commitHookEffectListMount(flags, finishedWork) {
23124 var updateQueue = finishedWork.updateQueue;
23125 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
23126
23127 if (lastEffect !== null) {
23128 var firstEffect = lastEffect.next;
23129 var effect = firstEffect;
23130
23131 do {
23132 if ((effect.tag & flags) === flags) {
23133 {
23134 if ((flags & Passive$1) !== NoFlags$1) {
23135 markComponentPassiveEffectMountStarted(finishedWork);
23136 } else if ((flags & Layout) !== NoFlags$1) {
23137 markComponentLayoutEffectMountStarted(finishedWork);
23138 }
23139 } // Mount
23140
23141
23142 var create = effect.create;
23143
23144 {
23145 if ((flags & Insertion) !== NoFlags$1) {
23146 setIsRunningInsertionEffect(true);
23147 }
23148 }
23149
23150 effect.destroy = create();
23151
23152 {
23153 if ((flags & Insertion) !== NoFlags$1) {
23154 setIsRunningInsertionEffect(false);
23155 }
23156 }
23157
23158 {
23159 if ((flags & Passive$1) !== NoFlags$1) {
23160 markComponentPassiveEffectMountStopped();
23161 } else if ((flags & Layout) !== NoFlags$1) {
23162 markComponentLayoutEffectMountStopped();
23163 }
23164 }
23165
23166 {
23167 var destroy = effect.destroy;
23168
23169 if (destroy !== undefined && typeof destroy !== 'function') {
23170 var hookName = void 0;
23171
23172 if ((effect.tag & Layout) !== NoFlags) {
23173 hookName = 'useLayoutEffect';
23174 } else if ((effect.tag & Insertion) !== NoFlags) {
23175 hookName = 'useInsertionEffect';
23176 } else {
23177 hookName = 'useEffect';
23178 }
23179
23180 var addendum = void 0;
23181
23182 if (destroy === null) {
23183 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
23184 } else if (typeof destroy.then === 'function') {
23185 addendum = '\n\nIt looks like you wrote ' + hookName + '(async () => ...) or returned a Promise. ' + 'Instead, write the async function inside your effect ' + 'and call it immediately:\n\n' + hookName + '(() => {\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://reactjs.org/link/hooks-data-fetching';
23186 } else {
23187 addendum = ' You returned: ' + destroy;
23188 }
23189
23190 error('%s must not return anything besides a function, ' + 'which is used for clean-up.%s', hookName, addendum);
23191 }
23192 }
23193 }
23194
23195 effect = effect.next;
23196 } while (effect !== firstEffect);
23197 }
23198}
23199
23200function commitPassiveEffectDurations(finishedRoot, finishedWork) {
23201 {
23202 // Only Profilers with work in their subtree will have an Update effect scheduled.
23203 if ((finishedWork.flags & Update) !== NoFlags) {
23204 switch (finishedWork.tag) {
23205 case Profiler:
23206 {
23207 var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration;
23208 var _finishedWork$memoize = finishedWork.memoizedProps,
23209 id = _finishedWork$memoize.id,
23210 onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase.
23211 // It does not get reset until the start of the next commit phase.
23212
23213 var commitTime = getCommitTime();
23214 var phase = finishedWork.alternate === null ? 'mount' : 'update';
23215
23216 {
23217 if (isCurrentUpdateNested()) {
23218 phase = 'nested-update';
23219 }
23220 }
23221
23222 if (typeof onPostCommit === 'function') {
23223 onPostCommit(id, phase, passiveEffectDuration, commitTime);
23224 } // Bubble times to the next nearest ancestor Profiler.
23225 // After we process that Profiler, we'll bubble further up.
23226
23227
23228 var parentFiber = finishedWork.return;
23229
23230 outer: while (parentFiber !== null) {
23231 switch (parentFiber.tag) {
23232 case HostRoot:
23233 var root = parentFiber.stateNode;
23234 root.passiveEffectDuration += passiveEffectDuration;
23235 break outer;
23236
23237 case Profiler:
23238 var parentStateNode = parentFiber.stateNode;
23239 parentStateNode.passiveEffectDuration += passiveEffectDuration;
23240 break outer;
23241 }
23242
23243 parentFiber = parentFiber.return;
23244 }
23245
23246 break;
23247 }
23248 }
23249 }
23250 }
23251}
23252
23253function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) {
23254 if ((finishedWork.flags & LayoutMask) !== NoFlags) {
23255 switch (finishedWork.tag) {
23256 case FunctionComponent:
23257 case ForwardRef:
23258 case SimpleMemoComponent:
23259 {
23260 if ( !offscreenSubtreeWasHidden) {
23261 // At this point layout effects have already been destroyed (during mutation phase).
23262 // This is done to prevent sibling component effects from interfering with each other,
23263 // e.g. a destroy function in one component should never override a ref set
23264 // by a create function in another component during the same commit.
23265 if ( finishedWork.mode & ProfileMode) {
23266 try {
23267 startLayoutEffectTimer();
23268 commitHookEffectListMount(Layout | HasEffect, finishedWork);
23269 } finally {
23270 recordLayoutEffectDuration(finishedWork);
23271 }
23272 } else {
23273 commitHookEffectListMount(Layout | HasEffect, finishedWork);
23274 }
23275 }
23276
23277 break;
23278 }
23279
23280 case ClassComponent:
23281 {
23282 var instance = finishedWork.stateNode;
23283
23284 if (finishedWork.flags & Update) {
23285 if (!offscreenSubtreeWasHidden) {
23286 if (current === null) {
23287 // We could update instance props and state here,
23288 // but instead we rely on them being set during last render.
23289 // TODO: revisit this when we implement resuming.
23290 {
23291 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23292 if (instance.props !== finishedWork.memoizedProps) {
23293 error('Expected %s props to match memoized props before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23294 }
23295
23296 if (instance.state !== finishedWork.memoizedState) {
23297 error('Expected %s state to match memoized state before ' + 'componentDidMount. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23298 }
23299 }
23300 }
23301
23302 if ( finishedWork.mode & ProfileMode) {
23303 try {
23304 startLayoutEffectTimer();
23305 instance.componentDidMount();
23306 } finally {
23307 recordLayoutEffectDuration(finishedWork);
23308 }
23309 } else {
23310 instance.componentDidMount();
23311 }
23312 } else {
23313 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
23314 var prevState = current.memoizedState; // We could update instance props and state here,
23315 // but instead we rely on them being set during last render.
23316 // TODO: revisit this when we implement resuming.
23317
23318 {
23319 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23320 if (instance.props !== finishedWork.memoizedProps) {
23321 error('Expected %s props to match memoized props before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23322 }
23323
23324 if (instance.state !== finishedWork.memoizedState) {
23325 error('Expected %s state to match memoized state before ' + 'componentDidUpdate. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23326 }
23327 }
23328 }
23329
23330 if ( finishedWork.mode & ProfileMode) {
23331 try {
23332 startLayoutEffectTimer();
23333 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
23334 } finally {
23335 recordLayoutEffectDuration(finishedWork);
23336 }
23337 } else {
23338 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
23339 }
23340 }
23341 }
23342 } // TODO: I think this is now always non-null by the time it reaches the
23343 // commit phase. Consider removing the type check.
23344
23345
23346 var updateQueue = finishedWork.updateQueue;
23347
23348 if (updateQueue !== null) {
23349 {
23350 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23351 if (instance.props !== finishedWork.memoizedProps) {
23352 error('Expected %s props to match memoized props before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.props`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23353 }
23354
23355 if (instance.state !== finishedWork.memoizedState) {
23356 error('Expected %s state to match memoized state before ' + 'processing the update queue. ' + 'This might either be because of a bug in React, or because ' + 'a component reassigns its own `this.state`. ' + 'Please file an issue.', getComponentNameFromFiber(finishedWork) || 'instance');
23357 }
23358 }
23359 } // We could update instance props and state here,
23360 // but instead we rely on them being set during last render.
23361 // TODO: revisit this when we implement resuming.
23362
23363
23364 commitUpdateQueue(finishedWork, updateQueue, instance);
23365 }
23366
23367 break;
23368 }
23369
23370 case HostRoot:
23371 {
23372 // TODO: I think this is now always non-null by the time it reaches the
23373 // commit phase. Consider removing the type check.
23374 var _updateQueue = finishedWork.updateQueue;
23375
23376 if (_updateQueue !== null) {
23377 var _instance = null;
23378
23379 if (finishedWork.child !== null) {
23380 switch (finishedWork.child.tag) {
23381 case HostComponent:
23382 _instance = getPublicInstance(finishedWork.child.stateNode);
23383 break;
23384
23385 case ClassComponent:
23386 _instance = finishedWork.child.stateNode;
23387 break;
23388 }
23389 }
23390
23391 commitUpdateQueue(finishedWork, _updateQueue, _instance);
23392 }
23393
23394 break;
23395 }
23396
23397 case HostComponent:
23398 {
23399 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
23400 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
23401 // These effects should only be committed when components are first mounted,
23402 // aka when there is no current/alternate.
23403
23404 if (current === null && finishedWork.flags & Update) {
23405 var type = finishedWork.type;
23406 var props = finishedWork.memoizedProps;
23407 commitMount(_instance2, type, props);
23408 }
23409
23410 break;
23411 }
23412
23413 case HostText:
23414 {
23415 // We have no life-cycles associated with text.
23416 break;
23417 }
23418
23419 case HostPortal:
23420 {
23421 // We have no life-cycles associated with portals.
23422 break;
23423 }
23424
23425 case Profiler:
23426 {
23427 {
23428 var _finishedWork$memoize2 = finishedWork.memoizedProps,
23429 onCommit = _finishedWork$memoize2.onCommit,
23430 onRender = _finishedWork$memoize2.onRender;
23431 var effectDuration = finishedWork.stateNode.effectDuration;
23432 var commitTime = getCommitTime();
23433 var phase = current === null ? 'mount' : 'update';
23434
23435 {
23436 if (isCurrentUpdateNested()) {
23437 phase = 'nested-update';
23438 }
23439 }
23440
23441 if (typeof onRender === 'function') {
23442 onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime);
23443 }
23444
23445 {
23446 if (typeof onCommit === 'function') {
23447 onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime);
23448 } // Schedule a passive effect for this Profiler to call onPostCommit hooks.
23449 // This effect should be scheduled even if there is no onPostCommit callback for this Profiler,
23450 // because the effect is also where times bubble to parent Profilers.
23451
23452
23453 enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor.
23454 // Do not reset these values until the next render so DevTools has a chance to read them first.
23455
23456 var parentFiber = finishedWork.return;
23457
23458 outer: while (parentFiber !== null) {
23459 switch (parentFiber.tag) {
23460 case HostRoot:
23461 var root = parentFiber.stateNode;
23462 root.effectDuration += effectDuration;
23463 break outer;
23464
23465 case Profiler:
23466 var parentStateNode = parentFiber.stateNode;
23467 parentStateNode.effectDuration += effectDuration;
23468 break outer;
23469 }
23470
23471 parentFiber = parentFiber.return;
23472 }
23473 }
23474 }
23475
23476 break;
23477 }
23478
23479 case SuspenseComponent:
23480 {
23481 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
23482 break;
23483 }
23484
23485 case SuspenseListComponent:
23486 case IncompleteClassComponent:
23487 case ScopeComponent:
23488 case OffscreenComponent:
23489 case LegacyHiddenComponent:
23490 case TracingMarkerComponent:
23491 {
23492 break;
23493 }
23494
23495 default:
23496 throw new 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.');
23497 }
23498 }
23499
23500 if ( !offscreenSubtreeWasHidden) {
23501 {
23502 if (finishedWork.flags & Ref) {
23503 commitAttachRef(finishedWork);
23504 }
23505 }
23506 }
23507}
23508
23509function reappearLayoutEffectsOnFiber(node) {
23510 // Turn on layout effects in a tree that previously disappeared.
23511 // TODO (Offscreen) Check: flags & LayoutStatic
23512 switch (node.tag) {
23513 case FunctionComponent:
23514 case ForwardRef:
23515 case SimpleMemoComponent:
23516 {
23517 if ( node.mode & ProfileMode) {
23518 try {
23519 startLayoutEffectTimer();
23520 safelyCallCommitHookLayoutEffectListMount(node, node.return);
23521 } finally {
23522 recordLayoutEffectDuration(node);
23523 }
23524 } else {
23525 safelyCallCommitHookLayoutEffectListMount(node, node.return);
23526 }
23527
23528 break;
23529 }
23530
23531 case ClassComponent:
23532 {
23533 var instance = node.stateNode;
23534
23535 if (typeof instance.componentDidMount === 'function') {
23536 safelyCallComponentDidMount(node, node.return, instance);
23537 }
23538
23539 safelyAttachRef(node, node.return);
23540 break;
23541 }
23542
23543 case HostComponent:
23544 {
23545 safelyAttachRef(node, node.return);
23546 break;
23547 }
23548 }
23549}
23550
23551function hideOrUnhideAllChildren(finishedWork, isHidden) {
23552 // Only hide or unhide the top-most host nodes.
23553 var hostSubtreeRoot = null;
23554
23555 {
23556 // We only have the top Fiber that was inserted but we need to recurse down its
23557 // children to find all the terminal nodes.
23558 var node = finishedWork;
23559
23560 while (true) {
23561 if (node.tag === HostComponent) {
23562 if (hostSubtreeRoot === null) {
23563 hostSubtreeRoot = node;
23564
23565 try {
23566 var instance = node.stateNode;
23567
23568 if (isHidden) {
23569 hideInstance(instance);
23570 } else {
23571 unhideInstance(node.stateNode, node.memoizedProps);
23572 }
23573 } catch (error) {
23574 captureCommitPhaseError(finishedWork, finishedWork.return, error);
23575 }
23576 }
23577 } else if (node.tag === HostText) {
23578 if (hostSubtreeRoot === null) {
23579 try {
23580 var _instance3 = node.stateNode;
23581
23582 if (isHidden) {
23583 hideTextInstance(_instance3);
23584 } else {
23585 unhideTextInstance(_instance3, node.memoizedProps);
23586 }
23587 } catch (error) {
23588 captureCommitPhaseError(finishedWork, finishedWork.return, error);
23589 }
23590 }
23591 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) {
23592 node.child.return = node;
23593 node = node.child;
23594 continue;
23595 }
23596
23597 if (node === finishedWork) {
23598 return;
23599 }
23600
23601 while (node.sibling === null) {
23602 if (node.return === null || node.return === finishedWork) {
23603 return;
23604 }
23605
23606 if (hostSubtreeRoot === node) {
23607 hostSubtreeRoot = null;
23608 }
23609
23610 node = node.return;
23611 }
23612
23613 if (hostSubtreeRoot === node) {
23614 hostSubtreeRoot = null;
23615 }
23616
23617 node.sibling.return = node.return;
23618 node = node.sibling;
23619 }
23620 }
23621}
23622
23623function commitAttachRef(finishedWork) {
23624 var ref = finishedWork.ref;
23625
23626 if (ref !== null) {
23627 var instance = finishedWork.stateNode;
23628 var instanceToUse;
23629
23630 switch (finishedWork.tag) {
23631 case HostComponent:
23632 instanceToUse = getPublicInstance(instance);
23633 break;
23634
23635 default:
23636 instanceToUse = instance;
23637 } // Moved outside to ensure DCE works with this flag
23638
23639 if (typeof ref === 'function') {
23640 var retVal;
23641
23642 if ( finishedWork.mode & ProfileMode) {
23643 try {
23644 startLayoutEffectTimer();
23645 retVal = ref(instanceToUse);
23646 } finally {
23647 recordLayoutEffectDuration(finishedWork);
23648 }
23649 } else {
23650 retVal = ref(instanceToUse);
23651 }
23652
23653 {
23654 if (typeof retVal === 'function') {
23655 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(finishedWork));
23656 }
23657 }
23658 } else {
23659 {
23660 if (!ref.hasOwnProperty('current')) {
23661 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentNameFromFiber(finishedWork));
23662 }
23663 }
23664
23665 ref.current = instanceToUse;
23666 }
23667 }
23668}
23669
23670function detachFiberMutation(fiber) {
23671 // Cut off the return pointer to disconnect it from the tree.
23672 // This enables us to detect and warn against state updates on an unmounted component.
23673 // It also prevents events from bubbling from within disconnected components.
23674 //
23675 // Ideally, we should also clear the child pointer of the parent alternate to let this
23676 // get GC:ed but we don't know which for sure which parent is the current
23677 // one so we'll settle for GC:ing the subtree of this child.
23678 // This child itself will be GC:ed when the parent updates the next time.
23679 //
23680 // Note that we can't clear child or sibling pointers yet.
23681 // They're needed for passive effects and for findDOMNode.
23682 // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
23683 //
23684 // Don't reset the alternate yet, either. We need that so we can detach the
23685 // alternate's fields in the passive phase. Clearing the return pointer is
23686 // sufficient for findDOMNode semantics.
23687 var alternate = fiber.alternate;
23688
23689 if (alternate !== null) {
23690 alternate.return = null;
23691 }
23692
23693 fiber.return = null;
23694}
23695
23696function detachFiberAfterEffects(fiber) {
23697 var alternate = fiber.alternate;
23698
23699 if (alternate !== null) {
23700 fiber.alternate = null;
23701 detachFiberAfterEffects(alternate);
23702 } // Note: Defensively using negation instead of < in case
23703 // `deletedTreeCleanUpLevel` is undefined.
23704
23705
23706 {
23707 // Clear cyclical Fiber fields. This level alone is designed to roughly
23708 // approximate the planned Fiber refactor. In that world, `setState` will be
23709 // bound to a special "instance" object instead of a Fiber. The Instance
23710 // object will not have any of these fields. It will only be connected to
23711 // the fiber tree via a single link at the root. So if this level alone is
23712 // sufficient to fix memory issues, that bodes well for our plans.
23713 fiber.child = null;
23714 fiber.deletions = null;
23715 fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host
23716 // tree, which has its own pointers to children, parents, and siblings.
23717 // The other host nodes also point back to fibers, so we should detach that
23718 // one, too.
23719
23720 if (fiber.tag === HostComponent) {
23721 var hostInstance = fiber.stateNode;
23722
23723 if (hostInstance !== null) {
23724 detachDeletedInstance(hostInstance);
23725 }
23726 }
23727
23728 fiber.stateNode = null; // I'm intentionally not clearing the `return` field in this level. We
23729 // already disconnect the `return` pointer at the root of the deleted
23730 // subtree (in `detachFiberMutation`). Besides, `return` by itself is not
23731 // cyclical — it's only cyclical when combined with `child`, `sibling`, and
23732 // `alternate`. But we'll clear it in the next level anyway, just in case.
23733
23734 {
23735 fiber._debugOwner = null;
23736 }
23737
23738 {
23739 // Theoretically, nothing in here should be necessary, because we already
23740 // disconnected the fiber from the tree. So even if something leaks this
23741 // particular fiber, it won't leak anything else
23742 //
23743 // The purpose of this branch is to be super aggressive so we can measure
23744 // if there's any difference in memory impact. If there is, that could
23745 // indicate a React leak we don't know about.
23746 fiber.return = null;
23747 fiber.dependencies = null;
23748 fiber.memoizedProps = null;
23749 fiber.memoizedState = null;
23750 fiber.pendingProps = null;
23751 fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
23752
23753 fiber.updateQueue = null;
23754 }
23755 }
23756}
23757
23758function getHostParentFiber(fiber) {
23759 var parent = fiber.return;
23760
23761 while (parent !== null) {
23762 if (isHostParent(parent)) {
23763 return parent;
23764 }
23765
23766 parent = parent.return;
23767 }
23768
23769 throw new Error('Expected to find a host parent. This error is likely caused by a bug ' + 'in React. Please file an issue.');
23770}
23771
23772function isHostParent(fiber) {
23773 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
23774}
23775
23776function getHostSibling(fiber) {
23777 // We're going to search forward into the tree until we find a sibling host
23778 // node. Unfortunately, if multiple insertions are done in a row we have to
23779 // search past them. This leads to exponential search for the next sibling.
23780 // TODO: Find a more efficient way to do this.
23781 var node = fiber;
23782
23783 siblings: while (true) {
23784 // If we didn't find anything, let's try the next sibling.
23785 while (node.sibling === null) {
23786 if (node.return === null || isHostParent(node.return)) {
23787 // If we pop out of the root or hit the parent the fiber we are the
23788 // last sibling.
23789 return null;
23790 }
23791
23792 node = node.return;
23793 }
23794
23795 node.sibling.return = node.return;
23796 node = node.sibling;
23797
23798 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
23799 // If it is not host node and, we might have a host node inside it.
23800 // Try to search down until we find one.
23801 if (node.flags & Placement) {
23802 // If we don't have a child, try the siblings instead.
23803 continue siblings;
23804 } // If we don't have a child, try the siblings instead.
23805 // We also skip portals because they are not part of this host tree.
23806
23807
23808 if (node.child === null || node.tag === HostPortal) {
23809 continue siblings;
23810 } else {
23811 node.child.return = node;
23812 node = node.child;
23813 }
23814 } // Check if this host node is stable or about to be placed.
23815
23816
23817 if (!(node.flags & Placement)) {
23818 // Found it!
23819 return node.stateNode;
23820 }
23821 }
23822}
23823
23824function commitPlacement(finishedWork) {
23825
23826
23827 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
23828
23829 switch (parentFiber.tag) {
23830 case HostComponent:
23831 {
23832 var parent = parentFiber.stateNode;
23833
23834 if (parentFiber.flags & ContentReset) {
23835 // Reset the text content of the parent before doing any insertions
23836 resetTextContent(parent); // Clear ContentReset from the effect tag
23837
23838 parentFiber.flags &= ~ContentReset;
23839 }
23840
23841 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
23842 // children to find all the terminal nodes.
23843
23844 insertOrAppendPlacementNode(finishedWork, before, parent);
23845 break;
23846 }
23847
23848 case HostRoot:
23849 case HostPortal:
23850 {
23851 var _parent = parentFiber.stateNode.containerInfo;
23852
23853 var _before = getHostSibling(finishedWork);
23854
23855 insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent);
23856 break;
23857 }
23858 // eslint-disable-next-line-no-fallthrough
23859
23860 default:
23861 throw new Error('Invalid host parent fiber. This error is likely caused by a bug ' + 'in React. Please file an issue.');
23862 }
23863}
23864
23865function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
23866 var tag = node.tag;
23867 var isHost = tag === HostComponent || tag === HostText;
23868
23869 if (isHost) {
23870 var stateNode = node.stateNode;
23871
23872 if (before) {
23873 insertInContainerBefore(parent, stateNode, before);
23874 } else {
23875 appendChildToContainer(parent, stateNode);
23876 }
23877 } else if (tag === HostPortal) ; else {
23878 var child = node.child;
23879
23880 if (child !== null) {
23881 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
23882 var sibling = child.sibling;
23883
23884 while (sibling !== null) {
23885 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
23886 sibling = sibling.sibling;
23887 }
23888 }
23889 }
23890}
23891
23892function insertOrAppendPlacementNode(node, before, parent) {
23893 var tag = node.tag;
23894 var isHost = tag === HostComponent || tag === HostText;
23895
23896 if (isHost) {
23897 var stateNode = node.stateNode;
23898
23899 if (before) {
23900 insertBefore(parent, stateNode, before);
23901 } else {
23902 appendChild(parent, stateNode);
23903 }
23904 } else if (tag === HostPortal) ; else {
23905 var child = node.child;
23906
23907 if (child !== null) {
23908 insertOrAppendPlacementNode(child, before, parent);
23909 var sibling = child.sibling;
23910
23911 while (sibling !== null) {
23912 insertOrAppendPlacementNode(sibling, before, parent);
23913 sibling = sibling.sibling;
23914 }
23915 }
23916 }
23917} // These are tracked on the stack as we recursively traverse a
23918// deleted subtree.
23919// TODO: Update these during the whole mutation phase, not just during
23920// a deletion.
23921
23922
23923var hostParent = null;
23924var hostParentIsContainer = false;
23925
23926function commitDeletionEffects(root, returnFiber, deletedFiber) {
23927 {
23928 // We only have the top Fiber that was deleted but we need to recurse down its
23929 // children to find all the terminal nodes.
23930 // Recursively delete all host nodes from the parent, detach refs, clean
23931 // up mounted layout effects, and call componentWillUnmount.
23932 // We only need to remove the topmost host child in each branch. But then we
23933 // still need to keep traversing to unmount effects, refs, and cWU. TODO: We
23934 // could split this into two separate traversals functions, where the second
23935 // one doesn't include any removeChild logic. This is maybe the same
23936 // function as "disappearLayoutEffects" (or whatever that turns into after
23937 // the layout phase is refactored to use recursion).
23938 // Before starting, find the nearest host parent on the stack so we know
23939 // which instance/container to remove the children from.
23940 // TODO: Instead of searching up the fiber return path on every deletion, we
23941 // can track the nearest host component on the JS stack as we traverse the
23942 // tree during the commit phase. This would make insertions faster, too.
23943 var parent = returnFiber;
23944
23945 findParent: while (parent !== null) {
23946 switch (parent.tag) {
23947 case HostComponent:
23948 {
23949 hostParent = parent.stateNode;
23950 hostParentIsContainer = false;
23951 break findParent;
23952 }
23953
23954 case HostRoot:
23955 {
23956 hostParent = parent.stateNode.containerInfo;
23957 hostParentIsContainer = true;
23958 break findParent;
23959 }
23960
23961 case HostPortal:
23962 {
23963 hostParent = parent.stateNode.containerInfo;
23964 hostParentIsContainer = true;
23965 break findParent;
23966 }
23967 }
23968
23969 parent = parent.return;
23970 }
23971
23972 if (hostParent === null) {
23973 throw new Error('Expected to find a host parent. This error is likely caused by ' + 'a bug in React. Please file an issue.');
23974 }
23975
23976 commitDeletionEffectsOnFiber(root, returnFiber, deletedFiber);
23977 hostParent = null;
23978 hostParentIsContainer = false;
23979 }
23980
23981 detachFiberMutation(deletedFiber);
23982}
23983
23984function recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, parent) {
23985 // TODO: Use a static flag to skip trees that don't have unmount effects
23986 var child = parent.child;
23987
23988 while (child !== null) {
23989 commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, child);
23990 child = child.sibling;
23991 }
23992}
23993
23994function commitDeletionEffectsOnFiber(finishedRoot, nearestMountedAncestor, deletedFiber) {
23995 onCommitUnmount(deletedFiber); // The cases in this outer switch modify the stack before they traverse
23996 // into their subtree. There are simpler cases in the inner switch
23997 // that don't modify the stack.
23998
23999 switch (deletedFiber.tag) {
24000 case HostComponent:
24001 {
24002 if (!offscreenSubtreeWasHidden) {
24003 safelyDetachRef(deletedFiber, nearestMountedAncestor);
24004 } // Intentional fallthrough to next branch
24005
24006 }
24007 // eslint-disable-next-line-no-fallthrough
24008
24009 case HostText:
24010 {
24011 // We only need to remove the nearest host child. Set the host parent
24012 // to `null` on the stack to indicate that nested children don't
24013 // need to be removed.
24014 {
24015 var prevHostParent = hostParent;
24016 var prevHostParentIsContainer = hostParentIsContainer;
24017 hostParent = null;
24018 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24019 hostParent = prevHostParent;
24020 hostParentIsContainer = prevHostParentIsContainer;
24021
24022 if (hostParent !== null) {
24023 // Now that all the child effects have unmounted, we can remove the
24024 // node from the tree.
24025 if (hostParentIsContainer) {
24026 removeChildFromContainer(hostParent, deletedFiber.stateNode);
24027 } else {
24028 removeChild(hostParent, deletedFiber.stateNode);
24029 }
24030 }
24031 }
24032
24033 return;
24034 }
24035
24036 case DehydratedFragment:
24037 {
24038 // Delete the dehydrated suspense boundary and all of its content.
24039
24040
24041 {
24042 if (hostParent !== null) {
24043 if (hostParentIsContainer) {
24044 clearSuspenseBoundaryFromContainer(hostParent, deletedFiber.stateNode);
24045 } else {
24046 clearSuspenseBoundary(hostParent, deletedFiber.stateNode);
24047 }
24048 }
24049 }
24050
24051 return;
24052 }
24053
24054 case HostPortal:
24055 {
24056 {
24057 // When we go into a portal, it becomes the parent to remove from.
24058 var _prevHostParent = hostParent;
24059 var _prevHostParentIsContainer = hostParentIsContainer;
24060 hostParent = deletedFiber.stateNode.containerInfo;
24061 hostParentIsContainer = true;
24062 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24063 hostParent = _prevHostParent;
24064 hostParentIsContainer = _prevHostParentIsContainer;
24065 }
24066
24067 return;
24068 }
24069
24070 case FunctionComponent:
24071 case ForwardRef:
24072 case MemoComponent:
24073 case SimpleMemoComponent:
24074 {
24075 if (!offscreenSubtreeWasHidden) {
24076 var updateQueue = deletedFiber.updateQueue;
24077
24078 if (updateQueue !== null) {
24079 var lastEffect = updateQueue.lastEffect;
24080
24081 if (lastEffect !== null) {
24082 var firstEffect = lastEffect.next;
24083 var effect = firstEffect;
24084
24085 do {
24086 var _effect = effect,
24087 destroy = _effect.destroy,
24088 tag = _effect.tag;
24089
24090 if (destroy !== undefined) {
24091 if ((tag & Insertion) !== NoFlags$1) {
24092 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
24093 } else if ((tag & Layout) !== NoFlags$1) {
24094 {
24095 markComponentLayoutEffectUnmountStarted(deletedFiber);
24096 }
24097
24098 if ( deletedFiber.mode & ProfileMode) {
24099 startLayoutEffectTimer();
24100 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
24101 recordLayoutEffectDuration(deletedFiber);
24102 } else {
24103 safelyCallDestroy(deletedFiber, nearestMountedAncestor, destroy);
24104 }
24105
24106 {
24107 markComponentLayoutEffectUnmountStopped();
24108 }
24109 }
24110 }
24111
24112 effect = effect.next;
24113 } while (effect !== firstEffect);
24114 }
24115 }
24116 }
24117
24118 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24119 return;
24120 }
24121
24122 case ClassComponent:
24123 {
24124 if (!offscreenSubtreeWasHidden) {
24125 safelyDetachRef(deletedFiber, nearestMountedAncestor);
24126 var instance = deletedFiber.stateNode;
24127
24128 if (typeof instance.componentWillUnmount === 'function') {
24129 safelyCallComponentWillUnmount(deletedFiber, nearestMountedAncestor, instance);
24130 }
24131 }
24132
24133 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24134 return;
24135 }
24136
24137 case ScopeComponent:
24138 {
24139
24140 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24141 return;
24142 }
24143
24144 case OffscreenComponent:
24145 {
24146 if ( // TODO: Remove this dead flag
24147 deletedFiber.mode & ConcurrentMode) {
24148 // If this offscreen component is hidden, we already unmounted it. Before
24149 // deleting the children, track that it's already unmounted so that we
24150 // don't attempt to unmount the effects again.
24151 // TODO: If the tree is hidden, in most cases we should be able to skip
24152 // over the nested children entirely. An exception is we haven't yet found
24153 // the topmost host node to delete, which we already track on the stack.
24154 // But the other case is portals, which need to be detached no matter how
24155 // deeply they are nested. We should use a subtree flag to track whether a
24156 // subtree includes a nested portal.
24157 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
24158 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || deletedFiber.memoizedState !== null;
24159 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24160 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
24161 } else {
24162 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24163 }
24164
24165 break;
24166 }
24167
24168 default:
24169 {
24170 recursivelyTraverseDeletionEffects(finishedRoot, nearestMountedAncestor, deletedFiber);
24171 return;
24172 }
24173 }
24174}
24175
24176function commitSuspenseCallback(finishedWork) {
24177 // TODO: Move this to passive phase
24178 var newState = finishedWork.memoizedState;
24179}
24180
24181function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
24182
24183 var newState = finishedWork.memoizedState;
24184
24185 if (newState === null) {
24186 var current = finishedWork.alternate;
24187
24188 if (current !== null) {
24189 var prevState = current.memoizedState;
24190
24191 if (prevState !== null) {
24192 var suspenseInstance = prevState.dehydrated;
24193
24194 if (suspenseInstance !== null) {
24195 commitHydratedSuspenseInstance(suspenseInstance);
24196 }
24197 }
24198 }
24199 }
24200}
24201
24202function attachSuspenseRetryListeners(finishedWork) {
24203 // If this boundary just timed out, then it will have a set of wakeables.
24204 // For each wakeable, attach a listener so that when it resolves, React
24205 // attempts to re-render the boundary in the primary (pre-timeout) state.
24206 var wakeables = finishedWork.updateQueue;
24207
24208 if (wakeables !== null) {
24209 finishedWork.updateQueue = null;
24210 var retryCache = finishedWork.stateNode;
24211
24212 if (retryCache === null) {
24213 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
24214 }
24215
24216 wakeables.forEach(function (wakeable) {
24217 // Memoize using the boundary fiber to prevent redundant listeners.
24218 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
24219
24220 if (!retryCache.has(wakeable)) {
24221 retryCache.add(wakeable);
24222
24223 {
24224 if (isDevToolsPresent) {
24225 if (inProgressLanes !== null && inProgressRoot !== null) {
24226 // If we have pending work still, associate the original updaters with it.
24227 restorePendingUpdaters(inProgressRoot, inProgressLanes);
24228 } else {
24229 throw Error('Expected finished root and lanes to be set. This is a bug in React.');
24230 }
24231 }
24232 }
24233
24234 wakeable.then(retry, retry);
24235 }
24236 });
24237 }
24238} // This function detects when a Suspense boundary goes from visible to hidden.
24239function commitMutationEffects(root, finishedWork, committedLanes) {
24240 inProgressLanes = committedLanes;
24241 inProgressRoot = root;
24242 setCurrentFiber(finishedWork);
24243 commitMutationEffectsOnFiber(finishedWork, root);
24244 setCurrentFiber(finishedWork);
24245 inProgressLanes = null;
24246 inProgressRoot = null;
24247}
24248
24249function recursivelyTraverseMutationEffects(root, parentFiber, lanes) {
24250 // Deletions effects can be scheduled on any fiber type. They need to happen
24251 // before the children effects hae fired.
24252 var deletions = parentFiber.deletions;
24253
24254 if (deletions !== null) {
24255 for (var i = 0; i < deletions.length; i++) {
24256 var childToDelete = deletions[i];
24257
24258 try {
24259 commitDeletionEffects(root, parentFiber, childToDelete);
24260 } catch (error) {
24261 captureCommitPhaseError(childToDelete, parentFiber, error);
24262 }
24263 }
24264 }
24265
24266 var prevDebugFiber = getCurrentFiber();
24267
24268 if (parentFiber.subtreeFlags & MutationMask) {
24269 var child = parentFiber.child;
24270
24271 while (child !== null) {
24272 setCurrentFiber(child);
24273 commitMutationEffectsOnFiber(child, root);
24274 child = child.sibling;
24275 }
24276 }
24277
24278 setCurrentFiber(prevDebugFiber);
24279}
24280
24281function commitMutationEffectsOnFiber(finishedWork, root, lanes) {
24282 var current = finishedWork.alternate;
24283 var flags = finishedWork.flags; // The effect flag should be checked *after* we refine the type of fiber,
24284 // because the fiber tag is more specific. An exception is any flag related
24285 // to reconcilation, because those can be set on all fiber types.
24286
24287 switch (finishedWork.tag) {
24288 case FunctionComponent:
24289 case ForwardRef:
24290 case MemoComponent:
24291 case SimpleMemoComponent:
24292 {
24293 recursivelyTraverseMutationEffects(root, finishedWork);
24294 commitReconciliationEffects(finishedWork);
24295
24296 if (flags & Update) {
24297 try {
24298 commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return);
24299 commitHookEffectListMount(Insertion | HasEffect, finishedWork);
24300 } catch (error) {
24301 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24302 } // Layout effects are destroyed during the mutation phase so that all
24303 // destroy functions for all fibers are called before any create functions.
24304 // This prevents sibling component effects from interfering with each other,
24305 // e.g. a destroy function in one component should never override a ref set
24306 // by a create function in another component during the same commit.
24307
24308
24309 if ( finishedWork.mode & ProfileMode) {
24310 try {
24311 startLayoutEffectTimer();
24312 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
24313 } catch (error) {
24314 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24315 }
24316
24317 recordLayoutEffectDuration(finishedWork);
24318 } else {
24319 try {
24320 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
24321 } catch (error) {
24322 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24323 }
24324 }
24325 }
24326
24327 return;
24328 }
24329
24330 case ClassComponent:
24331 {
24332 recursivelyTraverseMutationEffects(root, finishedWork);
24333 commitReconciliationEffects(finishedWork);
24334
24335 if (flags & Ref) {
24336 if (current !== null) {
24337 safelyDetachRef(current, current.return);
24338 }
24339 }
24340
24341 return;
24342 }
24343
24344 case HostComponent:
24345 {
24346 recursivelyTraverseMutationEffects(root, finishedWork);
24347 commitReconciliationEffects(finishedWork);
24348
24349 if (flags & Ref) {
24350 if (current !== null) {
24351 safelyDetachRef(current, current.return);
24352 }
24353 }
24354
24355 {
24356 // TODO: ContentReset gets cleared by the children during the commit
24357 // phase. This is a refactor hazard because it means we must read
24358 // flags the flags after `commitReconciliationEffects` has already run;
24359 // the order matters. We should refactor so that ContentReset does not
24360 // rely on mutating the flag during commit. Like by setting a flag
24361 // during the render phase instead.
24362 if (finishedWork.flags & ContentReset) {
24363 var instance = finishedWork.stateNode;
24364
24365 try {
24366 resetTextContent(instance);
24367 } catch (error) {
24368 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24369 }
24370 }
24371
24372 if (flags & Update) {
24373 var _instance4 = finishedWork.stateNode;
24374
24375 if (_instance4 != null) {
24376 // Commit the work prepared earlier.
24377 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
24378 // as the newProps. The updatePayload will contain the real change in
24379 // this case.
24380
24381 var oldProps = current !== null ? current.memoizedProps : newProps;
24382 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
24383
24384 var updatePayload = finishedWork.updateQueue;
24385 finishedWork.updateQueue = null;
24386
24387 if (updatePayload !== null) {
24388 try {
24389 commitUpdate(_instance4, updatePayload, type, oldProps, newProps, finishedWork);
24390 } catch (error) {
24391 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24392 }
24393 }
24394 }
24395 }
24396 }
24397
24398 return;
24399 }
24400
24401 case HostText:
24402 {
24403 recursivelyTraverseMutationEffects(root, finishedWork);
24404 commitReconciliationEffects(finishedWork);
24405
24406 if (flags & Update) {
24407 {
24408 if (finishedWork.stateNode === null) {
24409 throw new Error('This should have a text node initialized. This error is likely ' + 'caused by a bug in React. Please file an issue.');
24410 }
24411
24412 var textInstance = finishedWork.stateNode;
24413 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
24414 // as the newProps. The updatePayload will contain the real change in
24415 // this case.
24416
24417 var oldText = current !== null ? current.memoizedProps : newText;
24418
24419 try {
24420 commitTextUpdate(textInstance, oldText, newText);
24421 } catch (error) {
24422 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24423 }
24424 }
24425 }
24426
24427 return;
24428 }
24429
24430 case HostRoot:
24431 {
24432 recursivelyTraverseMutationEffects(root, finishedWork);
24433 commitReconciliationEffects(finishedWork);
24434
24435 if (flags & Update) {
24436 {
24437 if (current !== null) {
24438 var prevRootState = current.memoizedState;
24439
24440 if (prevRootState.isDehydrated) {
24441 try {
24442 commitHydratedContainer(root.containerInfo);
24443 } catch (error) {
24444 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24445 }
24446 }
24447 }
24448 }
24449 }
24450
24451 return;
24452 }
24453
24454 case HostPortal:
24455 {
24456 recursivelyTraverseMutationEffects(root, finishedWork);
24457 commitReconciliationEffects(finishedWork);
24458
24459 return;
24460 }
24461
24462 case SuspenseComponent:
24463 {
24464 recursivelyTraverseMutationEffects(root, finishedWork);
24465 commitReconciliationEffects(finishedWork);
24466 var offscreenFiber = finishedWork.child;
24467
24468 if (offscreenFiber.flags & Visibility) {
24469 var offscreenInstance = offscreenFiber.stateNode;
24470 var newState = offscreenFiber.memoizedState;
24471 var isHidden = newState !== null; // Track the current state on the Offscreen instance so we can
24472 // read it during an event
24473
24474 offscreenInstance.isHidden = isHidden;
24475
24476 if (isHidden) {
24477 var wasHidden = offscreenFiber.alternate !== null && offscreenFiber.alternate.memoizedState !== null;
24478
24479 if (!wasHidden) {
24480 // TODO: Move to passive phase
24481 markCommitTimeOfFallback();
24482 }
24483 }
24484 }
24485
24486 if (flags & Update) {
24487 try {
24488 commitSuspenseCallback(finishedWork);
24489 } catch (error) {
24490 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24491 }
24492
24493 attachSuspenseRetryListeners(finishedWork);
24494 }
24495
24496 return;
24497 }
24498
24499 case OffscreenComponent:
24500 {
24501 var _wasHidden = current !== null && current.memoizedState !== null;
24502
24503 if ( // TODO: Remove this dead flag
24504 finishedWork.mode & ConcurrentMode) {
24505 // Before committing the children, track on the stack whether this
24506 // offscreen subtree was already hidden, so that we don't unmount the
24507 // effects again.
24508 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden;
24509 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden || _wasHidden;
24510 recursivelyTraverseMutationEffects(root, finishedWork);
24511 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
24512 } else {
24513 recursivelyTraverseMutationEffects(root, finishedWork);
24514 }
24515
24516 commitReconciliationEffects(finishedWork);
24517
24518 if (flags & Visibility) {
24519 var _offscreenInstance = finishedWork.stateNode;
24520 var _newState = finishedWork.memoizedState;
24521
24522 var _isHidden = _newState !== null;
24523
24524 var offscreenBoundary = finishedWork; // Track the current state on the Offscreen instance so we can
24525 // read it during an event
24526
24527 _offscreenInstance.isHidden = _isHidden;
24528
24529 {
24530 if (_isHidden) {
24531 if (!_wasHidden) {
24532 if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
24533 nextEffect = offscreenBoundary;
24534 var offscreenChild = offscreenBoundary.child;
24535
24536 while (offscreenChild !== null) {
24537 nextEffect = offscreenChild;
24538 disappearLayoutEffects_begin(offscreenChild);
24539 offscreenChild = offscreenChild.sibling;
24540 }
24541 }
24542 }
24543 }
24544 }
24545
24546 {
24547 // TODO: This needs to run whenever there's an insertion or update
24548 // inside a hidden Offscreen tree.
24549 hideOrUnhideAllChildren(offscreenBoundary, _isHidden);
24550 }
24551 }
24552
24553 return;
24554 }
24555
24556 case SuspenseListComponent:
24557 {
24558 recursivelyTraverseMutationEffects(root, finishedWork);
24559 commitReconciliationEffects(finishedWork);
24560
24561 if (flags & Update) {
24562 attachSuspenseRetryListeners(finishedWork);
24563 }
24564
24565 return;
24566 }
24567
24568 case ScopeComponent:
24569 {
24570
24571 return;
24572 }
24573
24574 default:
24575 {
24576 recursivelyTraverseMutationEffects(root, finishedWork);
24577 commitReconciliationEffects(finishedWork);
24578 return;
24579 }
24580 }
24581}
24582
24583function commitReconciliationEffects(finishedWork) {
24584 // Placement effects (insertions, reorders) can be scheduled on any fiber
24585 // type. They needs to happen after the children effects have fired, but
24586 // before the effects on this fiber have fired.
24587 var flags = finishedWork.flags;
24588
24589 if (flags & Placement) {
24590 try {
24591 commitPlacement(finishedWork);
24592 } catch (error) {
24593 captureCommitPhaseError(finishedWork, finishedWork.return, error);
24594 } // Clear the "placement" from effect tag so that we know that this is
24595 // inserted, before any life-cycles like componentDidMount gets called.
24596 // TODO: findDOMNode doesn't rely on this any more but isMounted does
24597 // and isMounted is deprecated anyway so we should be able to kill this.
24598
24599
24600 finishedWork.flags &= ~Placement;
24601 }
24602
24603 if (flags & Hydrating) {
24604 finishedWork.flags &= ~Hydrating;
24605 }
24606}
24607
24608function commitLayoutEffects(finishedWork, root, committedLanes) {
24609 inProgressLanes = committedLanes;
24610 inProgressRoot = root;
24611 nextEffect = finishedWork;
24612 commitLayoutEffects_begin(finishedWork, root, committedLanes);
24613 inProgressLanes = null;
24614 inProgressRoot = null;
24615}
24616
24617function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) {
24618 // Suspense layout effects semantics don't change for legacy roots.
24619 var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode;
24620
24621 while (nextEffect !== null) {
24622 var fiber = nextEffect;
24623 var firstChild = fiber.child;
24624
24625 if ( fiber.tag === OffscreenComponent && isModernRoot) {
24626 // Keep track of the current Offscreen stack's state.
24627 var isHidden = fiber.memoizedState !== null;
24628 var newOffscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden;
24629
24630 if (newOffscreenSubtreeIsHidden) {
24631 // The Offscreen tree is hidden. Skip over its layout effects.
24632 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24633 continue;
24634 } else {
24635 // TODO (Offscreen) Also check: subtreeFlags & LayoutMask
24636 var current = fiber.alternate;
24637 var wasHidden = current !== null && current.memoizedState !== null;
24638 var newOffscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden;
24639 var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden;
24640 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; // Traverse the Offscreen subtree with the current Offscreen as the root.
24641
24642 offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden;
24643 offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden;
24644
24645 if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) {
24646 // This is the root of a reappearing boundary. Turn its layout effects
24647 // back on.
24648 nextEffect = fiber;
24649 reappearLayoutEffects_begin(fiber);
24650 }
24651
24652 var child = firstChild;
24653
24654 while (child !== null) {
24655 nextEffect = child;
24656 commitLayoutEffects_begin(child, // New root; bubble back up to here and stop.
24657 root, committedLanes);
24658 child = child.sibling;
24659 } // Restore Offscreen state and resume in our-progress traversal.
24660
24661
24662 nextEffect = fiber;
24663 offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
24664 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
24665 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24666 continue;
24667 }
24668 }
24669
24670 if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) {
24671 firstChild.return = fiber;
24672 nextEffect = firstChild;
24673 } else {
24674 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24675 }
24676 }
24677}
24678
24679function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) {
24680 while (nextEffect !== null) {
24681 var fiber = nextEffect;
24682
24683 if ((fiber.flags & LayoutMask) !== NoFlags) {
24684 var current = fiber.alternate;
24685 setCurrentFiber(fiber);
24686
24687 try {
24688 commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
24689 } catch (error) {
24690 captureCommitPhaseError(fiber, fiber.return, error);
24691 }
24692
24693 resetCurrentFiber();
24694 }
24695
24696 if (fiber === subtreeRoot) {
24697 nextEffect = null;
24698 return;
24699 }
24700
24701 var sibling = fiber.sibling;
24702
24703 if (sibling !== null) {
24704 sibling.return = fiber.return;
24705 nextEffect = sibling;
24706 return;
24707 }
24708
24709 nextEffect = fiber.return;
24710 }
24711}
24712
24713function disappearLayoutEffects_begin(subtreeRoot) {
24714 while (nextEffect !== null) {
24715 var fiber = nextEffect;
24716 var firstChild = fiber.child; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
24717
24718 switch (fiber.tag) {
24719 case FunctionComponent:
24720 case ForwardRef:
24721 case MemoComponent:
24722 case SimpleMemoComponent:
24723 {
24724 if ( fiber.mode & ProfileMode) {
24725 try {
24726 startLayoutEffectTimer();
24727 commitHookEffectListUnmount(Layout, fiber, fiber.return);
24728 } finally {
24729 recordLayoutEffectDuration(fiber);
24730 }
24731 } else {
24732 commitHookEffectListUnmount(Layout, fiber, fiber.return);
24733 }
24734
24735 break;
24736 }
24737
24738 case ClassComponent:
24739 {
24740 // TODO (Offscreen) Check: flags & RefStatic
24741 safelyDetachRef(fiber, fiber.return);
24742 var instance = fiber.stateNode;
24743
24744 if (typeof instance.componentWillUnmount === 'function') {
24745 safelyCallComponentWillUnmount(fiber, fiber.return, instance);
24746 }
24747
24748 break;
24749 }
24750
24751 case HostComponent:
24752 {
24753 safelyDetachRef(fiber, fiber.return);
24754 break;
24755 }
24756
24757 case OffscreenComponent:
24758 {
24759 // Check if this is a
24760 var isHidden = fiber.memoizedState !== null;
24761
24762 if (isHidden) {
24763 // Nested Offscreen tree is already hidden. Don't disappear
24764 // its effects.
24765 disappearLayoutEffects_complete(subtreeRoot);
24766 continue;
24767 }
24768
24769 break;
24770 }
24771 } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic
24772
24773
24774 if (firstChild !== null) {
24775 firstChild.return = fiber;
24776 nextEffect = firstChild;
24777 } else {
24778 disappearLayoutEffects_complete(subtreeRoot);
24779 }
24780 }
24781}
24782
24783function disappearLayoutEffects_complete(subtreeRoot) {
24784 while (nextEffect !== null) {
24785 var fiber = nextEffect;
24786
24787 if (fiber === subtreeRoot) {
24788 nextEffect = null;
24789 return;
24790 }
24791
24792 var sibling = fiber.sibling;
24793
24794 if (sibling !== null) {
24795 sibling.return = fiber.return;
24796 nextEffect = sibling;
24797 return;
24798 }
24799
24800 nextEffect = fiber.return;
24801 }
24802}
24803
24804function reappearLayoutEffects_begin(subtreeRoot) {
24805 while (nextEffect !== null) {
24806 var fiber = nextEffect;
24807 var firstChild = fiber.child;
24808
24809 if (fiber.tag === OffscreenComponent) {
24810 var isHidden = fiber.memoizedState !== null;
24811
24812 if (isHidden) {
24813 // Nested Offscreen tree is still hidden. Don't re-appear its effects.
24814 reappearLayoutEffects_complete(subtreeRoot);
24815 continue;
24816 }
24817 } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic
24818
24819
24820 if (firstChild !== null) {
24821 // This node may have been reused from a previous render, so we can't
24822 // assume its return pointer is correct.
24823 firstChild.return = fiber;
24824 nextEffect = firstChild;
24825 } else {
24826 reappearLayoutEffects_complete(subtreeRoot);
24827 }
24828 }
24829}
24830
24831function reappearLayoutEffects_complete(subtreeRoot) {
24832 while (nextEffect !== null) {
24833 var fiber = nextEffect; // TODO (Offscreen) Check: flags & LayoutStatic
24834
24835 setCurrentFiber(fiber);
24836
24837 try {
24838 reappearLayoutEffectsOnFiber(fiber);
24839 } catch (error) {
24840 captureCommitPhaseError(fiber, fiber.return, error);
24841 }
24842
24843 resetCurrentFiber();
24844
24845 if (fiber === subtreeRoot) {
24846 nextEffect = null;
24847 return;
24848 }
24849
24850 var sibling = fiber.sibling;
24851
24852 if (sibling !== null) {
24853 // This node may have been reused from a previous render, so we can't
24854 // assume its return pointer is correct.
24855 sibling.return = fiber.return;
24856 nextEffect = sibling;
24857 return;
24858 }
24859
24860 nextEffect = fiber.return;
24861 }
24862}
24863
24864function commitPassiveMountEffects(root, finishedWork, committedLanes, committedTransitions) {
24865 nextEffect = finishedWork;
24866 commitPassiveMountEffects_begin(finishedWork, root, committedLanes, committedTransitions);
24867}
24868
24869function commitPassiveMountEffects_begin(subtreeRoot, root, committedLanes, committedTransitions) {
24870 while (nextEffect !== null) {
24871 var fiber = nextEffect;
24872 var firstChild = fiber.child;
24873
24874 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
24875 firstChild.return = fiber;
24876 nextEffect = firstChild;
24877 } else {
24878 commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions);
24879 }
24880 }
24881}
24882
24883function commitPassiveMountEffects_complete(subtreeRoot, root, committedLanes, committedTransitions) {
24884 while (nextEffect !== null) {
24885 var fiber = nextEffect;
24886
24887 if ((fiber.flags & Passive) !== NoFlags) {
24888 setCurrentFiber(fiber);
24889
24890 try {
24891 commitPassiveMountOnFiber(root, fiber, committedLanes, committedTransitions);
24892 } catch (error) {
24893 captureCommitPhaseError(fiber, fiber.return, error);
24894 }
24895
24896 resetCurrentFiber();
24897 }
24898
24899 if (fiber === subtreeRoot) {
24900 nextEffect = null;
24901 return;
24902 }
24903
24904 var sibling = fiber.sibling;
24905
24906 if (sibling !== null) {
24907 sibling.return = fiber.return;
24908 nextEffect = sibling;
24909 return;
24910 }
24911
24912 nextEffect = fiber.return;
24913 }
24914}
24915
24916function commitPassiveMountOnFiber(finishedRoot, finishedWork, committedLanes, committedTransitions) {
24917 switch (finishedWork.tag) {
24918 case FunctionComponent:
24919 case ForwardRef:
24920 case SimpleMemoComponent:
24921 {
24922 if ( finishedWork.mode & ProfileMode) {
24923 startPassiveEffectTimer();
24924
24925 try {
24926 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
24927 } finally {
24928 recordPassiveEffectDuration(finishedWork);
24929 }
24930 } else {
24931 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
24932 }
24933
24934 break;
24935 }
24936 }
24937}
24938
24939function commitPassiveUnmountEffects(firstChild) {
24940 nextEffect = firstChild;
24941 commitPassiveUnmountEffects_begin();
24942}
24943
24944function commitPassiveUnmountEffects_begin() {
24945 while (nextEffect !== null) {
24946 var fiber = nextEffect;
24947 var child = fiber.child;
24948
24949 if ((nextEffect.flags & ChildDeletion) !== NoFlags) {
24950 var deletions = fiber.deletions;
24951
24952 if (deletions !== null) {
24953 for (var i = 0; i < deletions.length; i++) {
24954 var fiberToDelete = deletions[i];
24955 nextEffect = fiberToDelete;
24956 commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber);
24957 }
24958
24959 {
24960 // A fiber was deleted from this parent fiber, but it's still part of
24961 // the previous (alternate) parent fiber's list of children. Because
24962 // children are a linked list, an earlier sibling that's still alive
24963 // will be connected to the deleted fiber via its `alternate`:
24964 //
24965 // live fiber
24966 // --alternate--> previous live fiber
24967 // --sibling--> deleted fiber
24968 //
24969 // We can't disconnect `alternate` on nodes that haven't been deleted
24970 // yet, but we can disconnect the `sibling` and `child` pointers.
24971 var previousFiber = fiber.alternate;
24972
24973 if (previousFiber !== null) {
24974 var detachedChild = previousFiber.child;
24975
24976 if (detachedChild !== null) {
24977 previousFiber.child = null;
24978
24979 do {
24980 var detachedSibling = detachedChild.sibling;
24981 detachedChild.sibling = null;
24982 detachedChild = detachedSibling;
24983 } while (detachedChild !== null);
24984 }
24985 }
24986 }
24987
24988 nextEffect = fiber;
24989 }
24990 }
24991
24992 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) {
24993 child.return = fiber;
24994 nextEffect = child;
24995 } else {
24996 commitPassiveUnmountEffects_complete();
24997 }
24998 }
24999}
25000
25001function commitPassiveUnmountEffects_complete() {
25002 while (nextEffect !== null) {
25003 var fiber = nextEffect;
25004
25005 if ((fiber.flags & Passive) !== NoFlags) {
25006 setCurrentFiber(fiber);
25007 commitPassiveUnmountOnFiber(fiber);
25008 resetCurrentFiber();
25009 }
25010
25011 var sibling = fiber.sibling;
25012
25013 if (sibling !== null) {
25014 sibling.return = fiber.return;
25015 nextEffect = sibling;
25016 return;
25017 }
25018
25019 nextEffect = fiber.return;
25020 }
25021}
25022
25023function commitPassiveUnmountOnFiber(finishedWork) {
25024 switch (finishedWork.tag) {
25025 case FunctionComponent:
25026 case ForwardRef:
25027 case SimpleMemoComponent:
25028 {
25029 if ( finishedWork.mode & ProfileMode) {
25030 startPassiveEffectTimer();
25031 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
25032 recordPassiveEffectDuration(finishedWork);
25033 } else {
25034 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
25035 }
25036
25037 break;
25038 }
25039 }
25040}
25041
25042function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) {
25043 while (nextEffect !== null) {
25044 var fiber = nextEffect; // Deletion effects fire in parent -> child order
25045 // TODO: Check if fiber has a PassiveStatic flag
25046
25047 setCurrentFiber(fiber);
25048 commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
25049 resetCurrentFiber();
25050 var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we
25051 // do this, still need to handle `deletedTreeCleanUpLevel` correctly.)
25052
25053 if (child !== null) {
25054 child.return = fiber;
25055 nextEffect = child;
25056 } else {
25057 commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot);
25058 }
25059 }
25060}
25061
25062function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) {
25063 while (nextEffect !== null) {
25064 var fiber = nextEffect;
25065 var sibling = fiber.sibling;
25066 var returnFiber = fiber.return;
25067
25068 {
25069 // Recursively traverse the entire deleted tree and clean up fiber fields.
25070 // This is more aggressive than ideal, and the long term goal is to only
25071 // have to detach the deleted tree at the root.
25072 detachFiberAfterEffects(fiber);
25073
25074 if (fiber === deletedSubtreeRoot) {
25075 nextEffect = null;
25076 return;
25077 }
25078 }
25079
25080 if (sibling !== null) {
25081 sibling.return = returnFiber;
25082 nextEffect = sibling;
25083 return;
25084 }
25085
25086 nextEffect = returnFiber;
25087 }
25088}
25089
25090function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) {
25091 switch (current.tag) {
25092 case FunctionComponent:
25093 case ForwardRef:
25094 case SimpleMemoComponent:
25095 {
25096 if ( current.mode & ProfileMode) {
25097 startPassiveEffectTimer();
25098 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
25099 recordPassiveEffectDuration(current);
25100 } else {
25101 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
25102 }
25103
25104 break;
25105 }
25106 }
25107} // TODO: Reuse reappearLayoutEffects traversal here?
25108
25109
25110function invokeLayoutEffectMountInDEV(fiber) {
25111 {
25112 // We don't need to re-check StrictEffectsMode here.
25113 // This function is only called if that check has already passed.
25114 switch (fiber.tag) {
25115 case FunctionComponent:
25116 case ForwardRef:
25117 case SimpleMemoComponent:
25118 {
25119 try {
25120 commitHookEffectListMount(Layout | HasEffect, fiber);
25121 } catch (error) {
25122 captureCommitPhaseError(fiber, fiber.return, error);
25123 }
25124
25125 break;
25126 }
25127
25128 case ClassComponent:
25129 {
25130 var instance = fiber.stateNode;
25131
25132 try {
25133 instance.componentDidMount();
25134 } catch (error) {
25135 captureCommitPhaseError(fiber, fiber.return, error);
25136 }
25137
25138 break;
25139 }
25140 }
25141 }
25142}
25143
25144function invokePassiveEffectMountInDEV(fiber) {
25145 {
25146 // We don't need to re-check StrictEffectsMode here.
25147 // This function is only called if that check has already passed.
25148 switch (fiber.tag) {
25149 case FunctionComponent:
25150 case ForwardRef:
25151 case SimpleMemoComponent:
25152 {
25153 try {
25154 commitHookEffectListMount(Passive$1 | HasEffect, fiber);
25155 } catch (error) {
25156 captureCommitPhaseError(fiber, fiber.return, error);
25157 }
25158
25159 break;
25160 }
25161 }
25162 }
25163}
25164
25165function invokeLayoutEffectUnmountInDEV(fiber) {
25166 {
25167 // We don't need to re-check StrictEffectsMode here.
25168 // This function is only called if that check has already passed.
25169 switch (fiber.tag) {
25170 case FunctionComponent:
25171 case ForwardRef:
25172 case SimpleMemoComponent:
25173 {
25174 try {
25175 commitHookEffectListUnmount(Layout | HasEffect, fiber, fiber.return);
25176 } catch (error) {
25177 captureCommitPhaseError(fiber, fiber.return, error);
25178 }
25179
25180 break;
25181 }
25182
25183 case ClassComponent:
25184 {
25185 var instance = fiber.stateNode;
25186
25187 if (typeof instance.componentWillUnmount === 'function') {
25188 safelyCallComponentWillUnmount(fiber, fiber.return, instance);
25189 }
25190
25191 break;
25192 }
25193 }
25194 }
25195}
25196
25197function invokePassiveEffectUnmountInDEV(fiber) {
25198 {
25199 // We don't need to re-check StrictEffectsMode here.
25200 // This function is only called if that check has already passed.
25201 switch (fiber.tag) {
25202 case FunctionComponent:
25203 case ForwardRef:
25204 case SimpleMemoComponent:
25205 {
25206 try {
25207 commitHookEffectListUnmount(Passive$1 | HasEffect, fiber, fiber.return);
25208 } catch (error) {
25209 captureCommitPhaseError(fiber, fiber.return, error);
25210 }
25211 }
25212 }
25213 }
25214}
25215
25216var COMPONENT_TYPE = 0;
25217var HAS_PSEUDO_CLASS_TYPE = 1;
25218var ROLE_TYPE = 2;
25219var TEST_NAME_TYPE = 3;
25220var TEXT_TYPE = 4;
25221
25222if (typeof Symbol === 'function' && Symbol.for) {
25223 var symbolFor = Symbol.for;
25224 COMPONENT_TYPE = symbolFor('selector.component');
25225 HAS_PSEUDO_CLASS_TYPE = symbolFor('selector.has_pseudo_class');
25226 ROLE_TYPE = symbolFor('selector.role');
25227 TEST_NAME_TYPE = symbolFor('selector.test_id');
25228 TEXT_TYPE = symbolFor('selector.text');
25229}
25230var commitHooks = [];
25231function onCommitRoot$1() {
25232 {
25233 commitHooks.forEach(function (commitHook) {
25234 return commitHook();
25235 });
25236 }
25237}
25238
25239var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
25240function isLegacyActEnvironment(fiber) {
25241 {
25242 // Legacy mode. We preserve the behavior of React 17's act. It assumes an
25243 // act environment whenever `jest` is defined, but you can still turn off
25244 // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly
25245 // to false.
25246 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
25247 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined; // $FlowExpectedError - Flow doesn't know about jest
25248
25249 var jestIsDefined = typeof jest !== 'undefined';
25250 return jestIsDefined && isReactActEnvironmentGlobal !== false;
25251 }
25252}
25253function isConcurrentActEnvironment() {
25254 {
25255 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
25256 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined;
25257
25258 if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) {
25259 // TODO: Include link to relevant documentation page.
25260 error('The current testing environment is not configured to support ' + 'act(...)');
25261 }
25262
25263 return isReactActEnvironmentGlobal;
25264 }
25265}
25266
25267var ceil = Math.ceil;
25268var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher,
25269 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
25270 ReactCurrentBatchConfig$3 = ReactSharedInternals.ReactCurrentBatchConfig,
25271 ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue;
25272var NoContext =
25273/* */
252740;
25275var BatchedContext =
25276/* */
252771;
25278var RenderContext =
25279/* */
252802;
25281var CommitContext =
25282/* */
252834;
25284var RootInProgress = 0;
25285var RootFatalErrored = 1;
25286var RootErrored = 2;
25287var RootSuspended = 3;
25288var RootSuspendedWithDelay = 4;
25289var RootCompleted = 5;
25290var RootDidNotComplete = 6; // Describes where we are in the React execution stack
25291
25292var executionContext = NoContext; // The root we're working on
25293
25294var workInProgressRoot = null; // The fiber we're working on
25295
25296var workInProgress = null; // The lanes we're rendering
25297
25298var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree
25299// This is a superset of the lanes we started working on at the root. The only
25300// case where it's different from `workInProgressRootRenderLanes` is when we
25301// enter a subtree that is hidden and needs to be unhidden: Suspense and
25302// Offscreen component.
25303//
25304// Most things in the work loop should deal with workInProgressRootRenderLanes.
25305// Most things in begin/complete phases should deal with subtreeRenderLanes.
25306
25307var subtreeRenderLanes = NoLanes;
25308var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc.
25309
25310var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown
25311
25312var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's
25313// slightly different than `renderLanes` because `renderLanes` can change as you
25314// enter and exit an Offscreen tree. This value is the combination of all render
25315// lanes for the entire render phase.
25316
25317var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only
25318// includes unprocessed updates, not work in bailed out children.
25319
25320var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
25321
25322var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event).
25323
25324var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during the render phase.
25325
25326var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI.
25327// We will log them once the tree commits.
25328
25329var workInProgressRootRecoverableErrors = null; // The most recent time we committed a fallback. This lets us ensure a train
25330// model where we don't commit new loading states in too quick succession.
25331
25332var globalMostRecentFallbackTime = 0;
25333var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering
25334// more and prefer CPU suspense heuristics instead.
25335
25336var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
25337// suspense heuristics and opt out of rendering more content.
25338
25339var RENDER_TIMEOUT_MS = 500;
25340var workInProgressTransitions = null;
25341
25342function resetRenderTimer() {
25343 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
25344}
25345
25346function getRenderTargetTime() {
25347 return workInProgressRootRenderTargetTime;
25348}
25349var hasUncaughtError = false;
25350var firstUncaughtError = null;
25351var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true;
25352var rootDoesHavePassiveEffects = false;
25353var rootWithPendingPassiveEffects = null;
25354var pendingPassiveEffectsLanes = NoLanes;
25355var pendingPassiveProfilerEffects = [];
25356var pendingPassiveTransitions = null; // Use these to prevent an infinite loop of nested updates
25357
25358var NESTED_UPDATE_LIMIT = 50;
25359var nestedUpdateCount = 0;
25360var rootWithNestedUpdates = null;
25361var isFlushingPassiveEffects = false;
25362var didScheduleUpdateDuringPassiveEffects = false;
25363var NESTED_PASSIVE_UPDATE_LIMIT = 50;
25364var nestedPassiveUpdateCount = 0;
25365var rootWithPassiveNestedUpdates = null; // If two updates are scheduled within the same event, we should treat their
25366// event times as simultaneous, even if the actual clock time has advanced
25367// between the first and second call.
25368
25369var currentEventTime = NoTimestamp;
25370var currentEventTransitionLane = NoLanes;
25371var isRunningInsertionEffect = false;
25372function getWorkInProgressRoot() {
25373 return workInProgressRoot;
25374}
25375function requestEventTime() {
25376 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
25377 // We're inside React, so it's fine to read the actual time.
25378 return now();
25379 } // We're not inside React, so we may be in the middle of a browser event.
25380
25381
25382 if (currentEventTime !== NoTimestamp) {
25383 // Use the same start time for all updates until we enter React again.
25384 return currentEventTime;
25385 } // This is the first update since React yielded. Compute a new start time.
25386
25387
25388 currentEventTime = now();
25389 return currentEventTime;
25390}
25391function requestUpdateLane(fiber) {
25392 // Special cases
25393 var mode = fiber.mode;
25394
25395 if ((mode & ConcurrentMode) === NoMode) {
25396 return SyncLane;
25397 } else if ( (executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) {
25398 // This is a render phase update. These are not officially supported. The
25399 // old behavior is to give this the same "thread" (lanes) as
25400 // whatever is currently rendering. So if you call `setState` on a component
25401 // that happens later in the same render, it will flush. Ideally, we want to
25402 // remove the special case and treat them as if they came from an
25403 // interleaved event. Regardless, this pattern is not officially supported.
25404 // This behavior is only a fallback. The flag only exists until we can roll
25405 // out the setState warning, since existing code might accidentally rely on
25406 // the current behavior.
25407 return pickArbitraryLane(workInProgressRootRenderLanes);
25408 }
25409
25410 var isTransition = requestCurrentTransition() !== NoTransition;
25411
25412 if (isTransition) {
25413 if ( ReactCurrentBatchConfig$3.transition !== null) {
25414 var transition = ReactCurrentBatchConfig$3.transition;
25415
25416 if (!transition._updatedFibers) {
25417 transition._updatedFibers = new Set();
25418 }
25419
25420 transition._updatedFibers.add(fiber);
25421 } // The algorithm for assigning an update to a lane should be stable for all
25422 // updates at the same priority within the same event. To do this, the
25423 // inputs to the algorithm must be the same.
25424 //
25425 // The trick we use is to cache the first of each of these inputs within an
25426 // event. Then reset the cached values once we can be sure the event is
25427 // over. Our heuristic for that is whenever we enter a concurrent work loop.
25428
25429
25430 if (currentEventTransitionLane === NoLane) {
25431 // All transitions within the same event are assigned the same lane.
25432 currentEventTransitionLane = claimNextTransitionLane();
25433 }
25434
25435 return currentEventTransitionLane;
25436 } // Updates originating inside certain React methods, like flushSync, have
25437 // their priority set by tracking it with a context variable.
25438 //
25439 // The opaque type returned by the host config is internally a lane, so we can
25440 // use that directly.
25441 // TODO: Move this type conversion to the event priority module.
25442
25443
25444 var updateLane = getCurrentUpdatePriority();
25445
25446 if (updateLane !== NoLane) {
25447 return updateLane;
25448 } // This update originated outside React. Ask the host environment for an
25449 // appropriate priority, based on the type of event.
25450 //
25451 // The opaque type returned by the host config is internally a lane, so we can
25452 // use that directly.
25453 // TODO: Move this type conversion to the event priority module.
25454
25455
25456 var eventLane = getCurrentEventPriority();
25457 return eventLane;
25458}
25459
25460function requestRetryLane(fiber) {
25461 // This is a fork of `requestUpdateLane` designed specifically for Suspense
25462 // "retries" — a special update that attempts to flip a Suspense boundary
25463 // from its placeholder state to its primary/resolved state.
25464 // Special cases
25465 var mode = fiber.mode;
25466
25467 if ((mode & ConcurrentMode) === NoMode) {
25468 return SyncLane;
25469 }
25470
25471 return claimNextRetryLane();
25472}
25473
25474function scheduleUpdateOnFiber(root, fiber, lane, eventTime) {
25475 checkForNestedUpdates();
25476
25477 {
25478 if (isRunningInsertionEffect) {
25479 error('useInsertionEffect must not schedule updates.');
25480 }
25481 }
25482
25483 {
25484 if (isFlushingPassiveEffects) {
25485 didScheduleUpdateDuringPassiveEffects = true;
25486 }
25487 } // Mark that the root has a pending update.
25488
25489
25490 markRootUpdated(root, lane, eventTime);
25491
25492 if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) {
25493 // This update was dispatched during the render phase. This is a mistake
25494 // if the update originates from user space (with the exception of local
25495 // hook updates, which are handled differently and don't reach this
25496 // function), but there are some internal React features that use this as
25497 // an implementation detail, like selective hydration.
25498 warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase
25499 } else {
25500 // This is a normal update, scheduled from outside the render phase. For
25501 // example, during an input event.
25502 {
25503 if (isDevToolsPresent) {
25504 addFiberToLanesMap(root, fiber, lane);
25505 }
25506 }
25507
25508 warnIfUpdatesNotWrappedWithActDEV(fiber);
25509
25510 if (root === workInProgressRoot) {
25511 // Received an update to a tree that's in the middle of rendering. Mark
25512 // that there was an interleaved update work on this root. Unless the
25513 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
25514 // phase update. In that case, we don't treat render phase updates as if
25515 // they were interleaved, for backwards compat reasons.
25516 if ( (executionContext & RenderContext) === NoContext) {
25517 workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane);
25518 }
25519
25520 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
25521 // The root already suspended with a delay, which means this render
25522 // definitely won't finish. Since we have a new update, let's mark it as
25523 // suspended now, right before marking the incoming update. This has the
25524 // effect of interrupting the current render and switching to the update.
25525 // TODO: Make sure this doesn't override pings that happen while we've
25526 // already started rendering.
25527 markRootSuspended$1(root, workInProgressRootRenderLanes);
25528 }
25529 }
25530
25531 ensureRootIsScheduled(root, eventTime);
25532
25533 if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
25534 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
25535 // Flush the synchronous work now, unless we're already working or inside
25536 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
25537 // scheduleCallbackForFiber to preserve the ability to schedule a callback
25538 // without immediately flushing it. We only do this for user-initiated
25539 // updates, to preserve historical behavior of legacy mode.
25540 resetRenderTimer();
25541 flushSyncCallbacksOnlyInLegacyMode();
25542 }
25543 }
25544}
25545function scheduleInitialHydrationOnRoot(root, lane, eventTime) {
25546 // This is a special fork of scheduleUpdateOnFiber that is only used to
25547 // schedule the initial hydration of a root that has just been created. Most
25548 // of the stuff in scheduleUpdateOnFiber can be skipped.
25549 //
25550 // The main reason for this separate path, though, is to distinguish the
25551 // initial children from subsequent updates. In fully client-rendered roots
25552 // (createRoot instead of hydrateRoot), all top-level renders are modeled as
25553 // updates, but hydration roots are special because the initial render must
25554 // match what was rendered on the server.
25555 var current = root.current;
25556 current.lanes = lane;
25557 markRootUpdated(root, lane, eventTime);
25558 ensureRootIsScheduled(root, eventTime);
25559}
25560function isUnsafeClassRenderPhaseUpdate(fiber) {
25561 // Check if this is a render phase update. Only called by class components,
25562 // which special (deprecated) behavior for UNSAFE_componentWillReceive props.
25563 return (// TODO: Remove outdated deferRenderPhaseUpdateToNextBatch experiment. We
25564 // decided not to enable it.
25565 (executionContext & RenderContext) !== NoContext
25566 );
25567} // Use this function to schedule a task for a root. There's only one task per
25568// root; if a task was already scheduled, we'll check to make sure the priority
25569// of the existing task is the same as the priority of the next level that the
25570// root has work on. This function is called on every update, and right before
25571// exiting a task.
25572
25573function ensureRootIsScheduled(root, currentTime) {
25574 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as
25575 // expired so we know to work on those next.
25576
25577 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
25578
25579 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
25580
25581 if (nextLanes === NoLanes) {
25582 // Special case: There's nothing to work on.
25583 if (existingCallbackNode !== null) {
25584 cancelCallback$1(existingCallbackNode);
25585 }
25586
25587 root.callbackNode = null;
25588 root.callbackPriority = NoLane;
25589 return;
25590 } // We use the highest priority lane to represent the priority of the callback.
25591
25592
25593 var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it.
25594
25595 var existingCallbackPriority = root.callbackPriority;
25596
25597 if (existingCallbackPriority === newCallbackPriority && // Special case related to `act`. If the currently scheduled task is a
25598 // Scheduler task, rather than an `act` task, cancel it and re-scheduled
25599 // on the `act` queue.
25600 !( ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) {
25601 {
25602 // If we're going to re-use an existing task, it needs to exist.
25603 // Assume that discrete update microtasks are non-cancellable and null.
25604 // TODO: Temporary until we confirm this warning is not fired.
25605 if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) {
25606 error('Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.');
25607 }
25608 } // The priority hasn't changed. We can reuse the existing task. Exit.
25609
25610
25611 return;
25612 }
25613
25614 if (existingCallbackNode != null) {
25615 // Cancel the existing callback. We'll schedule a new one below.
25616 cancelCallback$1(existingCallbackNode);
25617 } // Schedule a new callback.
25618
25619
25620 var newCallbackNode;
25621
25622 if (newCallbackPriority === SyncLane) {
25623 // Special case: Sync React callbacks are scheduled on a special
25624 // internal queue
25625 if (root.tag === LegacyRoot) {
25626 if ( ReactCurrentActQueue$1.isBatchingLegacy !== null) {
25627 ReactCurrentActQueue$1.didScheduleLegacyUpdate = true;
25628 }
25629
25630 scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));
25631 } else {
25632 scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
25633 }
25634
25635 {
25636 // Flush the queue in a microtask.
25637 if ( ReactCurrentActQueue$1.current !== null) {
25638 // Inside `act`, use our internal `act` queue so that these get flushed
25639 // at the end of the current scope even when using the sync version
25640 // of `act`.
25641 ReactCurrentActQueue$1.current.push(flushSyncCallbacks);
25642 } else {
25643 scheduleMicrotask(function () {
25644 // In Safari, appending an iframe forces microtasks to run.
25645 // https://github.com/facebook/react/issues/22459
25646 // We don't support running callbacks in the middle of render
25647 // or commit so we need to check against that.
25648 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
25649 // Note that this would still prematurely flush the callbacks
25650 // if this happens outside render or commit phase (e.g. in an event).
25651 flushSyncCallbacks();
25652 }
25653 });
25654 }
25655 }
25656
25657 newCallbackNode = null;
25658 } else {
25659 var schedulerPriorityLevel;
25660
25661 switch (lanesToEventPriority(nextLanes)) {
25662 case DiscreteEventPriority:
25663 schedulerPriorityLevel = ImmediatePriority;
25664 break;
25665
25666 case ContinuousEventPriority:
25667 schedulerPriorityLevel = UserBlockingPriority;
25668 break;
25669
25670 case DefaultEventPriority:
25671 schedulerPriorityLevel = NormalPriority;
25672 break;
25673
25674 case IdleEventPriority:
25675 schedulerPriorityLevel = IdlePriority;
25676 break;
25677
25678 default:
25679 schedulerPriorityLevel = NormalPriority;
25680 break;
25681 }
25682
25683 newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
25684 }
25685
25686 root.callbackPriority = newCallbackPriority;
25687 root.callbackNode = newCallbackNode;
25688} // This is the entry point for every concurrent task, i.e. anything that
25689// goes through Scheduler.
25690
25691
25692function performConcurrentWorkOnRoot(root, didTimeout) {
25693 {
25694 resetNestedUpdateFlag();
25695 } // Since we know we're in a React event, we can clear the current
25696 // event time. The next update will compute a new event time.
25697
25698
25699 currentEventTime = NoTimestamp;
25700 currentEventTransitionLane = NoLanes;
25701
25702 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
25703 throw new Error('Should not already be working.');
25704 } // Flush any pending passive effects before deciding which lanes to work on,
25705 // in case they schedule additional work.
25706
25707
25708 var originalCallbackNode = root.callbackNode;
25709 var didFlushPassiveEffects = flushPassiveEffects();
25710
25711 if (didFlushPassiveEffects) {
25712 // Something in the passive effect phase may have canceled the current task.
25713 // Check if the task node for this root was changed.
25714 if (root.callbackNode !== originalCallbackNode) {
25715 // The current task was canceled. Exit. We don't need to call
25716 // `ensureRootIsScheduled` because the check above implies either that
25717 // there's a new task, or that there's no remaining work on this root.
25718 return null;
25719 }
25720 } // Determine the next lanes to work on, using the fields stored
25721 // on the root.
25722
25723
25724 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
25725
25726 if (lanes === NoLanes) {
25727 // Defensive coding. This is never expected to happen.
25728 return null;
25729 } // We disable time-slicing in some cases: if the work has been CPU-bound
25730 // for too long ("expired" work, to prevent starvation), or we're in
25731 // sync-updates-by-default mode.
25732 // TODO: We only check `didTimeout` defensively, to account for a Scheduler
25733 // bug we're still investigating. Once the bug in Scheduler is fixed,
25734 // we can remove this, since we track expiration ourselves.
25735
25736
25737 var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && ( !didTimeout);
25738 var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes);
25739
25740 if (exitStatus !== RootInProgress) {
25741 if (exitStatus === RootErrored) {
25742 // If something threw an error, try rendering one more time. We'll
25743 // render synchronously to block concurrent data mutations, and we'll
25744 // includes all pending updates are included. If it still fails after
25745 // the second attempt, we'll give up and commit the resulting tree.
25746 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
25747
25748 if (errorRetryLanes !== NoLanes) {
25749 lanes = errorRetryLanes;
25750 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
25751 }
25752 }
25753
25754 if (exitStatus === RootFatalErrored) {
25755 var fatalError = workInProgressRootFatalError;
25756 prepareFreshStack(root, NoLanes);
25757 markRootSuspended$1(root, lanes);
25758 ensureRootIsScheduled(root, now());
25759 throw fatalError;
25760 }
25761
25762 if (exitStatus === RootDidNotComplete) {
25763 // The render unwound without completing the tree. This happens in special
25764 // cases where need to exit the current render without producing a
25765 // consistent tree or committing.
25766 //
25767 // This should only happen during a concurrent render, not a discrete or
25768 // synchronous update. We should have already checked for this when we
25769 // unwound the stack.
25770 markRootSuspended$1(root, lanes);
25771 } else {
25772 // The render completed.
25773 // Check if this render may have yielded to a concurrent event, and if so,
25774 // confirm that any newly rendered stores are consistent.
25775 // TODO: It's possible that even a concurrent render may never have yielded
25776 // to the main thread, if it was fast enough, or if it expired. We could
25777 // skip the consistency check in that case, too.
25778 var renderWasConcurrent = !includesBlockingLane(root, lanes);
25779 var finishedWork = root.current.alternate;
25780
25781 if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) {
25782 // A store was mutated in an interleaved event. Render again,
25783 // synchronously, to block further mutations.
25784 exitStatus = renderRootSync(root, lanes); // We need to check again if something threw
25785
25786 if (exitStatus === RootErrored) {
25787 var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
25788
25789 if (_errorRetryLanes !== NoLanes) {
25790 lanes = _errorRetryLanes;
25791 exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any
25792 // concurrent events.
25793 }
25794 }
25795
25796 if (exitStatus === RootFatalErrored) {
25797 var _fatalError = workInProgressRootFatalError;
25798 prepareFreshStack(root, NoLanes);
25799 markRootSuspended$1(root, lanes);
25800 ensureRootIsScheduled(root, now());
25801 throw _fatalError;
25802 }
25803 } // We now have a consistent tree. The next step is either to commit it,
25804 // or, if something suspended, wait to commit it after a timeout.
25805
25806
25807 root.finishedWork = finishedWork;
25808 root.finishedLanes = lanes;
25809 finishConcurrentRender(root, exitStatus, lanes);
25810 }
25811 }
25812
25813 ensureRootIsScheduled(root, now());
25814
25815 if (root.callbackNode === originalCallbackNode) {
25816 // The task node scheduled for this root is the same one that's
25817 // currently executed. Need to return a continuation.
25818 return performConcurrentWorkOnRoot.bind(null, root);
25819 }
25820
25821 return null;
25822}
25823
25824function recoverFromConcurrentError(root, errorRetryLanes) {
25825 // If an error occurred during hydration, discard server response and fall
25826 // back to client side render.
25827 // Before rendering again, save the errors from the previous attempt.
25828 var errorsFromFirstAttempt = workInProgressRootConcurrentErrors;
25829
25830 if (isRootDehydrated(root)) {
25831 // The shell failed to hydrate. Set a flag to force a client rendering
25832 // during the next attempt. To do this, we call prepareFreshStack now
25833 // to create the root work-in-progress fiber. This is a bit weird in terms
25834 // of factoring, because it relies on renderRootSync not calling
25835 // prepareFreshStack again in the call below, which happens because the
25836 // root and lanes haven't changed.
25837 //
25838 // TODO: I think what we should do is set ForceClientRender inside
25839 // throwException, like we do for nested Suspense boundaries. The reason
25840 // it's here instead is so we can switch to the synchronous work loop, too.
25841 // Something to consider for a future refactor.
25842 var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes);
25843 rootWorkInProgress.flags |= ForceClientRender;
25844
25845 {
25846 errorHydratingContainer(root.containerInfo);
25847 }
25848 }
25849
25850 var exitStatus = renderRootSync(root, errorRetryLanes);
25851
25852 if (exitStatus !== RootErrored) {
25853 // Successfully finished rendering on retry
25854 // The errors from the failed first attempt have been recovered. Add
25855 // them to the collection of recoverable errors. We'll log them in the
25856 // commit phase.
25857 var errorsFromSecondAttempt = workInProgressRootRecoverableErrors;
25858 workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors
25859 // from the first attempt, to preserve the causal sequence.
25860
25861 if (errorsFromSecondAttempt !== null) {
25862 queueRecoverableErrors(errorsFromSecondAttempt);
25863 }
25864 }
25865
25866 return exitStatus;
25867}
25868
25869function queueRecoverableErrors(errors) {
25870 if (workInProgressRootRecoverableErrors === null) {
25871 workInProgressRootRecoverableErrors = errors;
25872 } else {
25873 workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors);
25874 }
25875}
25876
25877function finishConcurrentRender(root, exitStatus, lanes) {
25878 switch (exitStatus) {
25879 case RootInProgress:
25880 case RootFatalErrored:
25881 {
25882 throw new Error('Root did not complete. This is a bug in React.');
25883 }
25884 // Flow knows about invariant, so it complains if I add a break
25885 // statement, but eslint doesn't know about invariant, so it complains
25886 // if I do. eslint-disable-next-line no-fallthrough
25887
25888 case RootErrored:
25889 {
25890 // We should have already attempted to retry this tree. If we reached
25891 // this point, it errored again. Commit it.
25892 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
25893 break;
25894 }
25895
25896 case RootSuspended:
25897 {
25898 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we
25899 // should immediately commit it or wait a bit.
25900
25901 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope
25902 !shouldForceFlushFallbacksInDEV()) {
25903 // This render only included retries, no updates. Throttle committing
25904 // retries so that we don't show too many loading states too quickly.
25905 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
25906
25907 if (msUntilTimeout > 10) {
25908 var nextLanes = getNextLanes(root, NoLanes);
25909
25910 if (nextLanes !== NoLanes) {
25911 // There's additional work on this root.
25912 break;
25913 }
25914
25915 var suspendedLanes = root.suspendedLanes;
25916
25917 if (!isSubsetOfLanes(suspendedLanes, lanes)) {
25918 // We should prefer to render the fallback of at the last
25919 // suspended level. Ping the last suspended level to try
25920 // rendering it again.
25921 // FIXME: What if the suspended lanes are Idle? Should not restart.
25922 var eventTime = requestEventTime();
25923 markRootPinged(root, suspendedLanes);
25924 break;
25925 } // The render is suspended, it hasn't timed out, and there's no
25926 // lower priority work to do. Instead of committing the fallback
25927 // immediately, wait for more data to arrive.
25928
25929
25930 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), msUntilTimeout);
25931 break;
25932 }
25933 } // The work expired. Commit immediately.
25934
25935
25936 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
25937 break;
25938 }
25939
25940 case RootSuspendedWithDelay:
25941 {
25942 markRootSuspended$1(root, lanes);
25943
25944 if (includesOnlyTransitions(lanes)) {
25945 // This is a transition, so we should exit without committing a
25946 // placeholder and without scheduling a timeout. Delay indefinitely
25947 // until we receive more data.
25948 break;
25949 }
25950
25951 if (!shouldForceFlushFallbacksInDEV()) {
25952 // This is not a transition, but we did trigger an avoided state.
25953 // Schedule a placeholder to display after a short delay, using the Just
25954 // Noticeable Difference.
25955 // TODO: Is the JND optimization worth the added complexity? If this is
25956 // the only reason we track the event time, then probably not.
25957 // Consider removing.
25958 var mostRecentEventTime = getMostRecentEventTime(root, lanes);
25959 var eventTimeMs = mostRecentEventTime;
25960 var timeElapsedMs = now() - eventTimeMs;
25961
25962 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.
25963
25964
25965 if (_msUntilTimeout > 10) {
25966 // Instead of committing the fallback immediately, wait for more data
25967 // to arrive.
25968 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors, workInProgressTransitions), _msUntilTimeout);
25969 break;
25970 }
25971 } // Commit the placeholder.
25972
25973
25974 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
25975 break;
25976 }
25977
25978 case RootCompleted:
25979 {
25980 // The work completed. Ready to commit.
25981 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions);
25982 break;
25983 }
25984
25985 default:
25986 {
25987 throw new Error('Unknown root exit status.');
25988 }
25989 }
25990}
25991
25992function isRenderConsistentWithExternalStores(finishedWork) {
25993 // Search the rendered tree for external store reads, and check whether the
25994 // stores were mutated in a concurrent event. Intentionally using an iterative
25995 // loop instead of recursion so we can exit early.
25996 var node = finishedWork;
25997
25998 while (true) {
25999 if (node.flags & StoreConsistency) {
26000 var updateQueue = node.updateQueue;
26001
26002 if (updateQueue !== null) {
26003 var checks = updateQueue.stores;
26004
26005 if (checks !== null) {
26006 for (var i = 0; i < checks.length; i++) {
26007 var check = checks[i];
26008 var getSnapshot = check.getSnapshot;
26009 var renderedValue = check.value;
26010
26011 try {
26012 if (!objectIs(getSnapshot(), renderedValue)) {
26013 // Found an inconsistent store.
26014 return false;
26015 }
26016 } catch (error) {
26017 // If `getSnapshot` throws, return `false`. This will schedule
26018 // a re-render, and the error will be rethrown during render.
26019 return false;
26020 }
26021 }
26022 }
26023 }
26024 }
26025
26026 var child = node.child;
26027
26028 if (node.subtreeFlags & StoreConsistency && child !== null) {
26029 child.return = node;
26030 node = child;
26031 continue;
26032 }
26033
26034 if (node === finishedWork) {
26035 return true;
26036 }
26037
26038 while (node.sibling === null) {
26039 if (node.return === null || node.return === finishedWork) {
26040 return true;
26041 }
26042
26043 node = node.return;
26044 }
26045
26046 node.sibling.return = node.return;
26047 node = node.sibling;
26048 } // Flow doesn't know this is unreachable, but eslint does
26049 // eslint-disable-next-line no-unreachable
26050
26051
26052 return true;
26053}
26054
26055function markRootSuspended$1(root, suspendedLanes) {
26056 // When suspending, we should always exclude lanes that were pinged or (more
26057 // rarely, since we try to avoid it) updated during the render phase.
26058 // TODO: Lol maybe there's a better way to factor this besides this
26059 // obnoxiously named function :)
26060 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
26061 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes);
26062 markRootSuspended(root, suspendedLanes);
26063} // This is the entry point for synchronous tasks that don't go
26064// through Scheduler
26065
26066
26067function performSyncWorkOnRoot(root) {
26068 {
26069 syncNestedUpdateFlag();
26070 }
26071
26072 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
26073 throw new Error('Should not already be working.');
26074 }
26075
26076 flushPassiveEffects();
26077 var lanes = getNextLanes(root, NoLanes);
26078
26079 if (!includesSomeLane(lanes, SyncLane)) {
26080 // There's no remaining sync work left.
26081 ensureRootIsScheduled(root, now());
26082 return null;
26083 }
26084
26085 var exitStatus = renderRootSync(root, lanes);
26086
26087 if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
26088 // If something threw an error, try rendering one more time. We'll render
26089 // synchronously to block concurrent data mutations, and we'll includes
26090 // all pending updates are included. If it still fails after the second
26091 // attempt, we'll give up and commit the resulting tree.
26092 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
26093
26094 if (errorRetryLanes !== NoLanes) {
26095 lanes = errorRetryLanes;
26096 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
26097 }
26098 }
26099
26100 if (exitStatus === RootFatalErrored) {
26101 var fatalError = workInProgressRootFatalError;
26102 prepareFreshStack(root, NoLanes);
26103 markRootSuspended$1(root, lanes);
26104 ensureRootIsScheduled(root, now());
26105 throw fatalError;
26106 }
26107
26108 if (exitStatus === RootDidNotComplete) {
26109 throw new Error('Root did not complete. This is a bug in React.');
26110 } // We now have a consistent tree. Because this is a sync render, we
26111 // will commit it even if something suspended.
26112
26113
26114 var finishedWork = root.current.alternate;
26115 root.finishedWork = finishedWork;
26116 root.finishedLanes = lanes;
26117 commitRoot(root, workInProgressRootRecoverableErrors, workInProgressTransitions); // Before exiting, make sure there's a callback scheduled for the next
26118 // pending level.
26119
26120 ensureRootIsScheduled(root, now());
26121 return null;
26122}
26123
26124function flushRoot(root, lanes) {
26125 if (lanes !== NoLanes) {
26126 markRootEntangled(root, mergeLanes(lanes, SyncLane));
26127 ensureRootIsScheduled(root, now());
26128
26129 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
26130 resetRenderTimer();
26131 flushSyncCallbacks();
26132 }
26133 }
26134}
26135function batchedUpdates$1(fn, a) {
26136 var prevExecutionContext = executionContext;
26137 executionContext |= BatchedContext;
26138
26139 try {
26140 return fn(a);
26141 } finally {
26142 executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer
26143 // most batchedUpdates-like method.
26144
26145 if (executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
26146 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
26147 resetRenderTimer();
26148 flushSyncCallbacksOnlyInLegacyMode();
26149 }
26150 }
26151}
26152function discreteUpdates(fn, a, b, c, d) {
26153 var previousPriority = getCurrentUpdatePriority();
26154 var prevTransition = ReactCurrentBatchConfig$3.transition;
26155
26156 try {
26157 ReactCurrentBatchConfig$3.transition = null;
26158 setCurrentUpdatePriority(DiscreteEventPriority);
26159 return fn(a, b, c, d);
26160 } finally {
26161 setCurrentUpdatePriority(previousPriority);
26162 ReactCurrentBatchConfig$3.transition = prevTransition;
26163
26164 if (executionContext === NoContext) {
26165 resetRenderTimer();
26166 }
26167 }
26168} // Overload the definition to the two valid signatures.
26169// Warning, this opts-out of checking the function body.
26170
26171// eslint-disable-next-line no-redeclare
26172function flushSync(fn) {
26173 // In legacy mode, we flush pending passive effects at the beginning of the
26174 // next event, not at the end of the previous one.
26175 if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) {
26176 flushPassiveEffects();
26177 }
26178
26179 var prevExecutionContext = executionContext;
26180 executionContext |= BatchedContext;
26181 var prevTransition = ReactCurrentBatchConfig$3.transition;
26182 var previousPriority = getCurrentUpdatePriority();
26183
26184 try {
26185 ReactCurrentBatchConfig$3.transition = null;
26186 setCurrentUpdatePriority(DiscreteEventPriority);
26187
26188 if (fn) {
26189 return fn();
26190 } else {
26191 return undefined;
26192 }
26193 } finally {
26194 setCurrentUpdatePriority(previousPriority);
26195 ReactCurrentBatchConfig$3.transition = prevTransition;
26196 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
26197 // Note that this will happen even if batchedUpdates is higher up
26198 // the stack.
26199
26200 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
26201 flushSyncCallbacks();
26202 }
26203 }
26204}
26205function isAlreadyRendering() {
26206 // Used by the renderer to print a warning if certain APIs are called from
26207 // the wrong context.
26208 return (executionContext & (RenderContext | CommitContext)) !== NoContext;
26209}
26210function pushRenderLanes(fiber, lanes) {
26211 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
26212 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
26213 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
26214}
26215function popRenderLanes(fiber) {
26216 subtreeRenderLanes = subtreeRenderLanesCursor.current;
26217 pop(subtreeRenderLanesCursor, fiber);
26218}
26219
26220function prepareFreshStack(root, lanes) {
26221 root.finishedWork = null;
26222 root.finishedLanes = NoLanes;
26223 var timeoutHandle = root.timeoutHandle;
26224
26225 if (timeoutHandle !== noTimeout) {
26226 // The root previous suspended and scheduled a timeout to commit a fallback
26227 // state. Now that we have additional work, cancel the timeout.
26228 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
26229
26230 cancelTimeout(timeoutHandle);
26231 }
26232
26233 if (workInProgress !== null) {
26234 var interruptedWork = workInProgress.return;
26235
26236 while (interruptedWork !== null) {
26237 var current = interruptedWork.alternate;
26238 unwindInterruptedWork(current, interruptedWork);
26239 interruptedWork = interruptedWork.return;
26240 }
26241 }
26242
26243 workInProgressRoot = root;
26244 var rootWorkInProgress = createWorkInProgress(root.current, null);
26245 workInProgress = rootWorkInProgress;
26246 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
26247 workInProgressRootExitStatus = RootInProgress;
26248 workInProgressRootFatalError = null;
26249 workInProgressRootSkippedLanes = NoLanes;
26250 workInProgressRootInterleavedUpdatedLanes = NoLanes;
26251 workInProgressRootPingedLanes = NoLanes;
26252 workInProgressRootConcurrentErrors = null;
26253 workInProgressRootRecoverableErrors = null;
26254 finishQueueingConcurrentUpdates();
26255
26256 {
26257 ReactStrictModeWarnings.discardPendingWarnings();
26258 }
26259
26260 return rootWorkInProgress;
26261}
26262
26263function handleError(root, thrownValue) {
26264 do {
26265 var erroredWork = workInProgress;
26266
26267 try {
26268 // Reset module-level state that was set during the render phase.
26269 resetContextDependencies();
26270 resetHooksAfterThrow();
26271 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a
26272 // separate issue. Write a regression test using string refs.
26273
26274 ReactCurrentOwner$2.current = null;
26275
26276 if (erroredWork === null || erroredWork.return === null) {
26277 // Expected to be working on a non-root fiber. This is a fatal error
26278 // because there's no ancestor that can handle it; the root is
26279 // supposed to capture all errors that weren't caught by an error
26280 // boundary.
26281 workInProgressRootExitStatus = RootFatalErrored;
26282 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
26283 // sibling, or the parent if there are no siblings. But since the root
26284 // has no siblings nor a parent, we set it to null. Usually this is
26285 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
26286 // intentionally not calling those, we need set it here.
26287 // TODO: Consider calling `unwindWork` to pop the contexts.
26288
26289 workInProgress = null;
26290 return;
26291 }
26292
26293 if (enableProfilerTimer && erroredWork.mode & ProfileMode) {
26294 // Record the time spent rendering before an error was thrown. This
26295 // avoids inaccurate Profiler durations in the case of a
26296 // suspended render.
26297 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
26298 }
26299
26300 if (enableSchedulingProfiler) {
26301 markComponentRenderStopped();
26302
26303 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
26304 var wakeable = thrownValue;
26305 markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes);
26306 } else {
26307 markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes);
26308 }
26309 }
26310
26311 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
26312 completeUnitOfWork(erroredWork);
26313 } catch (yetAnotherThrownValue) {
26314 // Something in the return path also threw.
26315 thrownValue = yetAnotherThrownValue;
26316
26317 if (workInProgress === erroredWork && erroredWork !== null) {
26318 // If this boundary has already errored, then we had trouble processing
26319 // the error. Bubble it to the next boundary.
26320 erroredWork = erroredWork.return;
26321 workInProgress = erroredWork;
26322 } else {
26323 erroredWork = workInProgress;
26324 }
26325
26326 continue;
26327 } // Return to the normal work loop.
26328
26329
26330 return;
26331 } while (true);
26332}
26333
26334function pushDispatcher() {
26335 var prevDispatcher = ReactCurrentDispatcher$2.current;
26336 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
26337
26338 if (prevDispatcher === null) {
26339 // The React isomorphic package does not include a default dispatcher.
26340 // Instead the first renderer will lazily attach one, in order to give
26341 // nicer error messages.
26342 return ContextOnlyDispatcher;
26343 } else {
26344 return prevDispatcher;
26345 }
26346}
26347
26348function popDispatcher(prevDispatcher) {
26349 ReactCurrentDispatcher$2.current = prevDispatcher;
26350}
26351
26352function markCommitTimeOfFallback() {
26353 globalMostRecentFallbackTime = now();
26354}
26355function markSkippedUpdateLanes(lane) {
26356 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
26357}
26358function renderDidSuspend() {
26359 if (workInProgressRootExitStatus === RootInProgress) {
26360 workInProgressRootExitStatus = RootSuspended;
26361 }
26362}
26363function renderDidSuspendDelayIfPossible() {
26364 if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) {
26365 workInProgressRootExitStatus = RootSuspendedWithDelay;
26366 } // Check if there are updates that we skipped tree that might have unblocked
26367 // this render.
26368
26369
26370 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) {
26371 // Mark the current render as suspended so that we switch to working on
26372 // the updates that were skipped. Usually we only suspend at the end of
26373 // the render phase.
26374 // TODO: We should probably always mark the root as suspended immediately
26375 // (inside this function), since by suspending at the end of the render
26376 // phase introduces a potential mistake where we suspend lanes that were
26377 // pinged or updated while we were rendering.
26378 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
26379 }
26380}
26381function renderDidError(error) {
26382 if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
26383 workInProgressRootExitStatus = RootErrored;
26384 }
26385
26386 if (workInProgressRootConcurrentErrors === null) {
26387 workInProgressRootConcurrentErrors = [error];
26388 } else {
26389 workInProgressRootConcurrentErrors.push(error);
26390 }
26391} // Called during render to determine if anything has suspended.
26392// Returns false if we're not sure.
26393
26394function renderHasNotSuspendedYet() {
26395 // If something errored or completed, we can't really be sure,
26396 // so those are false.
26397 return workInProgressRootExitStatus === RootInProgress;
26398}
26399
26400function renderRootSync(root, lanes) {
26401 var prevExecutionContext = executionContext;
26402 executionContext |= RenderContext;
26403 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
26404 // and prepare a fresh one. Otherwise we'll continue where we left off.
26405
26406 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
26407 {
26408 if (isDevToolsPresent) {
26409 var memoizedUpdaters = root.memoizedUpdaters;
26410
26411 if (memoizedUpdaters.size > 0) {
26412 restorePendingUpdaters(root, workInProgressRootRenderLanes);
26413 memoizedUpdaters.clear();
26414 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
26415 // If we bailout on this work, we'll move them back (like above).
26416 // It's important to move them now in case the work spawns more work at the same priority with different updaters.
26417 // That way we can keep the current update and future updates separate.
26418
26419
26420 movePendingFibersToMemoized(root, lanes);
26421 }
26422 }
26423
26424 workInProgressTransitions = getTransitionsForLanes();
26425 prepareFreshStack(root, lanes);
26426 }
26427
26428 {
26429 markRenderStarted(lanes);
26430 }
26431
26432 do {
26433 try {
26434 workLoopSync();
26435 break;
26436 } catch (thrownValue) {
26437 handleError(root, thrownValue);
26438 }
26439 } while (true);
26440
26441 resetContextDependencies();
26442 executionContext = prevExecutionContext;
26443 popDispatcher(prevDispatcher);
26444
26445 if (workInProgress !== null) {
26446 // This is a sync render, so we should have finished the whole tree.
26447 throw new Error('Cannot commit an incomplete root. This error is likely caused by a ' + 'bug in React. Please file an issue.');
26448 }
26449
26450 {
26451 markRenderStopped();
26452 } // Set this to null to indicate there's no in-progress render.
26453
26454
26455 workInProgressRoot = null;
26456 workInProgressRootRenderLanes = NoLanes;
26457 return workInProgressRootExitStatus;
26458} // The work loop is an extremely hot path. Tell Closure not to inline it.
26459
26460/** @noinline */
26461
26462
26463function workLoopSync() {
26464 // Already timed out, so perform work without checking if we need to yield.
26465 while (workInProgress !== null) {
26466 performUnitOfWork(workInProgress);
26467 }
26468}
26469
26470function renderRootConcurrent(root, lanes) {
26471 var prevExecutionContext = executionContext;
26472 executionContext |= RenderContext;
26473 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
26474 // and prepare a fresh one. Otherwise we'll continue where we left off.
26475
26476 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
26477 {
26478 if (isDevToolsPresent) {
26479 var memoizedUpdaters = root.memoizedUpdaters;
26480
26481 if (memoizedUpdaters.size > 0) {
26482 restorePendingUpdaters(root, workInProgressRootRenderLanes);
26483 memoizedUpdaters.clear();
26484 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
26485 // If we bailout on this work, we'll move them back (like above).
26486 // It's important to move them now in case the work spawns more work at the same priority with different updaters.
26487 // That way we can keep the current update and future updates separate.
26488
26489
26490 movePendingFibersToMemoized(root, lanes);
26491 }
26492 }
26493
26494 workInProgressTransitions = getTransitionsForLanes();
26495 resetRenderTimer();
26496 prepareFreshStack(root, lanes);
26497 }
26498
26499 {
26500 markRenderStarted(lanes);
26501 }
26502
26503 do {
26504 try {
26505 workLoopConcurrent();
26506 break;
26507 } catch (thrownValue) {
26508 handleError(root, thrownValue);
26509 }
26510 } while (true);
26511
26512 resetContextDependencies();
26513 popDispatcher(prevDispatcher);
26514 executionContext = prevExecutionContext;
26515
26516
26517 if (workInProgress !== null) {
26518 // Still work remaining.
26519 {
26520 markRenderYielded();
26521 }
26522
26523 return RootInProgress;
26524 } else {
26525 // Completed the tree.
26526 {
26527 markRenderStopped();
26528 } // Set this to null to indicate there's no in-progress render.
26529
26530
26531 workInProgressRoot = null;
26532 workInProgressRootRenderLanes = NoLanes; // Return the final exit status.
26533
26534 return workInProgressRootExitStatus;
26535 }
26536}
26537/** @noinline */
26538
26539
26540function workLoopConcurrent() {
26541 // Perform work until Scheduler asks us to yield
26542 while (workInProgress !== null && !shouldYield()) {
26543 performUnitOfWork(workInProgress);
26544 }
26545}
26546
26547function performUnitOfWork(unitOfWork) {
26548 // The current, flushed, state of this fiber is the alternate. Ideally
26549 // nothing should rely on this, but relying on it here means that we don't
26550 // need an additional field on the work in progress.
26551 var current = unitOfWork.alternate;
26552 setCurrentFiber(unitOfWork);
26553 var next;
26554
26555 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
26556 startProfilerTimer(unitOfWork);
26557 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
26558 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
26559 } else {
26560 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
26561 }
26562
26563 resetCurrentFiber();
26564 unitOfWork.memoizedProps = unitOfWork.pendingProps;
26565
26566 if (next === null) {
26567 // If this doesn't spawn new work, complete the current work.
26568 completeUnitOfWork(unitOfWork);
26569 } else {
26570 workInProgress = next;
26571 }
26572
26573 ReactCurrentOwner$2.current = null;
26574}
26575
26576function completeUnitOfWork(unitOfWork) {
26577 // Attempt to complete the current unit of work, then move to the next
26578 // sibling. If there are no more siblings, return to the parent fiber.
26579 var completedWork = unitOfWork;
26580
26581 do {
26582 // The current, flushed, state of this fiber is the alternate. Ideally
26583 // nothing should rely on this, but relying on it here means that we don't
26584 // need an additional field on the work in progress.
26585 var current = completedWork.alternate;
26586 var returnFiber = completedWork.return; // Check if the work completed or if something threw.
26587
26588 if ((completedWork.flags & Incomplete) === NoFlags) {
26589 setCurrentFiber(completedWork);
26590 var next = void 0;
26591
26592 if ( (completedWork.mode & ProfileMode) === NoMode) {
26593 next = completeWork(current, completedWork, subtreeRenderLanes);
26594 } else {
26595 startProfilerTimer(completedWork);
26596 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.
26597
26598 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
26599 }
26600
26601 resetCurrentFiber();
26602
26603 if (next !== null) {
26604 // Completing this fiber spawned new work. Work on that next.
26605 workInProgress = next;
26606 return;
26607 }
26608 } else {
26609 // This fiber did not complete because something threw. Pop values off
26610 // the stack without entering the complete phase. If this is a boundary,
26611 // capture values if possible.
26612 var _next = unwindWork(current, completedWork); // Because this fiber did not complete, don't reset its lanes.
26613
26614
26615 if (_next !== null) {
26616 // If completing this work spawned new work, do that next. We'll come
26617 // back here again.
26618 // Since we're restarting, remove anything that is not a host effect
26619 // from the effect tag.
26620 _next.flags &= HostEffectMask;
26621 workInProgress = _next;
26622 return;
26623 }
26624
26625 if ( (completedWork.mode & ProfileMode) !== NoMode) {
26626 // Record the render duration for the fiber that errored.
26627 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.
26628
26629 var actualDuration = completedWork.actualDuration;
26630 var child = completedWork.child;
26631
26632 while (child !== null) {
26633 actualDuration += child.actualDuration;
26634 child = child.sibling;
26635 }
26636
26637 completedWork.actualDuration = actualDuration;
26638 }
26639
26640 if (returnFiber !== null) {
26641 // Mark the parent fiber as incomplete and clear its subtree flags.
26642 returnFiber.flags |= Incomplete;
26643 returnFiber.subtreeFlags = NoFlags;
26644 returnFiber.deletions = null;
26645 } else {
26646 // We've unwound all the way to the root.
26647 workInProgressRootExitStatus = RootDidNotComplete;
26648 workInProgress = null;
26649 return;
26650 }
26651 }
26652
26653 var siblingFiber = completedWork.sibling;
26654
26655 if (siblingFiber !== null) {
26656 // If there is more work to do in this returnFiber, do that next.
26657 workInProgress = siblingFiber;
26658 return;
26659 } // Otherwise, return to the parent
26660
26661
26662 completedWork = returnFiber; // Update the next thing we're working on in case something throws.
26663
26664 workInProgress = completedWork;
26665 } while (completedWork !== null); // We've reached the root.
26666
26667
26668 if (workInProgressRootExitStatus === RootInProgress) {
26669 workInProgressRootExitStatus = RootCompleted;
26670 }
26671}
26672
26673function commitRoot(root, recoverableErrors, transitions) {
26674 // TODO: This no longer makes any sense. We already wrap the mutation and
26675 // layout phases. Should be able to remove.
26676 var previousUpdateLanePriority = getCurrentUpdatePriority();
26677 var prevTransition = ReactCurrentBatchConfig$3.transition;
26678
26679 try {
26680 ReactCurrentBatchConfig$3.transition = null;
26681 setCurrentUpdatePriority(DiscreteEventPriority);
26682 commitRootImpl(root, recoverableErrors, transitions, previousUpdateLanePriority);
26683 } finally {
26684 ReactCurrentBatchConfig$3.transition = prevTransition;
26685 setCurrentUpdatePriority(previousUpdateLanePriority);
26686 }
26687
26688 return null;
26689}
26690
26691function commitRootImpl(root, recoverableErrors, transitions, renderPriorityLevel) {
26692 do {
26693 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
26694 // means `flushPassiveEffects` will sometimes result in additional
26695 // passive effects. So we need to keep flushing in a loop until there are
26696 // no more pending effects.
26697 // TODO: Might be better if `flushPassiveEffects` did not automatically
26698 // flush synchronous work at the end, to avoid factoring hazards like this.
26699 flushPassiveEffects();
26700 } while (rootWithPendingPassiveEffects !== null);
26701
26702 flushRenderPhaseStrictModeWarningsInDEV();
26703
26704 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
26705 throw new Error('Should not already be working.');
26706 }
26707
26708 var finishedWork = root.finishedWork;
26709 var lanes = root.finishedLanes;
26710
26711 {
26712 markCommitStarted(lanes);
26713 }
26714
26715 if (finishedWork === null) {
26716
26717 {
26718 markCommitStopped();
26719 }
26720
26721 return null;
26722 } else {
26723 {
26724 if (lanes === NoLanes) {
26725 error('root.finishedLanes should not be empty during a commit. This is a ' + 'bug in React.');
26726 }
26727 }
26728 }
26729
26730 root.finishedWork = null;
26731 root.finishedLanes = NoLanes;
26732
26733 if (finishedWork === root.current) {
26734 throw new Error('Cannot commit the same tree as before. This error is likely caused by ' + 'a bug in React. Please file an issue.');
26735 } // commitRoot never returns a continuation; it always finishes synchronously.
26736 // So we can clear these now to allow a new callback to be scheduled.
26737
26738
26739 root.callbackNode = null;
26740 root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first
26741 // pending time is whatever is left on the root fiber.
26742
26743 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
26744 markRootFinished(root, remainingLanes);
26745
26746 if (root === workInProgressRoot) {
26747 // We can reset these now that they are finished.
26748 workInProgressRoot = null;
26749 workInProgress = null;
26750 workInProgressRootRenderLanes = NoLanes;
26751 } // If there are pending passive effects, schedule a callback to process them.
26752 // Do this as early as possible, so it is queued before anything else that
26753 // might get scheduled in the commit phase. (See #16714.)
26754 // TODO: Delete all other places that schedule the passive effect callback
26755 // They're redundant.
26756
26757
26758 if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) {
26759 if (!rootDoesHavePassiveEffects) {
26760 rootDoesHavePassiveEffects = true;
26761 // to store it in pendingPassiveTransitions until they get processed
26762 // We need to pass this through as an argument to commitRoot
26763 // because workInProgressTransitions might have changed between
26764 // the previous render and commit if we throttle the commit
26765 // with setTimeout
26766
26767 pendingPassiveTransitions = transitions;
26768 scheduleCallback$1(NormalPriority, function () {
26769 flushPassiveEffects(); // This render triggered passive effects: release the root cache pool
26770 // *after* passive effects fire to avoid freeing a cache pool that may
26771 // be referenced by a node in the tree (HostRoot, Cache boundary etc)
26772
26773 return null;
26774 });
26775 }
26776 } // Check if there are any effects in the whole tree.
26777 // TODO: This is left over from the effect list implementation, where we had
26778 // to check for the existence of `firstEffect` to satisfy Flow. I think the
26779 // only other reason this optimization exists is because it affects profiling.
26780 // Reconsider whether this is necessary.
26781
26782
26783 var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
26784 var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
26785
26786 if (subtreeHasEffects || rootHasEffect) {
26787 var prevTransition = ReactCurrentBatchConfig$3.transition;
26788 ReactCurrentBatchConfig$3.transition = null;
26789 var previousPriority = getCurrentUpdatePriority();
26790 setCurrentUpdatePriority(DiscreteEventPriority);
26791 var prevExecutionContext = executionContext;
26792 executionContext |= CommitContext; // Reset this to null before calling lifecycles
26793
26794 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
26795 // of the effect list for each phase: all mutation effects come before all
26796 // layout effects, and so on.
26797 // The first phase a "before mutation" phase. We use this phase to read the
26798 // state of the host tree right before we mutate it. This is where
26799 // getSnapshotBeforeUpdate is called.
26800
26801 var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(root, finishedWork);
26802
26803 {
26804 // Mark the current commit time to be shared by all Profilers in this
26805 // batch. This enables them to be grouped later.
26806 recordCommitTime();
26807 }
26808
26809
26810 commitMutationEffects(root, finishedWork, lanes);
26811
26812 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
26813 // the mutation phase, so that the previous tree is still current during
26814 // componentWillUnmount, but before the layout phase, so that the finished
26815 // work is current during componentDidMount/Update.
26816
26817 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
26818
26819 {
26820 markLayoutEffectsStarted(lanes);
26821 }
26822
26823 commitLayoutEffects(finishedWork, root, lanes);
26824
26825 {
26826 markLayoutEffectsStopped();
26827 }
26828 // opportunity to paint.
26829
26830
26831 requestPaint();
26832 executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value.
26833
26834 setCurrentUpdatePriority(previousPriority);
26835 ReactCurrentBatchConfig$3.transition = prevTransition;
26836 } else {
26837 // No effects.
26838 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
26839 // no effects.
26840 // TODO: Maybe there's a better way to report this.
26841
26842 {
26843 recordCommitTime();
26844 }
26845 }
26846
26847 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
26848
26849 if (rootDoesHavePassiveEffects) {
26850 // This commit has passive effects. Stash a reference to them. But don't
26851 // schedule a callback until after flushing layout work.
26852 rootDoesHavePassiveEffects = false;
26853 rootWithPendingPassiveEffects = root;
26854 pendingPassiveEffectsLanes = lanes;
26855 } else {
26856
26857 {
26858 nestedPassiveUpdateCount = 0;
26859 rootWithPassiveNestedUpdates = null;
26860 }
26861 } // Read this again, since an effect might have updated it
26862
26863
26864 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
26865 // TODO: This is part of the `componentDidCatch` implementation. Its purpose
26866 // is to detect whether something might have called setState inside
26867 // `componentDidCatch`. The mechanism is known to be flawed because `setState`
26868 // inside `componentDidCatch` is itself flawed — that's why we recommend
26869 // `getDerivedStateFromError` instead. However, it could be improved by
26870 // checking if remainingLanes includes Sync work, instead of whether there's
26871 // any work remaining at all (which would also include stuff like Suspense
26872 // retries or transitions). It's been like this for a while, though, so fixing
26873 // it probably isn't that urgent.
26874
26875 if (remainingLanes === NoLanes) {
26876 // If there's no remaining work, we can clear the set of already failed
26877 // error boundaries.
26878 legacyErrorBoundariesThatAlreadyFailed = null;
26879 }
26880
26881 {
26882 if (!rootDidHavePassiveEffects) {
26883 commitDoubleInvokeEffectsInDEV(root.current, false);
26884 }
26885 }
26886
26887 onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
26888
26889 {
26890 if (isDevToolsPresent) {
26891 root.memoizedUpdaters.clear();
26892 }
26893 }
26894
26895 {
26896 onCommitRoot$1();
26897 } // Always call this before exiting `commitRoot`, to ensure that any
26898 // additional work on this root is scheduled.
26899
26900
26901 ensureRootIsScheduled(root, now());
26902
26903 if (recoverableErrors !== null) {
26904 // There were errors during this render, but recovered from them without
26905 // needing to surface it to the UI. We log them here.
26906 var onRecoverableError = root.onRecoverableError;
26907
26908 for (var i = 0; i < recoverableErrors.length; i++) {
26909 var recoverableError = recoverableErrors[i];
26910 var componentStack = recoverableError.stack;
26911 var digest = recoverableError.digest;
26912 onRecoverableError(recoverableError.value, {
26913 componentStack: componentStack,
26914 digest: digest
26915 });
26916 }
26917 }
26918
26919 if (hasUncaughtError) {
26920 hasUncaughtError = false;
26921 var error$1 = firstUncaughtError;
26922 firstUncaughtError = null;
26923 throw error$1;
26924 } // If the passive effects are the result of a discrete render, flush them
26925 // synchronously at the end of the current task so that the result is
26926 // immediately observable. Otherwise, we assume that they are not
26927 // order-dependent and do not need to be observed by external systems, so we
26928 // can wait until after paint.
26929 // TODO: We can optimize this by not scheduling the callback earlier. Since we
26930 // currently schedule the callback in multiple places, will wait until those
26931 // are consolidated.
26932
26933
26934 if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root.tag !== LegacyRoot) {
26935 flushPassiveEffects();
26936 } // Read this again, since a passive effect might have updated it
26937
26938
26939 remainingLanes = root.pendingLanes;
26940
26941 if (includesSomeLane(remainingLanes, SyncLane)) {
26942 {
26943 markNestedUpdateScheduled();
26944 } // Count the number of times the root synchronously re-renders without
26945 // finishing. If there are too many, it indicates an infinite update loop.
26946
26947
26948 if (root === rootWithNestedUpdates) {
26949 nestedUpdateCount++;
26950 } else {
26951 nestedUpdateCount = 0;
26952 rootWithNestedUpdates = root;
26953 }
26954 } else {
26955 nestedUpdateCount = 0;
26956 } // If layout work was scheduled, flush it now.
26957
26958
26959 flushSyncCallbacks();
26960
26961 {
26962 markCommitStopped();
26963 }
26964
26965 return null;
26966}
26967
26968function flushPassiveEffects() {
26969 // Returns whether passive effects were flushed.
26970 // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should
26971 // probably just combine the two functions. I believe they were only separate
26972 // in the first place because we used to wrap it with
26973 // `Scheduler.runWithPriority`, which accepts a function. But now we track the
26974 // priority within React itself, so we can mutate the variable directly.
26975 if (rootWithPendingPassiveEffects !== null) {
26976 var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);
26977 var priority = lowerEventPriority(DefaultEventPriority, renderPriority);
26978 var prevTransition = ReactCurrentBatchConfig$3.transition;
26979 var previousPriority = getCurrentUpdatePriority();
26980
26981 try {
26982 ReactCurrentBatchConfig$3.transition = null;
26983 setCurrentUpdatePriority(priority);
26984 return flushPassiveEffectsImpl();
26985 } finally {
26986 setCurrentUpdatePriority(previousPriority);
26987 ReactCurrentBatchConfig$3.transition = prevTransition; // Once passive effects have run for the tree - giving components a
26988 }
26989 }
26990
26991 return false;
26992}
26993function enqueuePendingPassiveProfilerEffect(fiber) {
26994 {
26995 pendingPassiveProfilerEffects.push(fiber);
26996
26997 if (!rootDoesHavePassiveEffects) {
26998 rootDoesHavePassiveEffects = true;
26999 scheduleCallback$1(NormalPriority, function () {
27000 flushPassiveEffects();
27001 return null;
27002 });
27003 }
27004 }
27005}
27006
27007function flushPassiveEffectsImpl() {
27008 if (rootWithPendingPassiveEffects === null) {
27009 return false;
27010 } // Cache and clear the transitions flag
27011
27012
27013 var transitions = pendingPassiveTransitions;
27014 pendingPassiveTransitions = null;
27015 var root = rootWithPendingPassiveEffects;
27016 var lanes = pendingPassiveEffectsLanes;
27017 rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.
27018 // Figure out why and fix it. It's not causing any known issues (probably
27019 // because it's only used for profiling), but it's a refactor hazard.
27020
27021 pendingPassiveEffectsLanes = NoLanes;
27022
27023 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
27024 throw new Error('Cannot flush passive effects while already rendering.');
27025 }
27026
27027 {
27028 isFlushingPassiveEffects = true;
27029 didScheduleUpdateDuringPassiveEffects = false;
27030 }
27031
27032 {
27033 markPassiveEffectsStarted(lanes);
27034 }
27035
27036 var prevExecutionContext = executionContext;
27037 executionContext |= CommitContext;
27038 commitPassiveUnmountEffects(root.current);
27039 commitPassiveMountEffects(root, root.current, lanes, transitions); // TODO: Move to commitPassiveMountEffects
27040
27041 {
27042 var profilerEffects = pendingPassiveProfilerEffects;
27043 pendingPassiveProfilerEffects = [];
27044
27045 for (var i = 0; i < profilerEffects.length; i++) {
27046 var _fiber = profilerEffects[i];
27047 commitPassiveEffectDurations(root, _fiber);
27048 }
27049 }
27050
27051 {
27052 markPassiveEffectsStopped();
27053 }
27054
27055 {
27056 commitDoubleInvokeEffectsInDEV(root.current, true);
27057 }
27058
27059 executionContext = prevExecutionContext;
27060 flushSyncCallbacks();
27061
27062 {
27063 // If additional passive effects were scheduled, increment a counter. If this
27064 // exceeds the limit, we'll fire a warning.
27065 if (didScheduleUpdateDuringPassiveEffects) {
27066 if (root === rootWithPassiveNestedUpdates) {
27067 nestedPassiveUpdateCount++;
27068 } else {
27069 nestedPassiveUpdateCount = 0;
27070 rootWithPassiveNestedUpdates = root;
27071 }
27072 } else {
27073 nestedPassiveUpdateCount = 0;
27074 }
27075
27076 isFlushingPassiveEffects = false;
27077 didScheduleUpdateDuringPassiveEffects = false;
27078 } // TODO: Move to commitPassiveMountEffects
27079
27080
27081 onPostCommitRoot(root);
27082
27083 {
27084 var stateNode = root.current.stateNode;
27085 stateNode.effectDuration = 0;
27086 stateNode.passiveEffectDuration = 0;
27087 }
27088
27089 return true;
27090}
27091
27092function isAlreadyFailedLegacyErrorBoundary(instance) {
27093 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
27094}
27095function markLegacyErrorBoundaryAsFailed(instance) {
27096 if (legacyErrorBoundariesThatAlreadyFailed === null) {
27097 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
27098 } else {
27099 legacyErrorBoundariesThatAlreadyFailed.add(instance);
27100 }
27101}
27102
27103function prepareToThrowUncaughtError(error) {
27104 if (!hasUncaughtError) {
27105 hasUncaughtError = true;
27106 firstUncaughtError = error;
27107 }
27108}
27109
27110var onUncaughtError = prepareToThrowUncaughtError;
27111
27112function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
27113 var errorInfo = createCapturedValueAtFiber(error, sourceFiber);
27114 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
27115 var root = enqueueUpdate(rootFiber, update, SyncLane);
27116 var eventTime = requestEventTime();
27117
27118 if (root !== null) {
27119 markRootUpdated(root, SyncLane, eventTime);
27120 ensureRootIsScheduled(root, eventTime);
27121 }
27122}
27123
27124function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) {
27125 {
27126 reportUncaughtErrorInDEV(error$1);
27127 setIsRunningInsertionEffect(false);
27128 }
27129
27130 if (sourceFiber.tag === HostRoot) {
27131 // Error was thrown at the root. There is no parent, so the root
27132 // itself should capture it.
27133 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1);
27134 return;
27135 }
27136
27137 var fiber = null;
27138
27139 {
27140 fiber = nearestMountedAncestor;
27141 }
27142
27143 while (fiber !== null) {
27144 if (fiber.tag === HostRoot) {
27145 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1);
27146 return;
27147 } else if (fiber.tag === ClassComponent) {
27148 var ctor = fiber.type;
27149 var instance = fiber.stateNode;
27150
27151 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
27152 var errorInfo = createCapturedValueAtFiber(error$1, sourceFiber);
27153 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
27154 var root = enqueueUpdate(fiber, update, SyncLane);
27155 var eventTime = requestEventTime();
27156
27157 if (root !== null) {
27158 markRootUpdated(root, SyncLane, eventTime);
27159 ensureRootIsScheduled(root, eventTime);
27160 }
27161
27162 return;
27163 }
27164 }
27165
27166 fiber = fiber.return;
27167 }
27168
27169 {
27170 // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning
27171 // will fire for errors that are thrown by destroy functions inside deleted
27172 // trees. What it should instead do is propagate the error to the parent of
27173 // the deleted tree. In the meantime, do not add this warning to the
27174 // allowlist; this is only for our internal use.
27175 error('Internal React error: Attempted to capture a commit phase error ' + 'inside a detached tree. This indicates a bug in React. Likely ' + 'causes include deleting the same fiber more than once, committing an ' + 'already-finished tree, or an inconsistent return pointer.\n\n' + 'Error message:\n\n%s', error$1);
27176 }
27177}
27178function pingSuspendedRoot(root, wakeable, pingedLanes) {
27179 var pingCache = root.pingCache;
27180
27181 if (pingCache !== null) {
27182 // The wakeable resolved, so we no longer need to memoize, because it will
27183 // never be thrown again.
27184 pingCache.delete(wakeable);
27185 }
27186
27187 var eventTime = requestEventTime();
27188 markRootPinged(root, pingedLanes);
27189 warnIfSuspenseResolutionNotWrappedWithActDEV(root);
27190
27191 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
27192 // Received a ping at the same priority level at which we're currently
27193 // rendering. We might want to restart this render. This should mirror
27194 // the logic of whether or not a root suspends once it completes.
27195 // TODO: If we're rendering sync either due to Sync, Batched or expired,
27196 // we should probably never restart.
27197 // If we're suspended with delay, or if it's a retry, we'll always suspend
27198 // so we can always restart.
27199 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
27200 // Restart from the root.
27201 prepareFreshStack(root, NoLanes);
27202 } else {
27203 // Even though we can't restart right now, we might get an
27204 // opportunity later. So we mark this render as having a ping.
27205 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
27206 }
27207 }
27208
27209 ensureRootIsScheduled(root, eventTime);
27210}
27211
27212function retryTimedOutBoundary(boundaryFiber, retryLane) {
27213 // The boundary fiber (a Suspense component or SuspenseList component)
27214 // previously was rendered in its fallback state. One of the promises that
27215 // suspended it has resolved, which means at least part of the tree was
27216 // likely unblocked. Try rendering again, at a new lanes.
27217 if (retryLane === NoLane) {
27218 // TODO: Assign this to `suspenseState.retryLane`? to avoid
27219 // unnecessary entanglement?
27220 retryLane = requestRetryLane(boundaryFiber);
27221 } // TODO: Special case idle priority?
27222
27223
27224 var eventTime = requestEventTime();
27225 var root = enqueueConcurrentRenderForLane(boundaryFiber, retryLane);
27226
27227 if (root !== null) {
27228 markRootUpdated(root, retryLane, eventTime);
27229 ensureRootIsScheduled(root, eventTime);
27230 }
27231}
27232
27233function retryDehydratedSuspenseBoundary(boundaryFiber) {
27234 var suspenseState = boundaryFiber.memoizedState;
27235 var retryLane = NoLane;
27236
27237 if (suspenseState !== null) {
27238 retryLane = suspenseState.retryLane;
27239 }
27240
27241 retryTimedOutBoundary(boundaryFiber, retryLane);
27242}
27243function resolveRetryWakeable(boundaryFiber, wakeable) {
27244 var retryLane = NoLane; // Default
27245
27246 var retryCache;
27247
27248 switch (boundaryFiber.tag) {
27249 case SuspenseComponent:
27250 retryCache = boundaryFiber.stateNode;
27251 var suspenseState = boundaryFiber.memoizedState;
27252
27253 if (suspenseState !== null) {
27254 retryLane = suspenseState.retryLane;
27255 }
27256
27257 break;
27258
27259 case SuspenseListComponent:
27260 retryCache = boundaryFiber.stateNode;
27261 break;
27262
27263 default:
27264 throw new Error('Pinged unknown suspense boundary type. ' + 'This is probably a bug in React.');
27265 }
27266
27267 if (retryCache !== null) {
27268 // The wakeable resolved, so we no longer need to memoize, because it will
27269 // never be thrown again.
27270 retryCache.delete(wakeable);
27271 }
27272
27273 retryTimedOutBoundary(boundaryFiber, retryLane);
27274} // Computes the next Just Noticeable Difference (JND) boundary.
27275// The theory is that a person can't tell the difference between small differences in time.
27276// Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
27277// difference in the experience. However, waiting for longer might mean that we can avoid
27278// showing an intermediate loading state. The longer we have already waited, the harder it
27279// is to tell small differences in time. Therefore, the longer we've already waited,
27280// the longer we can wait additionally. At some point we have to give up though.
27281// We pick a train model where the next boundary commits at a consistent schedule.
27282// These particular numbers are vague estimates. We expect to adjust them based on research.
27283
27284function jnd(timeElapsed) {
27285 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
27286}
27287
27288function checkForNestedUpdates() {
27289 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
27290 nestedUpdateCount = 0;
27291 rootWithNestedUpdates = null;
27292 throw new 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.');
27293 }
27294
27295 {
27296 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
27297 nestedPassiveUpdateCount = 0;
27298 rootWithPassiveNestedUpdates = null;
27299
27300 error('Maximum update depth exceeded. This can happen when a component ' + "calls setState inside useEffect, but useEffect either doesn't " + 'have a dependency array, or one of the dependencies changes on ' + 'every render.');
27301 }
27302 }
27303}
27304
27305function flushRenderPhaseStrictModeWarningsInDEV() {
27306 {
27307 ReactStrictModeWarnings.flushLegacyContextWarning();
27308
27309 {
27310 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
27311 }
27312 }
27313}
27314
27315function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) {
27316 {
27317 // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects
27318 // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level.
27319 // Maybe not a big deal since this is DEV only behavior.
27320 setCurrentFiber(fiber);
27321 invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV);
27322
27323 if (hasPassiveEffects) {
27324 invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectUnmountInDEV);
27325 }
27326
27327 invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV);
27328
27329 if (hasPassiveEffects) {
27330 invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV);
27331 }
27332
27333 resetCurrentFiber();
27334 }
27335}
27336
27337function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) {
27338 {
27339 // We don't need to re-check StrictEffectsMode here.
27340 // This function is only called if that check has already passed.
27341 var current = firstChild;
27342 var subtreeRoot = null;
27343
27344 while (current !== null) {
27345 var primarySubtreeFlag = current.subtreeFlags & fiberFlags;
27346
27347 if (current !== subtreeRoot && current.child !== null && primarySubtreeFlag !== NoFlags) {
27348 current = current.child;
27349 } else {
27350 if ((current.flags & fiberFlags) !== NoFlags) {
27351 invokeEffectFn(current);
27352 }
27353
27354 if (current.sibling !== null) {
27355 current = current.sibling;
27356 } else {
27357 current = subtreeRoot = current.return;
27358 }
27359 }
27360 }
27361 }
27362}
27363
27364var didWarnStateUpdateForNotYetMountedComponent = null;
27365function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
27366 {
27367 if ((executionContext & RenderContext) !== NoContext) {
27368 // We let the other warning about render phase updates deal with this one.
27369 return;
27370 }
27371
27372 if (!(fiber.mode & ConcurrentMode)) {
27373 return;
27374 }
27375
27376 var tag = fiber.tag;
27377
27378 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
27379 // Only warn for user-defined components, not internal ones like Suspense.
27380 return;
27381 } // We show the whole stack but dedupe on the top component's name because
27382 // the problematic code almost always lies inside that component.
27383
27384
27385 var componentName = getComponentNameFromFiber(fiber) || 'ReactComponent';
27386
27387 if (didWarnStateUpdateForNotYetMountedComponent !== null) {
27388 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
27389 return;
27390 }
27391
27392 didWarnStateUpdateForNotYetMountedComponent.add(componentName);
27393 } else {
27394 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);
27395 }
27396
27397 var previousFiber = current;
27398
27399 try {
27400 setCurrentFiber(fiber);
27401
27402 error("Can't perform a React state update on a component that hasn't mounted yet. " + 'This indicates that you have a side-effect in your render function that ' + 'asynchronously later calls tries to update the component. Move this work to ' + 'useEffect instead.');
27403 } finally {
27404 if (previousFiber) {
27405 setCurrentFiber(fiber);
27406 } else {
27407 resetCurrentFiber();
27408 }
27409 }
27410 }
27411}
27412var beginWork$1;
27413
27414{
27415 var dummyFiber = null;
27416
27417 beginWork$1 = function (current, unitOfWork, lanes) {
27418 // If a component throws an error, we replay it again in a synchronously
27419 // dispatched event, so that the debugger will treat it as an uncaught
27420 // error See ReactErrorUtils for more information.
27421 // Before entering the begin phase, copy the work-in-progress onto a dummy
27422 // fiber. If beginWork throws, we'll use this to reset the state.
27423 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
27424
27425 try {
27426 return beginWork(current, unitOfWork, lanes);
27427 } catch (originalError) {
27428 if (didSuspendOrErrorWhileHydratingDEV() || originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
27429 // Don't replay promises.
27430 // Don't replay errors if we are hydrating and have already suspended or handled an error
27431 throw originalError;
27432 } // Keep this code in sync with handleError; any changes here must have
27433 // corresponding changes there.
27434
27435
27436 resetContextDependencies();
27437 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
27438 // same fiber again.
27439 // Unwind the failed stack frame
27440
27441 unwindInterruptedWork(current, unitOfWork); // Restore the original properties of the fiber.
27442
27443 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
27444
27445 if ( unitOfWork.mode & ProfileMode) {
27446 // Reset the profiler timer.
27447 startProfilerTimer(unitOfWork);
27448 } // Run beginWork again.
27449
27450
27451 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes);
27452
27453 if (hasCaughtError()) {
27454 var replayError = clearCaughtError();
27455
27456 if (typeof replayError === 'object' && replayError !== null && replayError._suppressLogging && typeof originalError === 'object' && originalError !== null && !originalError._suppressLogging) {
27457 // If suppressed, let the flag carry over to the original error which is the one we'll rethrow.
27458 originalError._suppressLogging = true;
27459 }
27460 } // We always throw the original error in case the second render pass is not idempotent.
27461 // This can happen if a memoized function or CommonJS module doesn't throw after first invocation.
27462
27463
27464 throw originalError;
27465 }
27466 };
27467}
27468
27469var didWarnAboutUpdateInRender = false;
27470var didWarnAboutUpdateInRenderForAnotherComponent;
27471
27472{
27473 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
27474}
27475
27476function warnAboutRenderPhaseUpdatesInDEV(fiber) {
27477 {
27478 if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {
27479 switch (fiber.tag) {
27480 case FunctionComponent:
27481 case ForwardRef:
27482 case SimpleMemoComponent:
27483 {
27484 var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
27485
27486 var dedupeKey = renderingComponentName;
27487
27488 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
27489 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
27490 var setStateComponentName = getComponentNameFromFiber(fiber) || 'Unknown';
27491
27492 error('Cannot update a component (`%s`) while rendering a ' + 'different component (`%s`). To locate the bad setState() call inside `%s`, ' + 'follow the stack trace as described in https://reactjs.org/link/setstate-in-render', setStateComponentName, renderingComponentName, renderingComponentName);
27493 }
27494
27495 break;
27496 }
27497
27498 case ClassComponent:
27499 {
27500 if (!didWarnAboutUpdateInRender) {
27501 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
27502
27503 didWarnAboutUpdateInRender = true;
27504 }
27505
27506 break;
27507 }
27508 }
27509 }
27510 }
27511}
27512
27513function restorePendingUpdaters(root, lanes) {
27514 {
27515 if (isDevToolsPresent) {
27516 var memoizedUpdaters = root.memoizedUpdaters;
27517 memoizedUpdaters.forEach(function (schedulingFiber) {
27518 addFiberToLanesMap(root, schedulingFiber, lanes);
27519 }); // This function intentionally does not clear memoized updaters.
27520 // Those may still be relevant to the current commit
27521 // and a future one (e.g. Suspense).
27522 }
27523 }
27524}
27525var fakeActCallbackNode = {};
27526
27527function scheduleCallback$1(priorityLevel, callback) {
27528 {
27529 // If we're currently inside an `act` scope, bypass Scheduler and push to
27530 // the `act` queue instead.
27531 var actQueue = ReactCurrentActQueue$1.current;
27532
27533 if (actQueue !== null) {
27534 actQueue.push(callback);
27535 return fakeActCallbackNode;
27536 } else {
27537 return scheduleCallback(priorityLevel, callback);
27538 }
27539 }
27540}
27541
27542function cancelCallback$1(callbackNode) {
27543 if ( callbackNode === fakeActCallbackNode) {
27544 return;
27545 } // In production, always call Scheduler. This function will be stripped out.
27546
27547
27548 return cancelCallback(callbackNode);
27549}
27550
27551function shouldForceFlushFallbacksInDEV() {
27552 // Never force flush in production. This function should get stripped out.
27553 return ReactCurrentActQueue$1.current !== null;
27554}
27555
27556function warnIfUpdatesNotWrappedWithActDEV(fiber) {
27557 {
27558 if (fiber.mode & ConcurrentMode) {
27559 if (!isConcurrentActEnvironment()) {
27560 // Not in an act environment. No need to warn.
27561 return;
27562 }
27563 } else {
27564 // Legacy mode has additional cases where we suppress a warning.
27565 if (!isLegacyActEnvironment()) {
27566 // Not in an act environment. No need to warn.
27567 return;
27568 }
27569
27570 if (executionContext !== NoContext) {
27571 // Legacy mode doesn't warn if the update is batched, i.e.
27572 // batchedUpdates or flushSync.
27573 return;
27574 }
27575
27576 if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) {
27577 // For backwards compatibility with pre-hooks code, legacy mode only
27578 // warns for updates that originate from a hook.
27579 return;
27580 }
27581 }
27582
27583 if (ReactCurrentActQueue$1.current === null) {
27584 var previousFiber = current;
27585
27586 try {
27587 setCurrentFiber(fiber);
27588
27589 error('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://reactjs.org/link/wrap-tests-with-act', getComponentNameFromFiber(fiber));
27590 } finally {
27591 if (previousFiber) {
27592 setCurrentFiber(fiber);
27593 } else {
27594 resetCurrentFiber();
27595 }
27596 }
27597 }
27598 }
27599}
27600
27601function warnIfSuspenseResolutionNotWrappedWithActDEV(root) {
27602 {
27603 if (root.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) {
27604 error('A suspended resource finished loading inside a test, but the event ' + 'was not wrapped in act(...).\n\n' + 'When testing, code that resolves suspended data should be wrapped ' + 'into act(...):\n\n' + 'act(() => {\n' + ' /* finish loading suspended data */\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://reactjs.org/link/wrap-tests-with-act');
27605 }
27606 }
27607}
27608
27609function setIsRunningInsertionEffect(isRunning) {
27610 {
27611 isRunningInsertionEffect = isRunning;
27612 }
27613}
27614
27615/* eslint-disable react-internal/prod-error-codes */
27616var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
27617
27618var failedBoundaries = null;
27619var setRefreshHandler = function (handler) {
27620 {
27621 resolveFamily = handler;
27622 }
27623};
27624function resolveFunctionForHotReloading(type) {
27625 {
27626 if (resolveFamily === null) {
27627 // Hot reloading is disabled.
27628 return type;
27629 }
27630
27631 var family = resolveFamily(type);
27632
27633 if (family === undefined) {
27634 return type;
27635 } // Use the latest known implementation.
27636
27637
27638 return family.current;
27639 }
27640}
27641function resolveClassForHotReloading(type) {
27642 // No implementation differences.
27643 return resolveFunctionForHotReloading(type);
27644}
27645function resolveForwardRefForHotReloading(type) {
27646 {
27647 if (resolveFamily === null) {
27648 // Hot reloading is disabled.
27649 return type;
27650 }
27651
27652 var family = resolveFamily(type);
27653
27654 if (family === undefined) {
27655 // Check if we're dealing with a real forwardRef. Don't want to crash early.
27656 if (type !== null && type !== undefined && typeof type.render === 'function') {
27657 // ForwardRef is special because its resolved .type is an object,
27658 // but it's possible that we only have its inner render function in the map.
27659 // If that inner render function is different, we'll build a new forwardRef type.
27660 var currentRender = resolveFunctionForHotReloading(type.render);
27661
27662 if (type.render !== currentRender) {
27663 var syntheticType = {
27664 $$typeof: REACT_FORWARD_REF_TYPE,
27665 render: currentRender
27666 };
27667
27668 if (type.displayName !== undefined) {
27669 syntheticType.displayName = type.displayName;
27670 }
27671
27672 return syntheticType;
27673 }
27674 }
27675
27676 return type;
27677 } // Use the latest known implementation.
27678
27679
27680 return family.current;
27681 }
27682}
27683function isCompatibleFamilyForHotReloading(fiber, element) {
27684 {
27685 if (resolveFamily === null) {
27686 // Hot reloading is disabled.
27687 return false;
27688 }
27689
27690 var prevType = fiber.elementType;
27691 var nextType = element.type; // If we got here, we know types aren't === equal.
27692
27693 var needsCompareFamilies = false;
27694 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
27695
27696 switch (fiber.tag) {
27697 case ClassComponent:
27698 {
27699 if (typeof nextType === 'function') {
27700 needsCompareFamilies = true;
27701 }
27702
27703 break;
27704 }
27705
27706 case FunctionComponent:
27707 {
27708 if (typeof nextType === 'function') {
27709 needsCompareFamilies = true;
27710 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27711 // We don't know the inner type yet.
27712 // We're going to assume that the lazy inner type is stable,
27713 // and so it is sufficient to avoid reconciling it away.
27714 // We're not going to unwrap or actually use the new lazy type.
27715 needsCompareFamilies = true;
27716 }
27717
27718 break;
27719 }
27720
27721 case ForwardRef:
27722 {
27723 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
27724 needsCompareFamilies = true;
27725 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27726 needsCompareFamilies = true;
27727 }
27728
27729 break;
27730 }
27731
27732 case MemoComponent:
27733 case SimpleMemoComponent:
27734 {
27735 if ($$typeofNextType === REACT_MEMO_TYPE) {
27736 // TODO: if it was but can no longer be simple,
27737 // we shouldn't set this.
27738 needsCompareFamilies = true;
27739 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27740 needsCompareFamilies = true;
27741 }
27742
27743 break;
27744 }
27745
27746 default:
27747 return false;
27748 } // Check if both types have a family and it's the same one.
27749
27750
27751 if (needsCompareFamilies) {
27752 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
27753 // This means both of them need to be registered to preserve state.
27754 // If we unwrapped and compared the inner types for wrappers instead,
27755 // then we would risk falsely saying two separate memo(Foo)
27756 // calls are equivalent because they wrap the same Foo function.
27757 var prevFamily = resolveFamily(prevType);
27758
27759 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
27760 return true;
27761 }
27762 }
27763
27764 return false;
27765 }
27766}
27767function markFailedErrorBoundaryForHotReloading(fiber) {
27768 {
27769 if (resolveFamily === null) {
27770 // Hot reloading is disabled.
27771 return;
27772 }
27773
27774 if (typeof WeakSet !== 'function') {
27775 return;
27776 }
27777
27778 if (failedBoundaries === null) {
27779 failedBoundaries = new WeakSet();
27780 }
27781
27782 failedBoundaries.add(fiber);
27783 }
27784}
27785var scheduleRefresh = function (root, update) {
27786 {
27787 if (resolveFamily === null) {
27788 // Hot reloading is disabled.
27789 return;
27790 }
27791
27792 var staleFamilies = update.staleFamilies,
27793 updatedFamilies = update.updatedFamilies;
27794 flushPassiveEffects();
27795 flushSync(function () {
27796 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
27797 });
27798 }
27799};
27800var scheduleRoot = function (root, element) {
27801 {
27802 if (root.context !== emptyContextObject) {
27803 // Super edge case: root has a legacy _renderSubtree context
27804 // but we don't know the parentComponent so we can't pass it.
27805 // Just ignore. We'll delete this with _renderSubtree code path later.
27806 return;
27807 }
27808
27809 flushPassiveEffects();
27810 flushSync(function () {
27811 updateContainer(element, root, null, null);
27812 });
27813 }
27814};
27815
27816function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
27817 {
27818 var alternate = fiber.alternate,
27819 child = fiber.child,
27820 sibling = fiber.sibling,
27821 tag = fiber.tag,
27822 type = fiber.type;
27823 var candidateType = null;
27824
27825 switch (tag) {
27826 case FunctionComponent:
27827 case SimpleMemoComponent:
27828 case ClassComponent:
27829 candidateType = type;
27830 break;
27831
27832 case ForwardRef:
27833 candidateType = type.render;
27834 break;
27835 }
27836
27837 if (resolveFamily === null) {
27838 throw new Error('Expected resolveFamily to be set during hot reload.');
27839 }
27840
27841 var needsRender = false;
27842 var needsRemount = false;
27843
27844 if (candidateType !== null) {
27845 var family = resolveFamily(candidateType);
27846
27847 if (family !== undefined) {
27848 if (staleFamilies.has(family)) {
27849 needsRemount = true;
27850 } else if (updatedFamilies.has(family)) {
27851 if (tag === ClassComponent) {
27852 needsRemount = true;
27853 } else {
27854 needsRender = true;
27855 }
27856 }
27857 }
27858 }
27859
27860 if (failedBoundaries !== null) {
27861 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
27862 needsRemount = true;
27863 }
27864 }
27865
27866 if (needsRemount) {
27867 fiber._debugNeedsRemount = true;
27868 }
27869
27870 if (needsRemount || needsRender) {
27871 var _root = enqueueConcurrentRenderForLane(fiber, SyncLane);
27872
27873 if (_root !== null) {
27874 scheduleUpdateOnFiber(_root, fiber, SyncLane, NoTimestamp);
27875 }
27876 }
27877
27878 if (child !== null && !needsRemount) {
27879 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
27880 }
27881
27882 if (sibling !== null) {
27883 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
27884 }
27885 }
27886}
27887
27888var findHostInstancesForRefresh = function (root, families) {
27889 {
27890 var hostInstances = new Set();
27891 var types = new Set(families.map(function (family) {
27892 return family.current;
27893 }));
27894 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
27895 return hostInstances;
27896 }
27897};
27898
27899function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
27900 {
27901 var child = fiber.child,
27902 sibling = fiber.sibling,
27903 tag = fiber.tag,
27904 type = fiber.type;
27905 var candidateType = null;
27906
27907 switch (tag) {
27908 case FunctionComponent:
27909 case SimpleMemoComponent:
27910 case ClassComponent:
27911 candidateType = type;
27912 break;
27913
27914 case ForwardRef:
27915 candidateType = type.render;
27916 break;
27917 }
27918
27919 var didMatch = false;
27920
27921 if (candidateType !== null) {
27922 if (types.has(candidateType)) {
27923 didMatch = true;
27924 }
27925 }
27926
27927 if (didMatch) {
27928 // We have a match. This only drills down to the closest host components.
27929 // There's no need to search deeper because for the purpose of giving
27930 // visual feedback, "flashing" outermost parent rectangles is sufficient.
27931 findHostInstancesForFiberShallowly(fiber, hostInstances);
27932 } else {
27933 // If there's no match, maybe there will be one further down in the child tree.
27934 if (child !== null) {
27935 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
27936 }
27937 }
27938
27939 if (sibling !== null) {
27940 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
27941 }
27942 }
27943}
27944
27945function findHostInstancesForFiberShallowly(fiber, hostInstances) {
27946 {
27947 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
27948
27949 if (foundHostInstances) {
27950 return;
27951 } // If we didn't find any host children, fallback to closest host parent.
27952
27953
27954 var node = fiber;
27955
27956 while (true) {
27957 switch (node.tag) {
27958 case HostComponent:
27959 hostInstances.add(node.stateNode);
27960 return;
27961
27962 case HostPortal:
27963 hostInstances.add(node.stateNode.containerInfo);
27964 return;
27965
27966 case HostRoot:
27967 hostInstances.add(node.stateNode.containerInfo);
27968 return;
27969 }
27970
27971 if (node.return === null) {
27972 throw new Error('Expected to reach root first.');
27973 }
27974
27975 node = node.return;
27976 }
27977 }
27978}
27979
27980function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
27981 {
27982 var node = fiber;
27983 var foundHostInstances = false;
27984
27985 while (true) {
27986 if (node.tag === HostComponent) {
27987 // We got a match.
27988 foundHostInstances = true;
27989 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
27990 } else if (node.child !== null) {
27991 node.child.return = node;
27992 node = node.child;
27993 continue;
27994 }
27995
27996 if (node === fiber) {
27997 return foundHostInstances;
27998 }
27999
28000 while (node.sibling === null) {
28001 if (node.return === null || node.return === fiber) {
28002 return foundHostInstances;
28003 }
28004
28005 node = node.return;
28006 }
28007
28008 node.sibling.return = node.return;
28009 node = node.sibling;
28010 }
28011 }
28012
28013 return false;
28014}
28015
28016var hasBadMapPolyfill;
28017
28018{
28019 hasBadMapPolyfill = false;
28020
28021 try {
28022 var nonExtensibleObject = Object.preventExtensions({});
28023 /* eslint-disable no-new */
28024
28025 new Map([[nonExtensibleObject, null]]);
28026 new Set([nonExtensibleObject]);
28027 /* eslint-enable no-new */
28028 } catch (e) {
28029 // TODO: Consider warning about bad polyfills
28030 hasBadMapPolyfill = true;
28031 }
28032}
28033
28034function FiberNode(tag, pendingProps, key, mode) {
28035 // Instance
28036 this.tag = tag;
28037 this.key = key;
28038 this.elementType = null;
28039 this.type = null;
28040 this.stateNode = null; // Fiber
28041
28042 this.return = null;
28043 this.child = null;
28044 this.sibling = null;
28045 this.index = 0;
28046 this.ref = null;
28047 this.pendingProps = pendingProps;
28048 this.memoizedProps = null;
28049 this.updateQueue = null;
28050 this.memoizedState = null;
28051 this.dependencies = null;
28052 this.mode = mode; // Effects
28053
28054 this.flags = NoFlags;
28055 this.subtreeFlags = NoFlags;
28056 this.deletions = null;
28057 this.lanes = NoLanes;
28058 this.childLanes = NoLanes;
28059 this.alternate = null;
28060
28061 {
28062 // Note: The following is done to avoid a v8 performance cliff.
28063 //
28064 // Initializing the fields below to smis and later updating them with
28065 // double values will cause Fibers to end up having separate shapes.
28066 // This behavior/bug has something to do with Object.preventExtension().
28067 // Fortunately this only impacts DEV builds.
28068 // Unfortunately it makes React unusably slow for some applications.
28069 // To work around this, initialize the fields below with doubles.
28070 //
28071 // Learn more about this here:
28072 // https://github.com/facebook/react/issues/14365
28073 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
28074 this.actualDuration = Number.NaN;
28075 this.actualStartTime = Number.NaN;
28076 this.selfBaseDuration = Number.NaN;
28077 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
28078 // This won't trigger the performance cliff mentioned above,
28079 // and it simplifies other profiler code (including DevTools).
28080
28081 this.actualDuration = 0;
28082 this.actualStartTime = -1;
28083 this.selfBaseDuration = 0;
28084 this.treeBaseDuration = 0;
28085 }
28086
28087 {
28088 // This isn't directly used but is handy for debugging internals:
28089 this._debugSource = null;
28090 this._debugOwner = null;
28091 this._debugNeedsRemount = false;
28092 this._debugHookTypes = null;
28093
28094 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
28095 Object.preventExtensions(this);
28096 }
28097 }
28098} // This is a constructor function, rather than a POJO constructor, still
28099// please ensure we do the following:
28100// 1) Nobody should add any instance methods on this. Instance methods can be
28101// more difficult to predict when they get optimized and they are almost
28102// never inlined properly in static compilers.
28103// 2) Nobody should rely on `instanceof Fiber` for type testing. We should
28104// always know when it is a fiber.
28105// 3) We might want to experiment with using numeric keys since they are easier
28106// to optimize in a non-JIT environment.
28107// 4) We can easily go from a constructor to a createFiber object literal if that
28108// is faster.
28109// 5) It should be easy to port this to a C struct and keep a C implementation
28110// compatible.
28111
28112
28113var createFiber = function (tag, pendingProps, key, mode) {
28114 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
28115 return new FiberNode(tag, pendingProps, key, mode);
28116};
28117
28118function shouldConstruct$1(Component) {
28119 var prototype = Component.prototype;
28120 return !!(prototype && prototype.isReactComponent);
28121}
28122
28123function isSimpleFunctionComponent(type) {
28124 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined;
28125}
28126function resolveLazyComponentTag(Component) {
28127 if (typeof Component === 'function') {
28128 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
28129 } else if (Component !== undefined && Component !== null) {
28130 var $$typeof = Component.$$typeof;
28131
28132 if ($$typeof === REACT_FORWARD_REF_TYPE) {
28133 return ForwardRef;
28134 }
28135
28136 if ($$typeof === REACT_MEMO_TYPE) {
28137 return MemoComponent;
28138 }
28139 }
28140
28141 return IndeterminateComponent;
28142} // This is used to create an alternate fiber to do work on.
28143
28144function createWorkInProgress(current, pendingProps) {
28145 var workInProgress = current.alternate;
28146
28147 if (workInProgress === null) {
28148 // We use a double buffering pooling technique because we know that we'll
28149 // only ever need at most two versions of a tree. We pool the "other" unused
28150 // node that we're free to reuse. This is lazily created to avoid allocating
28151 // extra objects for things that are never updated. It also allow us to
28152 // reclaim the extra memory if needed.
28153 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
28154 workInProgress.elementType = current.elementType;
28155 workInProgress.type = current.type;
28156 workInProgress.stateNode = current.stateNode;
28157
28158 {
28159 // DEV-only fields
28160 workInProgress._debugSource = current._debugSource;
28161 workInProgress._debugOwner = current._debugOwner;
28162 workInProgress._debugHookTypes = current._debugHookTypes;
28163 }
28164
28165 workInProgress.alternate = current;
28166 current.alternate = workInProgress;
28167 } else {
28168 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
28169
28170 workInProgress.type = current.type; // We already have an alternate.
28171 // Reset the effect tag.
28172
28173 workInProgress.flags = NoFlags; // The effects are no longer valid.
28174
28175 workInProgress.subtreeFlags = NoFlags;
28176 workInProgress.deletions = null;
28177
28178 {
28179 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
28180 // This prevents time from endlessly accumulating in new commits.
28181 // This has the downside of resetting values for different priority renders,
28182 // But works for yielding (the common case) and should support resuming.
28183 workInProgress.actualDuration = 0;
28184 workInProgress.actualStartTime = -1;
28185 }
28186 } // Reset all effects except static ones.
28187 // Static effects are not specific to a render.
28188
28189
28190 workInProgress.flags = current.flags & StaticMask;
28191 workInProgress.childLanes = current.childLanes;
28192 workInProgress.lanes = current.lanes;
28193 workInProgress.child = current.child;
28194 workInProgress.memoizedProps = current.memoizedProps;
28195 workInProgress.memoizedState = current.memoizedState;
28196 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
28197 // it cannot be shared with the current fiber.
28198
28199 var currentDependencies = current.dependencies;
28200 workInProgress.dependencies = currentDependencies === null ? null : {
28201 lanes: currentDependencies.lanes,
28202 firstContext: currentDependencies.firstContext
28203 }; // These will be overridden during the parent's reconciliation
28204
28205 workInProgress.sibling = current.sibling;
28206 workInProgress.index = current.index;
28207 workInProgress.ref = current.ref;
28208
28209 {
28210 workInProgress.selfBaseDuration = current.selfBaseDuration;
28211 workInProgress.treeBaseDuration = current.treeBaseDuration;
28212 }
28213
28214 {
28215 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
28216
28217 switch (workInProgress.tag) {
28218 case IndeterminateComponent:
28219 case FunctionComponent:
28220 case SimpleMemoComponent:
28221 workInProgress.type = resolveFunctionForHotReloading(current.type);
28222 break;
28223
28224 case ClassComponent:
28225 workInProgress.type = resolveClassForHotReloading(current.type);
28226 break;
28227
28228 case ForwardRef:
28229 workInProgress.type = resolveForwardRefForHotReloading(current.type);
28230 break;
28231 }
28232 }
28233
28234 return workInProgress;
28235} // Used to reuse a Fiber for a second pass.
28236
28237function resetWorkInProgress(workInProgress, renderLanes) {
28238 // This resets the Fiber to what createFiber or createWorkInProgress would
28239 // have set the values to before during the first pass. Ideally this wouldn't
28240 // be necessary but unfortunately many code paths reads from the workInProgress
28241 // when they should be reading from current and writing to workInProgress.
28242 // We assume pendingProps, index, key, ref, return are still untouched to
28243 // avoid doing another reconciliation.
28244 // Reset the effect flags but keep any Placement tags, since that's something
28245 // that child fiber is setting, not the reconciliation.
28246 workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid.
28247
28248 var current = workInProgress.alternate;
28249
28250 if (current === null) {
28251 // Reset to createFiber's initial values.
28252 workInProgress.childLanes = NoLanes;
28253 workInProgress.lanes = renderLanes;
28254 workInProgress.child = null;
28255 workInProgress.subtreeFlags = NoFlags;
28256 workInProgress.memoizedProps = null;
28257 workInProgress.memoizedState = null;
28258 workInProgress.updateQueue = null;
28259 workInProgress.dependencies = null;
28260 workInProgress.stateNode = null;
28261
28262 {
28263 // Note: We don't reset the actualTime counts. It's useful to accumulate
28264 // actual time across multiple render passes.
28265 workInProgress.selfBaseDuration = 0;
28266 workInProgress.treeBaseDuration = 0;
28267 }
28268 } else {
28269 // Reset to the cloned values that createWorkInProgress would've.
28270 workInProgress.childLanes = current.childLanes;
28271 workInProgress.lanes = current.lanes;
28272 workInProgress.child = current.child;
28273 workInProgress.subtreeFlags = NoFlags;
28274 workInProgress.deletions = null;
28275 workInProgress.memoizedProps = current.memoizedProps;
28276 workInProgress.memoizedState = current.memoizedState;
28277 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
28278
28279 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
28280 // it cannot be shared with the current fiber.
28281
28282 var currentDependencies = current.dependencies;
28283 workInProgress.dependencies = currentDependencies === null ? null : {
28284 lanes: currentDependencies.lanes,
28285 firstContext: currentDependencies.firstContext
28286 };
28287
28288 {
28289 // Note: We don't reset the actualTime counts. It's useful to accumulate
28290 // actual time across multiple render passes.
28291 workInProgress.selfBaseDuration = current.selfBaseDuration;
28292 workInProgress.treeBaseDuration = current.treeBaseDuration;
28293 }
28294 }
28295
28296 return workInProgress;
28297}
28298function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) {
28299 var mode;
28300
28301 if (tag === ConcurrentRoot) {
28302 mode = ConcurrentMode;
28303
28304 if (isStrictMode === true) {
28305 mode |= StrictLegacyMode;
28306
28307 {
28308 mode |= StrictEffectsMode;
28309 }
28310 }
28311 } else {
28312 mode = NoMode;
28313 }
28314
28315 if ( isDevToolsPresent) {
28316 // Always collect profile timings when DevTools are present.
28317 // This enables DevTools to start capturing timing at any point–
28318 // Without some nodes in the tree having empty base times.
28319 mode |= ProfileMode;
28320 }
28321
28322 return createFiber(HostRoot, null, null, mode);
28323}
28324function createFiberFromTypeAndProps(type, // React$ElementType
28325key, pendingProps, owner, mode, lanes) {
28326 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
28327
28328 var resolvedType = type;
28329
28330 if (typeof type === 'function') {
28331 if (shouldConstruct$1(type)) {
28332 fiberTag = ClassComponent;
28333
28334 {
28335 resolvedType = resolveClassForHotReloading(resolvedType);
28336 }
28337 } else {
28338 {
28339 resolvedType = resolveFunctionForHotReloading(resolvedType);
28340 }
28341 }
28342 } else if (typeof type === 'string') {
28343 fiberTag = HostComponent;
28344 } else {
28345 getTag: switch (type) {
28346 case REACT_FRAGMENT_TYPE:
28347 return createFiberFromFragment(pendingProps.children, mode, lanes, key);
28348
28349 case REACT_STRICT_MODE_TYPE:
28350 fiberTag = Mode;
28351 mode |= StrictLegacyMode;
28352
28353 if ( (mode & ConcurrentMode) !== NoMode) {
28354 // Strict effects should never run on legacy roots
28355 mode |= StrictEffectsMode;
28356 }
28357
28358 break;
28359
28360 case REACT_PROFILER_TYPE:
28361 return createFiberFromProfiler(pendingProps, mode, lanes, key);
28362
28363 case REACT_SUSPENSE_TYPE:
28364 return createFiberFromSuspense(pendingProps, mode, lanes, key);
28365
28366 case REACT_SUSPENSE_LIST_TYPE:
28367 return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
28368
28369 case REACT_OFFSCREEN_TYPE:
28370 return createFiberFromOffscreen(pendingProps, mode, lanes, key);
28371
28372 case REACT_LEGACY_HIDDEN_TYPE:
28373
28374 // eslint-disable-next-line no-fallthrough
28375
28376 case REACT_SCOPE_TYPE:
28377
28378 // eslint-disable-next-line no-fallthrough
28379
28380 case REACT_CACHE_TYPE:
28381
28382 // eslint-disable-next-line no-fallthrough
28383
28384 case REACT_TRACING_MARKER_TYPE:
28385
28386 // eslint-disable-next-line no-fallthrough
28387
28388 case REACT_DEBUG_TRACING_MODE_TYPE:
28389
28390 // eslint-disable-next-line no-fallthrough
28391
28392 default:
28393 {
28394 if (typeof type === 'object' && type !== null) {
28395 switch (type.$$typeof) {
28396 case REACT_PROVIDER_TYPE:
28397 fiberTag = ContextProvider;
28398 break getTag;
28399
28400 case REACT_CONTEXT_TYPE:
28401 // This is a consumer
28402 fiberTag = ContextConsumer;
28403 break getTag;
28404
28405 case REACT_FORWARD_REF_TYPE:
28406 fiberTag = ForwardRef;
28407
28408 {
28409 resolvedType = resolveForwardRefForHotReloading(resolvedType);
28410 }
28411
28412 break getTag;
28413
28414 case REACT_MEMO_TYPE:
28415 fiberTag = MemoComponent;
28416 break getTag;
28417
28418 case REACT_LAZY_TYPE:
28419 fiberTag = LazyComponent;
28420 resolvedType = null;
28421 break getTag;
28422 }
28423 }
28424
28425 var info = '';
28426
28427 {
28428 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
28429 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.';
28430 }
28431
28432 var ownerName = owner ? getComponentNameFromFiber(owner) : null;
28433
28434 if (ownerName) {
28435 info += '\n\nCheck the render method of `' + ownerName + '`.';
28436 }
28437 }
28438
28439 throw new 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));
28440 }
28441 }
28442 }
28443
28444 var fiber = createFiber(fiberTag, pendingProps, key, mode);
28445 fiber.elementType = type;
28446 fiber.type = resolvedType;
28447 fiber.lanes = lanes;
28448
28449 {
28450 fiber._debugOwner = owner;
28451 }
28452
28453 return fiber;
28454}
28455function createFiberFromElement(element, mode, lanes) {
28456 var owner = null;
28457
28458 {
28459 owner = element._owner;
28460 }
28461
28462 var type = element.type;
28463 var key = element.key;
28464 var pendingProps = element.props;
28465 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
28466
28467 {
28468 fiber._debugSource = element._source;
28469 fiber._debugOwner = element._owner;
28470 }
28471
28472 return fiber;
28473}
28474function createFiberFromFragment(elements, mode, lanes, key) {
28475 var fiber = createFiber(Fragment, elements, key, mode);
28476 fiber.lanes = lanes;
28477 return fiber;
28478}
28479
28480function createFiberFromProfiler(pendingProps, mode, lanes, key) {
28481 {
28482 if (typeof pendingProps.id !== 'string') {
28483 error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id);
28484 }
28485 }
28486
28487 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
28488 fiber.elementType = REACT_PROFILER_TYPE;
28489 fiber.lanes = lanes;
28490
28491 {
28492 fiber.stateNode = {
28493 effectDuration: 0,
28494 passiveEffectDuration: 0
28495 };
28496 }
28497
28498 return fiber;
28499}
28500
28501function createFiberFromSuspense(pendingProps, mode, lanes, key) {
28502 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
28503 fiber.elementType = REACT_SUSPENSE_TYPE;
28504 fiber.lanes = lanes;
28505 return fiber;
28506}
28507function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
28508 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
28509 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
28510 fiber.lanes = lanes;
28511 return fiber;
28512}
28513function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
28514 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
28515 fiber.elementType = REACT_OFFSCREEN_TYPE;
28516 fiber.lanes = lanes;
28517 var primaryChildInstance = {
28518 isHidden: false
28519 };
28520 fiber.stateNode = primaryChildInstance;
28521 return fiber;
28522}
28523function createFiberFromText(content, mode, lanes) {
28524 var fiber = createFiber(HostText, content, null, mode);
28525 fiber.lanes = lanes;
28526 return fiber;
28527}
28528function createFiberFromHostInstanceForDeletion() {
28529 var fiber = createFiber(HostComponent, null, null, NoMode);
28530 fiber.elementType = 'DELETED';
28531 return fiber;
28532}
28533function createFiberFromDehydratedFragment(dehydratedNode) {
28534 var fiber = createFiber(DehydratedFragment, null, null, NoMode);
28535 fiber.stateNode = dehydratedNode;
28536 return fiber;
28537}
28538function createFiberFromPortal(portal, mode, lanes) {
28539 var pendingProps = portal.children !== null ? portal.children : [];
28540 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
28541 fiber.lanes = lanes;
28542 fiber.stateNode = {
28543 containerInfo: portal.containerInfo,
28544 pendingChildren: null,
28545 // Used by persistent updates
28546 implementation: portal.implementation
28547 };
28548 return fiber;
28549} // Used for stashing WIP properties to replay failed work in DEV.
28550
28551function assignFiberPropertiesInDEV(target, source) {
28552 if (target === null) {
28553 // This Fiber's initial properties will always be overwritten.
28554 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
28555 target = createFiber(IndeterminateComponent, null, null, NoMode);
28556 } // This is intentionally written as a list of all properties.
28557 // We tried to use Object.assign() instead but this is called in
28558 // the hottest path, and Object.assign() was too slow:
28559 // https://github.com/facebook/react/issues/12502
28560 // This code is DEV-only so size is not a concern.
28561
28562
28563 target.tag = source.tag;
28564 target.key = source.key;
28565 target.elementType = source.elementType;
28566 target.type = source.type;
28567 target.stateNode = source.stateNode;
28568 target.return = source.return;
28569 target.child = source.child;
28570 target.sibling = source.sibling;
28571 target.index = source.index;
28572 target.ref = source.ref;
28573 target.pendingProps = source.pendingProps;
28574 target.memoizedProps = source.memoizedProps;
28575 target.updateQueue = source.updateQueue;
28576 target.memoizedState = source.memoizedState;
28577 target.dependencies = source.dependencies;
28578 target.mode = source.mode;
28579 target.flags = source.flags;
28580 target.subtreeFlags = source.subtreeFlags;
28581 target.deletions = source.deletions;
28582 target.lanes = source.lanes;
28583 target.childLanes = source.childLanes;
28584 target.alternate = source.alternate;
28585
28586 {
28587 target.actualDuration = source.actualDuration;
28588 target.actualStartTime = source.actualStartTime;
28589 target.selfBaseDuration = source.selfBaseDuration;
28590 target.treeBaseDuration = source.treeBaseDuration;
28591 }
28592
28593 target._debugSource = source._debugSource;
28594 target._debugOwner = source._debugOwner;
28595 target._debugNeedsRemount = source._debugNeedsRemount;
28596 target._debugHookTypes = source._debugHookTypes;
28597 return target;
28598}
28599
28600function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError) {
28601 this.tag = tag;
28602 this.containerInfo = containerInfo;
28603 this.pendingChildren = null;
28604 this.current = null;
28605 this.pingCache = null;
28606 this.finishedWork = null;
28607 this.timeoutHandle = noTimeout;
28608 this.context = null;
28609 this.pendingContext = null;
28610 this.callbackNode = null;
28611 this.callbackPriority = NoLane;
28612 this.eventTimes = createLaneMap(NoLanes);
28613 this.expirationTimes = createLaneMap(NoTimestamp);
28614 this.pendingLanes = NoLanes;
28615 this.suspendedLanes = NoLanes;
28616 this.pingedLanes = NoLanes;
28617 this.expiredLanes = NoLanes;
28618 this.mutableReadLanes = NoLanes;
28619 this.finishedLanes = NoLanes;
28620 this.entangledLanes = NoLanes;
28621 this.entanglements = createLaneMap(NoLanes);
28622 this.identifierPrefix = identifierPrefix;
28623 this.onRecoverableError = onRecoverableError;
28624
28625 {
28626 this.mutableSourceEagerHydrationData = null;
28627 }
28628
28629 {
28630 this.effectDuration = 0;
28631 this.passiveEffectDuration = 0;
28632 }
28633
28634 {
28635 this.memoizedUpdaters = new Set();
28636 var pendingUpdatersLaneMap = this.pendingUpdatersLaneMap = [];
28637
28638 for (var _i = 0; _i < TotalLanes; _i++) {
28639 pendingUpdatersLaneMap.push(new Set());
28640 }
28641 }
28642
28643 {
28644 switch (tag) {
28645 case ConcurrentRoot:
28646 this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()';
28647 break;
28648
28649 case LegacyRoot:
28650 this._debugRootType = hydrate ? 'hydrate()' : 'render()';
28651 break;
28652 }
28653 }
28654}
28655
28656function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the
28657// host config, but because they are passed in at runtime, we have to thread
28658// them through the root constructor. Perhaps we should put them all into a
28659// single type, like a DynamicHostConfig that is defined by the renderer.
28660identifierPrefix, onRecoverableError, transitionCallbacks) {
28661 var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError);
28662 // stateNode is any.
28663
28664
28665 var uninitializedFiber = createHostRootFiber(tag, isStrictMode);
28666 root.current = uninitializedFiber;
28667 uninitializedFiber.stateNode = root;
28668
28669 {
28670 var _initialState = {
28671 element: initialChildren,
28672 isDehydrated: hydrate,
28673 cache: null,
28674 // not enabled yet
28675 transitions: null,
28676 pendingSuspenseBoundaries: null
28677 };
28678 uninitializedFiber.memoizedState = _initialState;
28679 }
28680
28681 initializeUpdateQueue(uninitializedFiber);
28682 return root;
28683}
28684
28685var ReactVersion = '18.2.0';
28686
28687function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
28688implementation) {
28689 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
28690
28691 {
28692 checkKeyStringCoercion(key);
28693 }
28694
28695 return {
28696 // This tag allow us to uniquely identify this as a React Portal
28697 $$typeof: REACT_PORTAL_TYPE,
28698 key: key == null ? null : '' + key,
28699 children: children,
28700 containerInfo: containerInfo,
28701 implementation: implementation
28702 };
28703}
28704
28705var didWarnAboutNestedUpdates;
28706var didWarnAboutFindNodeInStrictMode;
28707
28708{
28709 didWarnAboutNestedUpdates = false;
28710 didWarnAboutFindNodeInStrictMode = {};
28711}
28712
28713function getContextForSubtree(parentComponent) {
28714 if (!parentComponent) {
28715 return emptyContextObject;
28716 }
28717
28718 var fiber = get(parentComponent);
28719 var parentContext = findCurrentUnmaskedContext(fiber);
28720
28721 if (fiber.tag === ClassComponent) {
28722 var Component = fiber.type;
28723
28724 if (isContextProvider(Component)) {
28725 return processChildContext(fiber, Component, parentContext);
28726 }
28727 }
28728
28729 return parentContext;
28730}
28731
28732function findHostInstanceWithWarning(component, methodName) {
28733 {
28734 var fiber = get(component);
28735
28736 if (fiber === undefined) {
28737 if (typeof component.render === 'function') {
28738 throw new Error('Unable to find node on an unmounted component.');
28739 } else {
28740 var keys = Object.keys(component).join(',');
28741 throw new Error("Argument appears to not be a ReactComponent. Keys: " + keys);
28742 }
28743 }
28744
28745 var hostFiber = findCurrentHostFiber(fiber);
28746
28747 if (hostFiber === null) {
28748 return null;
28749 }
28750
28751 if (hostFiber.mode & StrictLegacyMode) {
28752 var componentName = getComponentNameFromFiber(fiber) || 'Component';
28753
28754 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
28755 didWarnAboutFindNodeInStrictMode[componentName] = true;
28756 var previousFiber = current;
28757
28758 try {
28759 setCurrentFiber(hostFiber);
28760
28761 if (fiber.mode & StrictLegacyMode) {
28762 error('%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://reactjs.org/link/strict-mode-find-node', methodName, methodName, componentName);
28763 } else {
28764 error('%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://reactjs.org/link/strict-mode-find-node', methodName, methodName, componentName);
28765 }
28766 } finally {
28767 // Ideally this should reset to previous but this shouldn't be called in
28768 // render and there's another warning for that anyway.
28769 if (previousFiber) {
28770 setCurrentFiber(previousFiber);
28771 } else {
28772 resetCurrentFiber();
28773 }
28774 }
28775 }
28776 }
28777
28778 return hostFiber.stateNode;
28779 }
28780}
28781
28782function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
28783 var hydrate = false;
28784 var initialChildren = null;
28785 return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
28786}
28787function createHydrationContainer(initialChildren, // TODO: Remove `callback` when we delete legacy mode.
28788callback, containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
28789 var hydrate = true;
28790 var root = createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); // TODO: Move this to FiberRoot constructor
28791
28792 root.context = getContextForSubtree(null); // Schedule the initial render. In a hydration root, this is different from
28793 // a regular update because the initial render must match was was rendered
28794 // on the server.
28795 // NOTE: This update intentionally doesn't have a payload. We're only using
28796 // the update to schedule work on the root fiber (and, for legacy roots, to
28797 // enqueue the callback if one is provided).
28798
28799 var current = root.current;
28800 var eventTime = requestEventTime();
28801 var lane = requestUpdateLane(current);
28802 var update = createUpdate(eventTime, lane);
28803 update.callback = callback !== undefined && callback !== null ? callback : null;
28804 enqueueUpdate(current, update, lane);
28805 scheduleInitialHydrationOnRoot(root, lane, eventTime);
28806 return root;
28807}
28808function updateContainer(element, container, parentComponent, callback) {
28809 {
28810 onScheduleRoot(container, element);
28811 }
28812
28813 var current$1 = container.current;
28814 var eventTime = requestEventTime();
28815 var lane = requestUpdateLane(current$1);
28816
28817 {
28818 markRenderScheduled(lane);
28819 }
28820
28821 var context = getContextForSubtree(parentComponent);
28822
28823 if (container.context === null) {
28824 container.context = context;
28825 } else {
28826 container.pendingContext = context;
28827 }
28828
28829 {
28830 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
28831 didWarnAboutNestedUpdates = true;
28832
28833 error('Render methods should be a pure function of props and state; ' + 'triggering nested component updates from render is not allowed. ' + 'If necessary, trigger nested updates in componentDidUpdate.\n\n' + 'Check the render method of %s.', getComponentNameFromFiber(current) || 'Unknown');
28834 }
28835 }
28836
28837 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property
28838 // being called "element".
28839
28840 update.payload = {
28841 element: element
28842 };
28843 callback = callback === undefined ? null : callback;
28844
28845 if (callback !== null) {
28846 {
28847 if (typeof callback !== 'function') {
28848 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
28849 }
28850 }
28851
28852 update.callback = callback;
28853 }
28854
28855 var root = enqueueUpdate(current$1, update, lane);
28856
28857 if (root !== null) {
28858 scheduleUpdateOnFiber(root, current$1, lane, eventTime);
28859 entangleTransitions(root, current$1, lane);
28860 }
28861
28862 return lane;
28863}
28864function getPublicRootInstance(container) {
28865 var containerFiber = container.current;
28866
28867 if (!containerFiber.child) {
28868 return null;
28869 }
28870
28871 switch (containerFiber.child.tag) {
28872 case HostComponent:
28873 return getPublicInstance(containerFiber.child.stateNode);
28874
28875 default:
28876 return containerFiber.child.stateNode;
28877 }
28878}
28879function attemptSynchronousHydration$1(fiber) {
28880 switch (fiber.tag) {
28881 case HostRoot:
28882 {
28883 var root = fiber.stateNode;
28884
28885 if (isRootDehydrated(root)) {
28886 // Flush the first scheduled "update".
28887 var lanes = getHighestPriorityPendingLanes(root);
28888 flushRoot(root, lanes);
28889 }
28890
28891 break;
28892 }
28893
28894 case SuspenseComponent:
28895 {
28896 flushSync(function () {
28897 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
28898
28899 if (root !== null) {
28900 var eventTime = requestEventTime();
28901 scheduleUpdateOnFiber(root, fiber, SyncLane, eventTime);
28902 }
28903 }); // If we're still blocked after this, we need to increase
28904 // the priority of any promises resolving within this
28905 // boundary so that they next attempt also has higher pri.
28906
28907 var retryLane = SyncLane;
28908 markRetryLaneIfNotHydrated(fiber, retryLane);
28909 break;
28910 }
28911 }
28912}
28913
28914function markRetryLaneImpl(fiber, retryLane) {
28915 var suspenseState = fiber.memoizedState;
28916
28917 if (suspenseState !== null && suspenseState.dehydrated !== null) {
28918 suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane);
28919 }
28920} // Increases the priority of thenables when they resolve within this boundary.
28921
28922
28923function markRetryLaneIfNotHydrated(fiber, retryLane) {
28924 markRetryLaneImpl(fiber, retryLane);
28925 var alternate = fiber.alternate;
28926
28927 if (alternate) {
28928 markRetryLaneImpl(alternate, retryLane);
28929 }
28930}
28931function attemptContinuousHydration$1(fiber) {
28932 if (fiber.tag !== SuspenseComponent) {
28933 // We ignore HostRoots here because we can't increase
28934 // their priority and they should not suspend on I/O,
28935 // since you have to wrap anything that might suspend in
28936 // Suspense.
28937 return;
28938 }
28939
28940 var lane = SelectiveHydrationLane;
28941 var root = enqueueConcurrentRenderForLane(fiber, lane);
28942
28943 if (root !== null) {
28944 var eventTime = requestEventTime();
28945 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
28946 }
28947
28948 markRetryLaneIfNotHydrated(fiber, lane);
28949}
28950function attemptHydrationAtCurrentPriority$1(fiber) {
28951 if (fiber.tag !== SuspenseComponent) {
28952 // We ignore HostRoots here because we can't increase
28953 // their priority other than synchronously flush it.
28954 return;
28955 }
28956
28957 var lane = requestUpdateLane(fiber);
28958 var root = enqueueConcurrentRenderForLane(fiber, lane);
28959
28960 if (root !== null) {
28961 var eventTime = requestEventTime();
28962 scheduleUpdateOnFiber(root, fiber, lane, eventTime);
28963 }
28964
28965 markRetryLaneIfNotHydrated(fiber, lane);
28966}
28967function findHostInstanceWithNoPortals(fiber) {
28968 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
28969
28970 if (hostFiber === null) {
28971 return null;
28972 }
28973
28974 return hostFiber.stateNode;
28975}
28976
28977var shouldErrorImpl = function (fiber) {
28978 return null;
28979};
28980
28981function shouldError(fiber) {
28982 return shouldErrorImpl(fiber);
28983}
28984
28985var shouldSuspendImpl = function (fiber) {
28986 return false;
28987};
28988
28989function shouldSuspend(fiber) {
28990 return shouldSuspendImpl(fiber);
28991}
28992var overrideHookState = null;
28993var overrideHookStateDeletePath = null;
28994var overrideHookStateRenamePath = null;
28995var overrideProps = null;
28996var overridePropsDeletePath = null;
28997var overridePropsRenamePath = null;
28998var scheduleUpdate = null;
28999var setErrorHandler = null;
29000var setSuspenseHandler = null;
29001
29002{
29003 var copyWithDeleteImpl = function (obj, path, index) {
29004 var key = path[index];
29005 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
29006
29007 if (index + 1 === path.length) {
29008 if (isArray(updated)) {
29009 updated.splice(key, 1);
29010 } else {
29011 delete updated[key];
29012 }
29013
29014 return updated;
29015 } // $FlowFixMe number or string is fine here
29016
29017
29018 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
29019 return updated;
29020 };
29021
29022 var copyWithDelete = function (obj, path) {
29023 return copyWithDeleteImpl(obj, path, 0);
29024 };
29025
29026 var copyWithRenameImpl = function (obj, oldPath, newPath, index) {
29027 var oldKey = oldPath[index];
29028 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
29029
29030 if (index + 1 === oldPath.length) {
29031 var newKey = newPath[index]; // $FlowFixMe number or string is fine here
29032
29033 updated[newKey] = updated[oldKey];
29034
29035 if (isArray(updated)) {
29036 updated.splice(oldKey, 1);
29037 } else {
29038 delete updated[oldKey];
29039 }
29040 } else {
29041 // $FlowFixMe number or string is fine here
29042 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here
29043 obj[oldKey], oldPath, newPath, index + 1);
29044 }
29045
29046 return updated;
29047 };
29048
29049 var copyWithRename = function (obj, oldPath, newPath) {
29050 if (oldPath.length !== newPath.length) {
29051 warn('copyWithRename() expects paths of the same length');
29052
29053 return;
29054 } else {
29055 for (var i = 0; i < newPath.length - 1; i++) {
29056 if (oldPath[i] !== newPath[i]) {
29057 warn('copyWithRename() expects paths to be the same except for the deepest key');
29058
29059 return;
29060 }
29061 }
29062 }
29063
29064 return copyWithRenameImpl(obj, oldPath, newPath, 0);
29065 };
29066
29067 var copyWithSetImpl = function (obj, path, index, value) {
29068 if (index >= path.length) {
29069 return value;
29070 }
29071
29072 var key = path[index];
29073 var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe number or string is fine here
29074
29075 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
29076 return updated;
29077 };
29078
29079 var copyWithSet = function (obj, path, value) {
29080 return copyWithSetImpl(obj, path, 0, value);
29081 };
29082
29083 var findHook = function (fiber, id) {
29084 // For now, the "id" of stateful hooks is just the stateful hook index.
29085 // This may change in the future with e.g. nested hooks.
29086 var currentHook = fiber.memoizedState;
29087
29088 while (currentHook !== null && id > 0) {
29089 currentHook = currentHook.next;
29090 id--;
29091 }
29092
29093 return currentHook;
29094 }; // Support DevTools editable values for useState and useReducer.
29095
29096
29097 overrideHookState = function (fiber, id, path, value) {
29098 var hook = findHook(fiber, id);
29099
29100 if (hook !== null) {
29101 var newState = copyWithSet(hook.memoizedState, path, value);
29102 hook.memoizedState = newState;
29103 hook.baseState = newState; // We aren't actually adding an update to the queue,
29104 // because there is no update we can add for useReducer hooks that won't trigger an error.
29105 // (There's no appropriate action type for DevTools overrides.)
29106 // As a result though, React will see the scheduled update as a noop and bailout.
29107 // Shallow cloning props works as a workaround for now to bypass the bailout check.
29108
29109 fiber.memoizedProps = assign({}, fiber.memoizedProps);
29110 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29111
29112 if (root !== null) {
29113 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29114 }
29115 }
29116 };
29117
29118 overrideHookStateDeletePath = function (fiber, id, path) {
29119 var hook = findHook(fiber, id);
29120
29121 if (hook !== null) {
29122 var newState = copyWithDelete(hook.memoizedState, path);
29123 hook.memoizedState = newState;
29124 hook.baseState = newState; // We aren't actually adding an update to the queue,
29125 // because there is no update we can add for useReducer hooks that won't trigger an error.
29126 // (There's no appropriate action type for DevTools overrides.)
29127 // As a result though, React will see the scheduled update as a noop and bailout.
29128 // Shallow cloning props works as a workaround for now to bypass the bailout check.
29129
29130 fiber.memoizedProps = assign({}, fiber.memoizedProps);
29131 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29132
29133 if (root !== null) {
29134 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29135 }
29136 }
29137 };
29138
29139 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) {
29140 var hook = findHook(fiber, id);
29141
29142 if (hook !== null) {
29143 var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
29144 hook.memoizedState = newState;
29145 hook.baseState = newState; // We aren't actually adding an update to the queue,
29146 // because there is no update we can add for useReducer hooks that won't trigger an error.
29147 // (There's no appropriate action type for DevTools overrides.)
29148 // As a result though, React will see the scheduled update as a noop and bailout.
29149 // Shallow cloning props works as a workaround for now to bypass the bailout check.
29150
29151 fiber.memoizedProps = assign({}, fiber.memoizedProps);
29152 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29153
29154 if (root !== null) {
29155 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29156 }
29157 }
29158 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
29159
29160
29161 overrideProps = function (fiber, path, value) {
29162 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
29163
29164 if (fiber.alternate) {
29165 fiber.alternate.pendingProps = fiber.pendingProps;
29166 }
29167
29168 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29169
29170 if (root !== null) {
29171 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29172 }
29173 };
29174
29175 overridePropsDeletePath = function (fiber, path) {
29176 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
29177
29178 if (fiber.alternate) {
29179 fiber.alternate.pendingProps = fiber.pendingProps;
29180 }
29181
29182 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29183
29184 if (root !== null) {
29185 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29186 }
29187 };
29188
29189 overridePropsRenamePath = function (fiber, oldPath, newPath) {
29190 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
29191
29192 if (fiber.alternate) {
29193 fiber.alternate.pendingProps = fiber.pendingProps;
29194 }
29195
29196 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29197
29198 if (root !== null) {
29199 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29200 }
29201 };
29202
29203 scheduleUpdate = function (fiber) {
29204 var root = enqueueConcurrentRenderForLane(fiber, SyncLane);
29205
29206 if (root !== null) {
29207 scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
29208 }
29209 };
29210
29211 setErrorHandler = function (newShouldErrorImpl) {
29212 shouldErrorImpl = newShouldErrorImpl;
29213 };
29214
29215 setSuspenseHandler = function (newShouldSuspendImpl) {
29216 shouldSuspendImpl = newShouldSuspendImpl;
29217 };
29218}
29219
29220function findHostInstanceByFiber(fiber) {
29221 var hostFiber = findCurrentHostFiber(fiber);
29222
29223 if (hostFiber === null) {
29224 return null;
29225 }
29226
29227 return hostFiber.stateNode;
29228}
29229
29230function emptyFindFiberByHostInstance(instance) {
29231 return null;
29232}
29233
29234function getCurrentFiberForDevTools() {
29235 return current;
29236}
29237
29238function injectIntoDevTools(devToolsConfig) {
29239 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
29240 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
29241 return injectInternals({
29242 bundleType: devToolsConfig.bundleType,
29243 version: devToolsConfig.version,
29244 rendererPackageName: devToolsConfig.rendererPackageName,
29245 rendererConfig: devToolsConfig.rendererConfig,
29246 overrideHookState: overrideHookState,
29247 overrideHookStateDeletePath: overrideHookStateDeletePath,
29248 overrideHookStateRenamePath: overrideHookStateRenamePath,
29249 overrideProps: overrideProps,
29250 overridePropsDeletePath: overridePropsDeletePath,
29251 overridePropsRenamePath: overridePropsRenamePath,
29252 setErrorHandler: setErrorHandler,
29253 setSuspenseHandler: setSuspenseHandler,
29254 scheduleUpdate: scheduleUpdate,
29255 currentDispatcherRef: ReactCurrentDispatcher,
29256 findHostInstanceByFiber: findHostInstanceByFiber,
29257 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
29258 // React Refresh
29259 findHostInstancesForRefresh: findHostInstancesForRefresh ,
29260 scheduleRefresh: scheduleRefresh ,
29261 scheduleRoot: scheduleRoot ,
29262 setRefreshHandler: setRefreshHandler ,
29263 // Enables DevTools to append owner stacks to error messages in DEV mode.
29264 getCurrentFiber: getCurrentFiberForDevTools ,
29265 // Enables DevTools to detect reconciler version rather than renderer version
29266 // which may not match for third party renderers.
29267 reconcilerVersion: ReactVersion
29268 });
29269}
29270
29271/* global reportError */
29272
29273var defaultOnRecoverableError = typeof reportError === 'function' ? // In modern browsers, reportError will dispatch an error event,
29274// emulating an uncaught JavaScript error.
29275reportError : function (error) {
29276 // In older browsers and test environments, fallback to console.error.
29277 // eslint-disable-next-line react-internal/no-production-logging
29278 console['error'](error);
29279};
29280
29281function ReactDOMRoot(internalRoot) {
29282 this._internalRoot = internalRoot;
29283}
29284
29285ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function (children) {
29286 var root = this._internalRoot;
29287
29288 if (root === null) {
29289 throw new Error('Cannot update an unmounted root.');
29290 }
29291
29292 {
29293 if (typeof arguments[1] === 'function') {
29294 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
29295 } else if (isValidContainer(arguments[1])) {
29296 error('You passed a container to the second argument of root.render(...). ' + "You don't need to pass it again since you already passed it to create the root.");
29297 } else if (typeof arguments[1] !== 'undefined') {
29298 error('You passed a second argument to root.render(...) but it only accepts ' + 'one argument.');
29299 }
29300
29301 var container = root.containerInfo;
29302
29303 if (container.nodeType !== COMMENT_NODE) {
29304 var hostInstance = findHostInstanceWithNoPortals(root.current);
29305
29306 if (hostInstance) {
29307 if (hostInstance.parentNode !== container) {
29308 error('render(...): It looks like the React-rendered content of the ' + 'root container was removed without using React. This is not ' + 'supported and will cause errors. Instead, call ' + "root.unmount() to empty a root's container.");
29309 }
29310 }
29311 }
29312 }
29313
29314 updateContainer(children, root, null, null);
29315};
29316
29317ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = function () {
29318 {
29319 if (typeof arguments[0] === 'function') {
29320 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
29321 }
29322 }
29323
29324 var root = this._internalRoot;
29325
29326 if (root !== null) {
29327 this._internalRoot = null;
29328 var container = root.containerInfo;
29329
29330 {
29331 if (isAlreadyRendering()) {
29332 error('Attempted to synchronously unmount a root while React was already ' + 'rendering. React cannot finish unmounting the root until the ' + 'current render has completed, which may lead to a race condition.');
29333 }
29334 }
29335
29336 flushSync(function () {
29337 updateContainer(null, root, null, null);
29338 });
29339 unmarkContainerAsRoot(container);
29340 }
29341};
29342
29343function createRoot(container, options) {
29344 if (!isValidContainer(container)) {
29345 throw new Error('createRoot(...): Target container is not a DOM element.');
29346 }
29347
29348 warnIfReactDOMContainerInDEV(container);
29349 var isStrictMode = false;
29350 var concurrentUpdatesByDefaultOverride = false;
29351 var identifierPrefix = '';
29352 var onRecoverableError = defaultOnRecoverableError;
29353 var transitionCallbacks = null;
29354
29355 if (options !== null && options !== undefined) {
29356 {
29357 if (options.hydrate) {
29358 warn('hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, <App />) instead.');
29359 } else {
29360 if (typeof options === 'object' && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) {
29361 error('You passed a JSX element to createRoot. You probably meant to ' + 'call root.render instead. ' + 'Example usage:\n\n' + ' let root = createRoot(domContainer);\n' + ' root.render(<App />);');
29362 }
29363 }
29364 }
29365
29366 if (options.unstable_strictMode === true) {
29367 isStrictMode = true;
29368 }
29369
29370 if (options.identifierPrefix !== undefined) {
29371 identifierPrefix = options.identifierPrefix;
29372 }
29373
29374 if (options.onRecoverableError !== undefined) {
29375 onRecoverableError = options.onRecoverableError;
29376 }
29377
29378 if (options.transitionCallbacks !== undefined) {
29379 transitionCallbacks = options.transitionCallbacks;
29380 }
29381 }
29382
29383 var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
29384 markContainerAsRoot(root.current, container);
29385 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29386 listenToAllSupportedEvents(rootContainerElement);
29387 return new ReactDOMRoot(root);
29388}
29389
29390function ReactDOMHydrationRoot(internalRoot) {
29391 this._internalRoot = internalRoot;
29392}
29393
29394function scheduleHydration(target) {
29395 if (target) {
29396 queueExplicitHydrationTarget(target);
29397 }
29398}
29399
29400ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration;
29401function hydrateRoot(container, initialChildren, options) {
29402 if (!isValidContainer(container)) {
29403 throw new Error('hydrateRoot(...): Target container is not a DOM element.');
29404 }
29405
29406 warnIfReactDOMContainerInDEV(container);
29407
29408 {
29409 if (initialChildren === undefined) {
29410 error('Must provide initial children as second argument to hydrateRoot. ' + 'Example usage: hydrateRoot(domContainer, <App />)');
29411 }
29412 } // For now we reuse the whole bag of options since they contain
29413 // the hydration callbacks.
29414
29415
29416 var hydrationCallbacks = options != null ? options : null; // TODO: Delete this option
29417
29418 var mutableSources = options != null && options.hydratedSources || null;
29419 var isStrictMode = false;
29420 var concurrentUpdatesByDefaultOverride = false;
29421 var identifierPrefix = '';
29422 var onRecoverableError = defaultOnRecoverableError;
29423
29424 if (options !== null && options !== undefined) {
29425 if (options.unstable_strictMode === true) {
29426 isStrictMode = true;
29427 }
29428
29429 if (options.identifierPrefix !== undefined) {
29430 identifierPrefix = options.identifierPrefix;
29431 }
29432
29433 if (options.onRecoverableError !== undefined) {
29434 onRecoverableError = options.onRecoverableError;
29435 }
29436 }
29437
29438 var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
29439 markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway.
29440
29441 listenToAllSupportedEvents(container);
29442
29443 if (mutableSources) {
29444 for (var i = 0; i < mutableSources.length; i++) {
29445 var mutableSource = mutableSources[i];
29446 registerMutableSourceForHydration(root, mutableSource);
29447 }
29448 }
29449
29450 return new ReactDOMHydrationRoot(root);
29451}
29452function isValidContainer(node) {
29453 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || !disableCommentsAsDOMContainers ));
29454} // TODO: Remove this function which also includes comment nodes.
29455// We only use it in places that are currently more relaxed.
29456
29457function isValidContainerLegacy(node) {
29458 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 '));
29459}
29460
29461function warnIfReactDOMContainerInDEV(container) {
29462 {
29463 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
29464 error('createRoot(): Creating roots directly with 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 using a container element created ' + 'for your app.');
29465 }
29466
29467 if (isContainerMarkedAsRoot(container)) {
29468 if (container._reactRootContainer) {
29469 error('You are calling ReactDOMClient.createRoot() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.');
29470 } else {
29471 error('You are calling ReactDOMClient.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.');
29472 }
29473 }
29474 }
29475}
29476
29477var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
29478var topLevelUpdateWarnings;
29479
29480{
29481 topLevelUpdateWarnings = function (container) {
29482 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
29483 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer.current);
29484
29485 if (hostInstance) {
29486 if (hostInstance.parentNode !== container) {
29487 error('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.');
29488 }
29489 }
29490 }
29491
29492 var isRootRenderedBySomeReact = !!container._reactRootContainer;
29493 var rootEl = getReactRootElementInContainer(container);
29494 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
29495
29496 if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
29497 error('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.');
29498 }
29499
29500 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
29501 error('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.');
29502 }
29503 };
29504}
29505
29506function getReactRootElementInContainer(container) {
29507 if (!container) {
29508 return null;
29509 }
29510
29511 if (container.nodeType === DOCUMENT_NODE) {
29512 return container.documentElement;
29513 } else {
29514 return container.firstChild;
29515 }
29516}
29517
29518function noopOnRecoverableError() {// This isn't reachable because onRecoverableError isn't called in the
29519 // legacy API.
29520}
29521
29522function legacyCreateRootFromDOMContainer(container, initialChildren, parentComponent, callback, isHydrationContainer) {
29523 if (isHydrationContainer) {
29524 if (typeof callback === 'function') {
29525 var originalCallback = callback;
29526
29527 callback = function () {
29528 var instance = getPublicRootInstance(root);
29529 originalCallback.call(instance);
29530 };
29531 }
29532
29533 var root = createHydrationContainer(initialChildren, callback, container, LegacyRoot, null, // hydrationCallbacks
29534 false, // isStrictMode
29535 false, // concurrentUpdatesByDefaultOverride,
29536 '', // identifierPrefix
29537 noopOnRecoverableError);
29538 container._reactRootContainer = root;
29539 markContainerAsRoot(root.current, container);
29540 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29541 listenToAllSupportedEvents(rootContainerElement);
29542 flushSync();
29543 return root;
29544 } else {
29545 // First clear any existing content.
29546 var rootSibling;
29547
29548 while (rootSibling = container.lastChild) {
29549 container.removeChild(rootSibling);
29550 }
29551
29552 if (typeof callback === 'function') {
29553 var _originalCallback = callback;
29554
29555 callback = function () {
29556 var instance = getPublicRootInstance(_root);
29557
29558 _originalCallback.call(instance);
29559 };
29560 }
29561
29562 var _root = createContainer(container, LegacyRoot, null, // hydrationCallbacks
29563 false, // isStrictMode
29564 false, // concurrentUpdatesByDefaultOverride,
29565 '', // identifierPrefix
29566 noopOnRecoverableError);
29567
29568 container._reactRootContainer = _root;
29569 markContainerAsRoot(_root.current, container);
29570
29571 var _rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29572
29573 listenToAllSupportedEvents(_rootContainerElement); // Initial mount should not be batched.
29574
29575 flushSync(function () {
29576 updateContainer(initialChildren, _root, parentComponent, callback);
29577 });
29578 return _root;
29579 }
29580}
29581
29582function warnOnInvalidCallback$1(callback, callerName) {
29583 {
29584 if (callback !== null && typeof callback !== 'function') {
29585 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
29586 }
29587 }
29588}
29589
29590function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
29591 {
29592 topLevelUpdateWarnings(container);
29593 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');
29594 }
29595
29596 var maybeRoot = container._reactRootContainer;
29597 var root;
29598
29599 if (!maybeRoot) {
29600 // Initial mount
29601 root = legacyCreateRootFromDOMContainer(container, children, parentComponent, callback, forceHydrate);
29602 } else {
29603 root = maybeRoot;
29604
29605 if (typeof callback === 'function') {
29606 var originalCallback = callback;
29607
29608 callback = function () {
29609 var instance = getPublicRootInstance(root);
29610 originalCallback.call(instance);
29611 };
29612 } // Update
29613
29614
29615 updateContainer(children, root, parentComponent, callback);
29616 }
29617
29618 return getPublicRootInstance(root);
29619}
29620
29621function findDOMNode(componentOrElement) {
29622 {
29623 var owner = ReactCurrentOwner$3.current;
29624
29625 if (owner !== null && owner.stateNode !== null) {
29626 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
29627
29628 if (!warnedAboutRefsInRender) {
29629 error('%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.', getComponentNameFromType(owner.type) || 'A component');
29630 }
29631
29632 owner.stateNode._warnedAboutRefsInRender = true;
29633 }
29634 }
29635
29636 if (componentOrElement == null) {
29637 return null;
29638 }
29639
29640 if (componentOrElement.nodeType === ELEMENT_NODE) {
29641 return componentOrElement;
29642 }
29643
29644 {
29645 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
29646 }
29647}
29648function hydrate(element, container, callback) {
29649 {
29650 error('ReactDOM.hydrate is no longer supported in React 18. Use hydrateRoot ' + 'instead. Until you switch to the new API, your app will behave as ' + "if it's running React 17. Learn " + 'more: https://reactjs.org/link/switch-to-createroot');
29651 }
29652
29653 if (!isValidContainerLegacy(container)) {
29654 throw new Error('Target container is not a DOM element.');
29655 }
29656
29657 {
29658 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29659
29660 if (isModernRoot) {
29661 error('You are calling ReactDOM.hydrate() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. ' + 'Did you mean to call hydrateRoot(container, element)?');
29662 }
29663 } // TODO: throw or warn if we couldn't hydrate?
29664
29665
29666 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
29667}
29668function render(element, container, callback) {
29669 {
29670 error('ReactDOM.render is no longer supported in React 18. Use createRoot ' + 'instead. Until you switch to the new API, your app will behave as ' + "if it's running React 17. Learn " + 'more: https://reactjs.org/link/switch-to-createroot');
29671 }
29672
29673 if (!isValidContainerLegacy(container)) {
29674 throw new Error('Target container is not a DOM element.');
29675 }
29676
29677 {
29678 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29679
29680 if (isModernRoot) {
29681 error('You are calling ReactDOM.render() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. ' + 'Did you mean to call root.render(element)?');
29682 }
29683 }
29684
29685 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
29686}
29687function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
29688 {
29689 error('ReactDOM.unstable_renderSubtreeIntoContainer() is no longer supported ' + 'in React 18. Consider using a portal instead. Until you switch to ' + "the createRoot API, your app will behave as if it's running React " + '17. Learn more: https://reactjs.org/link/switch-to-createroot');
29690 }
29691
29692 if (!isValidContainerLegacy(containerNode)) {
29693 throw new Error('Target container is not a DOM element.');
29694 }
29695
29696 if (parentComponent == null || !has(parentComponent)) {
29697 throw new Error('parentComponent must be a valid React Component');
29698 }
29699
29700 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
29701}
29702function unmountComponentAtNode(container) {
29703 if (!isValidContainerLegacy(container)) {
29704 throw new Error('unmountComponentAtNode(...): Target container is not a DOM element.');
29705 }
29706
29707 {
29708 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29709
29710 if (isModernRoot) {
29711 error('You are calling ReactDOM.unmountComponentAtNode() on a container that was previously ' + 'passed to ReactDOMClient.createRoot(). This is not supported. Did you mean to call root.unmount()?');
29712 }
29713 }
29714
29715 if (container._reactRootContainer) {
29716 {
29717 var rootEl = getReactRootElementInContainer(container);
29718 var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
29719
29720 if (renderedByDifferentReact) {
29721 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
29722 }
29723 } // Unmount should not be batched.
29724
29725
29726 flushSync(function () {
29727 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
29728 // $FlowFixMe This should probably use `delete container._reactRootContainer`
29729 container._reactRootContainer = null;
29730 unmarkContainerAsRoot(container);
29731 });
29732 }); // If you call unmountComponentAtNode twice in quick succession, you'll
29733 // get `true` twice. That's probably fine?
29734
29735 return true;
29736 } else {
29737 {
29738 var _rootEl = getReactRootElementInContainer(container);
29739
29740 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node.
29741
29742 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainerLegacy(container.parentNode) && !!container.parentNode._reactRootContainer;
29743
29744 if (hasNonRootReactChild) {
29745 error("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.');
29746 }
29747 }
29748
29749 return false;
29750 }
29751}
29752
29753setAttemptSynchronousHydration(attemptSynchronousHydration$1);
29754setAttemptContinuousHydration(attemptContinuousHydration$1);
29755setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
29756setGetCurrentUpdatePriority(getCurrentUpdatePriority);
29757setAttemptHydrationAtPriority(runWithPriority);
29758
29759{
29760 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
29761 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
29762 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
29763 error('React depends on Map and Set built-in types. Make sure that you load a ' + 'polyfill in older browsers. https://reactjs.org/link/react-polyfills');
29764 }
29765}
29766
29767setRestoreImplementation(restoreControlledState$3);
29768setBatchingImplementation(batchedUpdates$1, discreteUpdates, flushSync);
29769
29770function createPortal$1(children, container) {
29771 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
29772
29773 if (!isValidContainer(container)) {
29774 throw new Error('Target container is not a DOM element.');
29775 } // TODO: pass ReactDOM portal implementation as third argument
29776 // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
29777
29778
29779 return createPortal(children, container, null, key);
29780}
29781
29782function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
29783 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
29784}
29785
29786var Internals = {
29787 usingClientEntryPoint: false,
29788 // Keep in sync with ReactTestUtils.js.
29789 // This is an array for better minification.
29790 Events: [getInstanceFromNode, getNodeFromInstance, getFiberCurrentPropsFromNode, enqueueStateRestore, restoreStateIfNeeded, batchedUpdates$1]
29791};
29792
29793function createRoot$1(container, options) {
29794 {
29795 if (!Internals.usingClientEntryPoint && !false) {
29796 error('You are importing createRoot from "react-dom" which is not supported. ' + 'You should instead import it from "react-dom/client".');
29797 }
29798 }
29799
29800 return createRoot(container, options);
29801}
29802
29803function hydrateRoot$1(container, initialChildren, options) {
29804 {
29805 if (!Internals.usingClientEntryPoint && !false) {
29806 error('You are importing hydrateRoot from "react-dom" which is not supported. ' + 'You should instead import it from "react-dom/client".');
29807 }
29808 }
29809
29810 return hydrateRoot(container, initialChildren, options);
29811} // Overload the definition to the two valid signatures.
29812// Warning, this opts-out of checking the function body.
29813
29814
29815// eslint-disable-next-line no-redeclare
29816function flushSync$1(fn) {
29817 {
29818 if (isAlreadyRendering()) {
29819 error('flushSync was called from inside a lifecycle method. React cannot ' + 'flush when React is already rendering. Consider moving this call to ' + 'a scheduler task or micro task.');
29820 }
29821 }
29822
29823 return flushSync(fn);
29824}
29825var foundDevTools = injectIntoDevTools({
29826 findFiberByHostInstance: getClosestInstanceFromNode,
29827 bundleType: 1 ,
29828 version: ReactVersion,
29829 rendererPackageName: 'react-dom'
29830});
29831
29832{
29833 if (!foundDevTools && canUseDOM && window.top === window.self) {
29834 // If we're in Chrome or Firefox, provide a download link if not installed.
29835 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
29836 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
29837
29838 if (/^(https?|file):$/.test(protocol)) {
29839 // eslint-disable-next-line react-internal/no-production-logging
29840 console.info('%cDownload the React DevTools ' + 'for a better development experience: ' + 'https://reactjs.org/link/react-devtools' + (protocol === 'file:' ? '\nYou might need to use a local HTTP server (instead of file://): ' + 'https://reactjs.org/link/react-devtools-faq' : ''), 'font-weight:bold');
29841 }
29842 }
29843 }
29844}
29845
29846exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
29847exports.createPortal = createPortal$1;
29848exports.createRoot = createRoot$1;
29849exports.findDOMNode = findDOMNode;
29850exports.flushSync = flushSync$1;
29851exports.hydrate = hydrate;
29852exports.hydrateRoot = hydrateRoot$1;
29853exports.render = render;
29854exports.unmountComponentAtNode = unmountComponentAtNode;
29855exports.unstable_batchedUpdates = batchedUpdates$1;
29856exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
29857exports.version = ReactVersion;
29858 /* global __REACT_DEVTOOLS_GLOBAL_HOOK__ */
29859if (
29860 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined' &&
29861 typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop ===
29862 'function'
29863) {
29864 __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
29865}
29866
29867 })();
29868}