UNPKG

1.06 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(function (global, factory) {
11 typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
12 typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
13 (global = global || self, factory(global.ReactDOM = {}, global.React));
14}(this, (function (exports, React) { 'use strict';
15
16 var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
17
18 var suppressWarning = false;
19 function setSuppressWarning(newSuppressWarning) {
20 {
21 suppressWarning = newSuppressWarning;
22 }
23 } // In DEV, calls to console.warn and console.error get replaced
24 // by calls to these methods by a Babel plugin.
25 //
26 // In PROD (or in packages without access to React internals),
27 // they are left as they are instead.
28
29 function warn(format) {
30 {
31 if (!suppressWarning) {
32 for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
33 args[_key - 1] = arguments[_key];
34 }
35
36 printWarning('warn', format, args);
37 }
38 }
39 }
40 function error(format) {
41 {
42 if (!suppressWarning) {
43 for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
44 args[_key2 - 1] = arguments[_key2];
45 }
46
47 printWarning('error', format, args);
48 }
49 }
50 }
51
52 function printWarning(level, format, args) {
53 // When changing this logic, you might want to also
54 // update consoleWithStackDev.www.js as well.
55 {
56 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
57 var stack = ReactDebugCurrentFrame.getStackAddendum();
58
59 if (stack !== '') {
60 format += '%s';
61 args = args.concat([stack]);
62 } // eslint-disable-next-line react-internal/safe-string-coercion
63
64
65 var argsWithFormat = args.map(function (item) {
66 return String(item);
67 }); // Careful: RN currently depends on this prefix
68
69 argsWithFormat.unshift('Warning: ' + format); // We intentionally don't use spread (or .apply) directly because it
70 // breaks IE9: https://github.com/facebook/react/issues/13610
71 // eslint-disable-next-line react-internal/no-production-logging
72
73 Function.prototype.apply.call(console[level], console, argsWithFormat);
74 }
75 }
76
77 var FunctionComponent = 0;
78 var ClassComponent = 1;
79 var IndeterminateComponent = 2; // Before we know whether it is function or class
80
81 var HostRoot = 3; // Root of a host tree. Could be nested inside another node.
82
83 var HostPortal = 4; // A subtree. Could be an entry point to a different renderer.
84
85 var HostComponent = 5;
86 var HostText = 6;
87 var Fragment = 7;
88 var Mode = 8;
89 var ContextConsumer = 9;
90 var ContextProvider = 10;
91 var ForwardRef = 11;
92 var Profiler = 12;
93 var SuspenseComponent = 13;
94 var MemoComponent = 14;
95 var SimpleMemoComponent = 15;
96 var LazyComponent = 16;
97 var IncompleteClassComponent = 17;
98 var DehydratedFragment = 18;
99 var SuspenseListComponent = 19;
100 var ScopeComponent = 21;
101 var OffscreenComponent = 22;
102 var LegacyHiddenComponent = 23;
103 var CacheComponent = 24;
104 var TracingMarkerComponent = 25;
105
106 // -----------------------------------------------------------------------------
107 var enableClientRenderFallbackOnTextMismatch = true; // Recoil still uses useMutableSource in www, need to delete
108 // the react-reconciler package.
109
110 var enableNewReconciler = false; // Support legacy Primer support on internal FB www
111
112 var enableLazyContextPropagation = false; // FB-only usage. The new API has different semantics.
113
114 var enableLegacyHidden = false; // Enables unstable_avoidThisFallback feature in Fiber
115
116 var enableSuspenseAvoidThisFallback = false; // Enables unstable_avoidThisFallback feature in Fizz
117 // React DOM Chopping Block
118 //
119 // Similar to main Chopping Block but only flags related to React DOM. These are
120 // grouped because we will likely batch all of them into a single major release.
121 // -----------------------------------------------------------------------------
122 // Disable support for comment nodes as React DOM containers. Already disabled
123 // in open source, but www codebase still relies on it. Need to remove.
124
125 var disableCommentsAsDOMContainers = true; // Disable javascript: URL strings in href for XSS protection.
126 // and client rendering, mostly to allow JSX attributes to apply to the custom
127 // element's object properties instead of only HTML attributes.
128 // https://github.com/facebook/react/issues/11347
129
130 var enableCustomElementPropertySupport = false; // Disables children for <textarea> elements
131 var warnAboutStringRefs = false; // -----------------------------------------------------------------------------
132 // Debugging and DevTools
133 // -----------------------------------------------------------------------------
134 // Adds user timing marks for e.g. state updates, suspense, and work loop stuff,
135 // for an experimental timeline tool.
136
137 var enableSchedulingProfiler = true; // Helps identify side effects in render-phase lifecycle hooks and setState
138
139 var enableProfilerTimer = true; // Record durations for commit and passive effects phases.
140
141 var enableProfilerCommitHooks = true; // Phase param passed to onRender callback differentiates between an "update" and a "cascading-update".
142
143 var allNativeEvents = new Set();
144 /**
145 * Mapping from registration name to event name
146 */
147
148
149 var registrationNameDependencies = {};
150 /**
151 * Mapping from lowercase registration names to the properly cased version,
152 * used to warn in the case of missing event handlers. Available
153 * only in true.
154 * @type {Object}
155 */
156
157 var possibleRegistrationNames = {} ; // Trust the developer to only use possibleRegistrationNames in true
158
159 function registerTwoPhaseEvent(registrationName, dependencies) {
160 registerDirectEvent(registrationName, dependencies);
161 registerDirectEvent(registrationName + 'Capture', dependencies);
162 }
163 function registerDirectEvent(registrationName, dependencies) {
164 {
165 if (registrationNameDependencies[registrationName]) {
166 error('EventRegistry: More than one plugin attempted to publish the same ' + 'registration name, `%s`.', registrationName);
167 }
168 }
169
170 registrationNameDependencies[registrationName] = dependencies;
171
172 {
173 var lowerCasedName = registrationName.toLowerCase();
174 possibleRegistrationNames[lowerCasedName] = registrationName;
175
176 if (registrationName === 'onDoubleClick') {
177 possibleRegistrationNames.ondblclick = registrationName;
178 }
179 }
180
181 for (var i = 0; i < dependencies.length; i++) {
182 allNativeEvents.add(dependencies[i]);
183 }
184 }
185
186 var canUseDOM = !!(typeof window !== 'undefined' && typeof window.document !== 'undefined' && typeof window.document.createElement !== 'undefined');
187
188 var hasOwnProperty = Object.prototype.hasOwnProperty;
189
190 /*
191 * The `'' + value` pattern (used in in perf-sensitive code) throws for Symbol
192 * and Temporal.* types. See https://github.com/facebook/react/pull/22064.
193 *
194 * The functions in this module will throw an easier-to-understand,
195 * easier-to-debug exception with a clear errors message message explaining the
196 * problem. (Instead of a confusing exception thrown inside the implementation
197 * of the `value` object).
198 */
199 // $FlowFixMe only called in DEV, so void return is not possible.
200 function typeName(value) {
201 {
202 // toStringTag is needed for namespaced types like Temporal.Instant
203 var hasToStringTag = typeof Symbol === 'function' && Symbol.toStringTag;
204 var type = hasToStringTag && value[Symbol.toStringTag] || value.constructor.name || 'Object';
205 return type;
206 }
207 } // $FlowFixMe only called in DEV, so void return is not possible.
208
209
210 function willCoercionThrow(value) {
211 {
212 try {
213 testStringCoercion(value);
214 return false;
215 } catch (e) {
216 return true;
217 }
218 }
219 }
220
221 function testStringCoercion(value) {
222 // If you ended up here by following an exception call stack, here's what's
223 // happened: you supplied an object or symbol value to React (as a prop, key,
224 // DOM attribute, CSS property, string ref, etc.) and when React tried to
225 // coerce it to a string using `'' + value`, an exception was thrown.
226 //
227 // The most common types that will cause this exception are `Symbol` instances
228 // and Temporal objects like `Temporal.Instant`. But any object that has a
229 // `valueOf` or `[Symbol.toPrimitive]` method that throws will also cause this
230 // exception. (Library authors do this to prevent users from using built-in
231 // numeric operators like `+` or comparison operators like `>=` because custom
232 // methods are needed to perform accurate arithmetic or comparison.)
233 //
234 // To fix the problem, coerce this object or symbol value to a string before
235 // passing it to React. The most reliable way is usually `String(value)`.
236 //
237 // To find which value is throwing, check the browser or debugger console.
238 // Before this exception was thrown, there should be `console.error` output
239 // that shows the type (Symbol, Temporal.PlainDate, etc.) that caused the
240 // problem and how that type was used: key, atrribute, input value prop, etc.
241 // In most cases, this console output also shows the component and its
242 // ancestor components where the exception happened.
243 //
244 // eslint-disable-next-line react-internal/safe-string-coercion
245 return '' + value;
246 }
247
248 function checkAttributeStringCoercion(value, attributeName) {
249 {
250 if (willCoercionThrow(value)) {
251 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));
252
253 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
254 }
255 }
256 }
257 function checkKeyStringCoercion(value) {
258 {
259 if (willCoercionThrow(value)) {
260 error('The provided key is an unsupported type %s.' + ' This value must be coerced to a string before before using it here.', typeName(value));
261
262 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
263 }
264 }
265 }
266 function checkPropStringCoercion(value, propName) {
267 {
268 if (willCoercionThrow(value)) {
269 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));
270
271 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
272 }
273 }
274 }
275 function checkCSSPropertyStringCoercion(value, propName) {
276 {
277 if (willCoercionThrow(value)) {
278 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));
279
280 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
281 }
282 }
283 }
284 function checkHtmlStringCoercion(value) {
285 {
286 if (willCoercionThrow(value)) {
287 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));
288
289 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
290 }
291 }
292 }
293 function checkFormFieldValueStringCoercion(value) {
294 {
295 if (willCoercionThrow(value)) {
296 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));
297
298 return testStringCoercion(value); // throw (to help callers find troubleshooting comments)
299 }
300 }
301 }
302
303 // A reserved attribute.
304 // It is handled by React separately and shouldn't be written to the DOM.
305 var RESERVED = 0; // A simple string attribute.
306 // Attributes that aren't in the filter are presumed to have this type.
307
308 var STRING = 1; // A string attribute that accepts booleans in React. In HTML, these are called
309 // "enumerated" attributes with "true" and "false" as possible values.
310 // When true, it should be set to a "true" string.
311 // When false, it should be set to a "false" string.
312
313 var BOOLEANISH_STRING = 2; // A real boolean attribute.
314 // When true, it should be present (set either to an empty string or its name).
315 // When false, it should be omitted.
316
317 var BOOLEAN = 3; // An attribute that can be used as a flag as well as with a value.
318 // When true, it should be present (set either to an empty string or its name).
319 // When false, it should be omitted.
320 // For any other value, should be present with that value.
321
322 var OVERLOADED_BOOLEAN = 4; // An attribute that must be numeric or parse as a numeric.
323 // When falsy, it should be removed.
324
325 var NUMERIC = 5; // An attribute that must be positive numeric or parse as a positive numeric.
326 // When falsy, it should be removed.
327
328 var POSITIVE_NUMERIC = 6;
329
330 /* eslint-disable max-len */
331 var 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";
332 /* eslint-enable max-len */
333
334 var ATTRIBUTE_NAME_CHAR = ATTRIBUTE_NAME_START_CHAR + "\\-.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
335 var VALID_ATTRIBUTE_NAME_REGEX = new RegExp('^[' + ATTRIBUTE_NAME_START_CHAR + '][' + ATTRIBUTE_NAME_CHAR + ']*$');
336 var illegalAttributeNameCache = {};
337 var validatedAttributeNameCache = {};
338 function isAttributeNameSafe(attributeName) {
339 if (hasOwnProperty.call(validatedAttributeNameCache, attributeName)) {
340 return true;
341 }
342
343 if (hasOwnProperty.call(illegalAttributeNameCache, attributeName)) {
344 return false;
345 }
346
347 if (VALID_ATTRIBUTE_NAME_REGEX.test(attributeName)) {
348 validatedAttributeNameCache[attributeName] = true;
349 return true;
350 }
351
352 illegalAttributeNameCache[attributeName] = true;
353
354 {
355 error('Invalid attribute name: `%s`', attributeName);
356 }
357
358 return false;
359 }
360 function shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag) {
361 if (propertyInfo !== null) {
362 return propertyInfo.type === RESERVED;
363 }
364
365 if (isCustomComponentTag) {
366 return false;
367 }
368
369 if (name.length > 2 && (name[0] === 'o' || name[0] === 'O') && (name[1] === 'n' || name[1] === 'N')) {
370 return true;
371 }
372
373 return false;
374 }
375 function shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag) {
376 if (propertyInfo !== null && propertyInfo.type === RESERVED) {
377 return false;
378 }
379
380 switch (typeof value) {
381 case 'function': // $FlowIssue symbol is perfectly valid here
382
383 case 'symbol':
384 // eslint-disable-line
385 return true;
386
387 case 'boolean':
388 {
389 if (isCustomComponentTag) {
390 return false;
391 }
392
393 if (propertyInfo !== null) {
394 return !propertyInfo.acceptsBooleans;
395 } else {
396 var prefix = name.toLowerCase().slice(0, 5);
397 return prefix !== 'data-' && prefix !== 'aria-';
398 }
399 }
400
401 default:
402 return false;
403 }
404 }
405 function shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag) {
406 if (value === null || typeof value === 'undefined') {
407 return true;
408 }
409
410 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, isCustomComponentTag)) {
411 return true;
412 }
413
414 if (isCustomComponentTag) {
415 return false;
416 }
417
418 if (propertyInfo !== null) {
419
420 switch (propertyInfo.type) {
421 case BOOLEAN:
422 return !value;
423
424 case OVERLOADED_BOOLEAN:
425 return value === false;
426
427 case NUMERIC:
428 return isNaN(value);
429
430 case POSITIVE_NUMERIC:
431 return isNaN(value) || value < 1;
432 }
433 }
434
435 return false;
436 }
437 function getPropertyInfo(name) {
438 return properties.hasOwnProperty(name) ? properties[name] : null;
439 }
440
441 function PropertyInfoRecord(name, type, mustUseProperty, attributeName, attributeNamespace, sanitizeURL, removeEmptyString) {
442 this.acceptsBooleans = type === BOOLEANISH_STRING || type === BOOLEAN || type === OVERLOADED_BOOLEAN;
443 this.attributeName = attributeName;
444 this.attributeNamespace = attributeNamespace;
445 this.mustUseProperty = mustUseProperty;
446 this.propertyName = name;
447 this.type = type;
448 this.sanitizeURL = sanitizeURL;
449 this.removeEmptyString = removeEmptyString;
450 } // When adding attributes to this list, be sure to also add them to
451 // the `possibleStandardNames` module to ensure casing and incorrect
452 // name warnings.
453
454
455 var properties = {}; // These props are reserved by React. They shouldn't be written to the DOM.
456
457 var reservedProps = ['children', 'dangerouslySetInnerHTML', // TODO: This prevents the assignment of defaultValue to regular
458 // elements (not just inputs). Now that ReactDOMInput assigns to the
459 // defaultValue property -- do we need this?
460 'defaultValue', 'defaultChecked', 'innerHTML', 'suppressContentEditableWarning', 'suppressHydrationWarning', 'style'];
461
462 reservedProps.forEach(function (name) {
463 properties[name] = new PropertyInfoRecord(name, RESERVED, false, // mustUseProperty
464 name, // attributeName
465 null, // attributeNamespace
466 false, // sanitizeURL
467 false);
468 }); // A few React string attributes have a different name.
469 // This is a mapping from React prop names to the attribute names.
470
471 [['acceptCharset', 'accept-charset'], ['className', 'class'], ['htmlFor', 'for'], ['httpEquiv', 'http-equiv']].forEach(function (_ref) {
472 var name = _ref[0],
473 attributeName = _ref[1];
474 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
475 attributeName, // attributeName
476 null, // attributeNamespace
477 false, // sanitizeURL
478 false);
479 }); // These are "enumerated" HTML attributes that accept "true" and "false".
480 // In React, we let users pass `true` and `false` even though technically
481 // these aren't boolean attributes (they are coerced to strings).
482
483 ['contentEditable', 'draggable', 'spellCheck', 'value'].forEach(function (name) {
484 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
485 name.toLowerCase(), // attributeName
486 null, // attributeNamespace
487 false, // sanitizeURL
488 false);
489 }); // These are "enumerated" SVG attributes that accept "true" and "false".
490 // In React, we let users pass `true` and `false` even though technically
491 // these aren't boolean attributes (they are coerced to strings).
492 // Since these are SVG attributes, their attribute names are case-sensitive.
493
494 ['autoReverse', 'externalResourcesRequired', 'focusable', 'preserveAlpha'].forEach(function (name) {
495 properties[name] = new PropertyInfoRecord(name, BOOLEANISH_STRING, false, // mustUseProperty
496 name, // attributeName
497 null, // attributeNamespace
498 false, // sanitizeURL
499 false);
500 }); // These are HTML boolean attributes.
501
502 ['allowFullScreen', 'async', // Note: there is a special case that prevents it from being written to the DOM
503 // on the client side because the browsers are inconsistent. Instead we call focus().
504 'autoFocus', 'autoPlay', 'controls', 'default', 'defer', 'disabled', 'disablePictureInPicture', 'disableRemotePlayback', 'formNoValidate', 'hidden', 'loop', 'noModule', 'noValidate', 'open', 'playsInline', 'readOnly', 'required', 'reversed', 'scoped', 'seamless', // Microdata
505 'itemScope'].forEach(function (name) {
506 properties[name] = new PropertyInfoRecord(name, BOOLEAN, false, // mustUseProperty
507 name.toLowerCase(), // attributeName
508 null, // attributeNamespace
509 false, // sanitizeURL
510 false);
511 }); // These are the few React props that we set as DOM properties
512 // rather than attributes. These are all booleans.
513
514 ['checked', // Note: `option.selected` is not updated if `select.multiple` is
515 // disabled with `removeAttribute`. We have special logic for handling this.
516 'multiple', 'muted', 'selected' // NOTE: if you add a camelCased prop to this list,
517 // you'll need to set attributeName to name.toLowerCase()
518 // instead in the assignment below.
519 ].forEach(function (name) {
520 properties[name] = new PropertyInfoRecord(name, BOOLEAN, true, // mustUseProperty
521 name, // attributeName
522 null, // attributeNamespace
523 false, // sanitizeURL
524 false);
525 }); // These are HTML attributes that are "overloaded booleans": they behave like
526 // booleans, but can also accept a string value.
527
528 ['capture', 'download' // NOTE: if you add a camelCased prop to this list,
529 // you'll need to set attributeName to name.toLowerCase()
530 // instead in the assignment below.
531 ].forEach(function (name) {
532 properties[name] = new PropertyInfoRecord(name, OVERLOADED_BOOLEAN, false, // mustUseProperty
533 name, // attributeName
534 null, // attributeNamespace
535 false, // sanitizeURL
536 false);
537 }); // These are HTML attributes that must be positive numbers.
538
539 ['cols', 'rows', 'size', 'span' // NOTE: if you add a camelCased prop to this list,
540 // you'll need to set attributeName to name.toLowerCase()
541 // instead in the assignment below.
542 ].forEach(function (name) {
543 properties[name] = new PropertyInfoRecord(name, POSITIVE_NUMERIC, false, // mustUseProperty
544 name, // attributeName
545 null, // attributeNamespace
546 false, // sanitizeURL
547 false);
548 }); // These are HTML attributes that must be numbers.
549
550 ['rowSpan', 'start'].forEach(function (name) {
551 properties[name] = new PropertyInfoRecord(name, NUMERIC, false, // mustUseProperty
552 name.toLowerCase(), // attributeName
553 null, // attributeNamespace
554 false, // sanitizeURL
555 false);
556 });
557 var CAMELIZE = /[\-\:]([a-z])/g;
558
559 var capitalize = function (token) {
560 return token[1].toUpperCase();
561 }; // This is a list of all SVG attributes that need special casing, namespacing,
562 // or boolean value assignment. Regular attributes that just accept strings
563 // and have the same names are omitted, just like in the HTML attribute filter.
564 // Some of these attributes can be hard to find. This list was created by
565 // scraping the MDN documentation.
566
567
568 ['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,
569 // you'll need to set attributeName to name.toLowerCase()
570 // instead in the assignment below.
571 ].forEach(function (attributeName) {
572 var name = attributeName.replace(CAMELIZE, capitalize);
573 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
574 attributeName, null, // attributeNamespace
575 false, // sanitizeURL
576 false);
577 }); // String SVG attributes with the xlink namespace.
578
579 ['xlink:actuate', 'xlink:arcrole', 'xlink:role', 'xlink:show', 'xlink:title', 'xlink:type' // NOTE: if you add a camelCased prop to this list,
580 // you'll need to set attributeName to name.toLowerCase()
581 // instead in the assignment below.
582 ].forEach(function (attributeName) {
583 var name = attributeName.replace(CAMELIZE, capitalize);
584 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
585 attributeName, 'http://www.w3.org/1999/xlink', false, // sanitizeURL
586 false);
587 }); // String SVG attributes with the xml namespace.
588
589 ['xml:base', 'xml:lang', 'xml:space' // NOTE: if you add a camelCased prop to this list,
590 // you'll need to set attributeName to name.toLowerCase()
591 // instead in the assignment below.
592 ].forEach(function (attributeName) {
593 var name = attributeName.replace(CAMELIZE, capitalize);
594 properties[name] = new PropertyInfoRecord(name, STRING, false, // mustUseProperty
595 attributeName, 'http://www.w3.org/XML/1998/namespace', false, // sanitizeURL
596 false);
597 }); // These attribute exists both in HTML and SVG.
598 // The attribute name is case-sensitive in SVG so we can't just use
599 // the React name like we do for attributes that exist only in HTML.
600
601 ['tabIndex', 'crossOrigin'].forEach(function (attributeName) {
602 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
603 attributeName.toLowerCase(), // attributeName
604 null, // attributeNamespace
605 false, // sanitizeURL
606 false);
607 }); // These attributes accept URLs. These must not allow javascript: URLS.
608 // These will also need to accept Trusted Types object in the future.
609
610 var xlinkHref = 'xlinkHref';
611 properties[xlinkHref] = new PropertyInfoRecord('xlinkHref', STRING, false, // mustUseProperty
612 'xlink:href', 'http://www.w3.org/1999/xlink', true, // sanitizeURL
613 false);
614 ['src', 'href', 'action', 'formAction'].forEach(function (attributeName) {
615 properties[attributeName] = new PropertyInfoRecord(attributeName, STRING, false, // mustUseProperty
616 attributeName.toLowerCase(), // attributeName
617 null, // attributeNamespace
618 true, // sanitizeURL
619 true);
620 });
621
622 // and any newline or tab are filtered out as if they're not part of the URL.
623 // https://url.spec.whatwg.org/#url-parsing
624 // Tab or newline are defined as \r\n\t:
625 // https://infra.spec.whatwg.org/#ascii-tab-or-newline
626 // A C0 control is a code point in the range \u0000 NULL to \u001F
627 // INFORMATION SEPARATOR ONE, inclusive:
628 // https://infra.spec.whatwg.org/#c0-control-or-space
629
630 /* eslint-disable max-len */
631
632 var 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;
633 var didWarn = false;
634
635 function sanitizeURL(url) {
636 {
637 if (!didWarn && isJavaScriptProtocol.test(url)) {
638 didWarn = true;
639
640 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));
641 }
642 }
643 }
644
645 /**
646 * Get the value for a property on a node. Only used in DEV for SSR validation.
647 * The "expected" argument is used as a hint of what the expected value is.
648 * Some properties have multiple equivalent values.
649 */
650 function getValueForProperty(node, name, expected, propertyInfo) {
651 {
652 if (propertyInfo.mustUseProperty) {
653 var propertyName = propertyInfo.propertyName;
654 return node[propertyName];
655 } else {
656 // This check protects multiple uses of `expected`, which is why the
657 // react-internal/safe-string-coercion rule is disabled in several spots
658 // below.
659 {
660 checkAttributeStringCoercion(expected, name);
661 }
662
663 if ( propertyInfo.sanitizeURL) {
664 // If we haven't fully disabled javascript: URLs, and if
665 // the hydration is successful of a javascript: URL, we
666 // still want to warn on the client.
667 // eslint-disable-next-line react-internal/safe-string-coercion
668 sanitizeURL('' + expected);
669 }
670
671 var attributeName = propertyInfo.attributeName;
672 var stringValue = null;
673
674 if (propertyInfo.type === OVERLOADED_BOOLEAN) {
675 if (node.hasAttribute(attributeName)) {
676 var value = node.getAttribute(attributeName);
677
678 if (value === '') {
679 return true;
680 }
681
682 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
683 return value;
684 } // eslint-disable-next-line react-internal/safe-string-coercion
685
686
687 if (value === '' + expected) {
688 return expected;
689 }
690
691 return value;
692 }
693 } else if (node.hasAttribute(attributeName)) {
694 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
695 // We had an attribute but shouldn't have had one, so read it
696 // for the error message.
697 return node.getAttribute(attributeName);
698 }
699
700 if (propertyInfo.type === BOOLEAN) {
701 // If this was a boolean, it doesn't matter what the value is
702 // the fact that we have it is the same as the expected.
703 return expected;
704 } // Even if this property uses a namespace we use getAttribute
705 // because we assume its namespaced name is the same as our config.
706 // To use getAttributeNS we need the local name which we don't have
707 // in our config atm.
708
709
710 stringValue = node.getAttribute(attributeName);
711 }
712
713 if (shouldRemoveAttribute(name, expected, propertyInfo, false)) {
714 return stringValue === null ? expected : stringValue; // eslint-disable-next-line react-internal/safe-string-coercion
715 } else if (stringValue === '' + expected) {
716 return expected;
717 } else {
718 return stringValue;
719 }
720 }
721 }
722 }
723 /**
724 * Get the value for a attribute on a node. Only used in DEV for SSR validation.
725 * The third argument is used as a hint of what the expected value is. Some
726 * attributes have multiple equivalent values.
727 */
728
729 function getValueForAttribute(node, name, expected) {
730 {
731 if (!isAttributeNameSafe(name)) {
732 return;
733 }
734
735 if (!node.hasAttribute(name)) {
736 return expected === undefined ? undefined : null;
737 }
738
739 var value = node.getAttribute(name);
740
741 {
742 checkAttributeStringCoercion(expected, name);
743 }
744
745 if (value === '' + expected) {
746 return expected;
747 }
748
749 return value;
750 }
751 }
752 /**
753 * Sets the value for a property on a node.
754 *
755 * @param {DOMElement} node
756 * @param {string} name
757 * @param {*} value
758 */
759
760 function setValueForProperty(node, name, value, isCustomComponentTag) {
761 var propertyInfo = getPropertyInfo(name);
762
763 if (shouldIgnoreAttribute(name, propertyInfo, isCustomComponentTag)) {
764 return;
765 }
766
767 if (shouldRemoveAttribute(name, value, propertyInfo, isCustomComponentTag)) {
768 value = null;
769 } // If the prop isn't in the special list, treat it as a simple attribute.
770
771
772 if (isCustomComponentTag || propertyInfo === null) {
773 if (isAttributeNameSafe(name)) {
774 var _attributeName = name;
775
776 if (value === null) {
777 node.removeAttribute(_attributeName);
778 } else {
779 {
780 checkAttributeStringCoercion(value, name);
781 }
782
783 node.setAttribute(_attributeName, '' + value);
784 }
785 }
786
787 return;
788 }
789
790 var mustUseProperty = propertyInfo.mustUseProperty;
791
792 if (mustUseProperty) {
793 var propertyName = propertyInfo.propertyName;
794
795 if (value === null) {
796 var type = propertyInfo.type;
797 node[propertyName] = type === BOOLEAN ? false : '';
798 } else {
799 // Contrary to `setAttribute`, object properties are properly
800 // `toString`ed by IE8/9.
801 node[propertyName] = value;
802 }
803
804 return;
805 } // The rest are treated as attributes with special cases.
806
807
808 var attributeName = propertyInfo.attributeName,
809 attributeNamespace = propertyInfo.attributeNamespace;
810
811 if (value === null) {
812 node.removeAttribute(attributeName);
813 } else {
814 var _type = propertyInfo.type;
815 var attributeValue;
816
817 if (_type === BOOLEAN || _type === OVERLOADED_BOOLEAN && value === true) {
818 // If attribute type is boolean, we know for sure it won't be an execution sink
819 // and we won't require Trusted Type here.
820 attributeValue = '';
821 } else {
822 // `setAttribute` with objects becomes only `[object]` in IE8/9,
823 // ('' + value) makes it output the correct toString()-value.
824 {
825 {
826 checkAttributeStringCoercion(value, attributeName);
827 }
828
829 attributeValue = '' + value;
830 }
831
832 if (propertyInfo.sanitizeURL) {
833 sanitizeURL(attributeValue.toString());
834 }
835 }
836
837 if (attributeNamespace) {
838 node.setAttributeNS(attributeNamespace, attributeName, attributeValue);
839 } else {
840 node.setAttribute(attributeName, attributeValue);
841 }
842 }
843 }
844
845 // ATTENTION
846 // When adding new symbols to this file,
847 // Please consider also adding to 'react-devtools-shared/src/backend/ReactSymbols'
848 // The Symbol used to tag the ReactElement-like types.
849 var REACT_ELEMENT_TYPE = Symbol.for('react.element');
850 var REACT_PORTAL_TYPE = Symbol.for('react.portal');
851 var REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
852 var REACT_STRICT_MODE_TYPE = Symbol.for('react.strict_mode');
853 var REACT_PROFILER_TYPE = Symbol.for('react.profiler');
854 var REACT_PROVIDER_TYPE = Symbol.for('react.provider');
855 var REACT_CONTEXT_TYPE = Symbol.for('react.context');
856 var REACT_FORWARD_REF_TYPE = Symbol.for('react.forward_ref');
857 var REACT_SUSPENSE_TYPE = Symbol.for('react.suspense');
858 var REACT_SUSPENSE_LIST_TYPE = Symbol.for('react.suspense_list');
859 var REACT_MEMO_TYPE = Symbol.for('react.memo');
860 var REACT_LAZY_TYPE = Symbol.for('react.lazy');
861 var REACT_SCOPE_TYPE = Symbol.for('react.scope');
862 var REACT_DEBUG_TRACING_MODE_TYPE = Symbol.for('react.debug_trace_mode');
863 var REACT_OFFSCREEN_TYPE = Symbol.for('react.offscreen');
864 var REACT_LEGACY_HIDDEN_TYPE = Symbol.for('react.legacy_hidden');
865 var REACT_CACHE_TYPE = Symbol.for('react.cache');
866 var REACT_TRACING_MARKER_TYPE = Symbol.for('react.tracing_marker');
867 var MAYBE_ITERATOR_SYMBOL = Symbol.iterator;
868 var FAUX_ITERATOR_SYMBOL = '@@iterator';
869 function getIteratorFn(maybeIterable) {
870 if (maybeIterable === null || typeof maybeIterable !== 'object') {
871 return null;
872 }
873
874 var maybeIterator = MAYBE_ITERATOR_SYMBOL && maybeIterable[MAYBE_ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL];
875
876 if (typeof maybeIterator === 'function') {
877 return maybeIterator;
878 }
879
880 return null;
881 }
882
883 var assign = Object.assign;
884
885 // Helpers to patch console.logs to avoid logging during side-effect free
886 // replaying on render function. This currently only patches the object
887 // lazily which won't cover if the log function was extracted eagerly.
888 // We could also eagerly patch the method.
889 var disabledDepth = 0;
890 var prevLog;
891 var prevInfo;
892 var prevWarn;
893 var prevError;
894 var prevGroup;
895 var prevGroupCollapsed;
896 var prevGroupEnd;
897
898 function disabledLog() {}
899
900 disabledLog.__reactDisabledLog = true;
901 function disableLogs() {
902 {
903 if (disabledDepth === 0) {
904 /* eslint-disable react-internal/no-production-logging */
905 prevLog = console.log;
906 prevInfo = console.info;
907 prevWarn = console.warn;
908 prevError = console.error;
909 prevGroup = console.group;
910 prevGroupCollapsed = console.groupCollapsed;
911 prevGroupEnd = console.groupEnd; // https://github.com/facebook/react/issues/19099
912
913 var props = {
914 configurable: true,
915 enumerable: true,
916 value: disabledLog,
917 writable: true
918 }; // $FlowFixMe Flow thinks console is immutable.
919
920 Object.defineProperties(console, {
921 info: props,
922 log: props,
923 warn: props,
924 error: props,
925 group: props,
926 groupCollapsed: props,
927 groupEnd: props
928 });
929 /* eslint-enable react-internal/no-production-logging */
930 }
931
932 disabledDepth++;
933 }
934 }
935 function reenableLogs() {
936 {
937 disabledDepth--;
938
939 if (disabledDepth === 0) {
940 /* eslint-disable react-internal/no-production-logging */
941 var props = {
942 configurable: true,
943 enumerable: true,
944 writable: true
945 }; // $FlowFixMe Flow thinks console is immutable.
946
947 Object.defineProperties(console, {
948 log: assign({}, props, {
949 value: prevLog
950 }),
951 info: assign({}, props, {
952 value: prevInfo
953 }),
954 warn: assign({}, props, {
955 value: prevWarn
956 }),
957 error: assign({}, props, {
958 value: prevError
959 }),
960 group: assign({}, props, {
961 value: prevGroup
962 }),
963 groupCollapsed: assign({}, props, {
964 value: prevGroupCollapsed
965 }),
966 groupEnd: assign({}, props, {
967 value: prevGroupEnd
968 })
969 });
970 /* eslint-enable react-internal/no-production-logging */
971 }
972
973 if (disabledDepth < 0) {
974 error('disabledDepth fell below zero. ' + 'This is a bug in React. Please file an issue.');
975 }
976 }
977 }
978
979 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
980 var prefix;
981 function describeBuiltInComponentFrame(name, source, ownerFn) {
982 {
983 if (prefix === undefined) {
984 // Extract the VM specific prefix used by each line.
985 try {
986 throw Error();
987 } catch (x) {
988 var match = x.stack.trim().match(/\n( *(at )?)/);
989 prefix = match && match[1] || '';
990 }
991 } // We use the prefix to ensure our stacks line up with native stack frames.
992
993
994 return '\n' + prefix + name;
995 }
996 }
997 var reentry = false;
998 var componentFrameCache;
999
1000 {
1001 var PossiblyWeakMap = typeof WeakMap === 'function' ? WeakMap : Map;
1002 componentFrameCache = new PossiblyWeakMap();
1003 }
1004
1005 function describeNativeComponentFrame(fn, construct) {
1006 // If something asked for a stack inside a fake render, it should get ignored.
1007 if ( !fn || reentry) {
1008 return '';
1009 }
1010
1011 {
1012 var frame = componentFrameCache.get(fn);
1013
1014 if (frame !== undefined) {
1015 return frame;
1016 }
1017 }
1018
1019 var control;
1020 reentry = true;
1021 var previousPrepareStackTrace = Error.prepareStackTrace; // $FlowFixMe It does accept undefined.
1022
1023 Error.prepareStackTrace = undefined;
1024 var previousDispatcher;
1025
1026 {
1027 previousDispatcher = ReactCurrentDispatcher.current; // Set the dispatcher in DEV because this might be call in the render function
1028 // for warnings.
1029
1030 ReactCurrentDispatcher.current = null;
1031 disableLogs();
1032 }
1033
1034 try {
1035 // This should throw.
1036 if (construct) {
1037 // Something should be setting the props in the constructor.
1038 var Fake = function () {
1039 throw Error();
1040 }; // $FlowFixMe
1041
1042
1043 Object.defineProperty(Fake.prototype, 'props', {
1044 set: function () {
1045 // We use a throwing setter instead of frozen or non-writable props
1046 // because that won't throw in a non-strict mode function.
1047 throw Error();
1048 }
1049 });
1050
1051 if (typeof Reflect === 'object' && Reflect.construct) {
1052 // We construct a different control for this case to include any extra
1053 // frames added by the construct call.
1054 try {
1055 Reflect.construct(Fake, []);
1056 } catch (x) {
1057 control = x;
1058 }
1059
1060 Reflect.construct(fn, [], Fake);
1061 } else {
1062 try {
1063 Fake.call();
1064 } catch (x) {
1065 control = x;
1066 }
1067
1068 fn.call(Fake.prototype);
1069 }
1070 } else {
1071 try {
1072 throw Error();
1073 } catch (x) {
1074 control = x;
1075 }
1076
1077 fn();
1078 }
1079 } catch (sample) {
1080 // This is inlined manually because closure doesn't do it for us.
1081 if (sample && control && typeof sample.stack === 'string') {
1082 // This extracts the first frame from the sample that isn't also in the control.
1083 // Skipping one frame that we assume is the frame that calls the two.
1084 var sampleLines = sample.stack.split('\n');
1085 var controlLines = control.stack.split('\n');
1086 var s = sampleLines.length - 1;
1087 var c = controlLines.length - 1;
1088
1089 while (s >= 1 && c >= 0 && sampleLines[s] !== controlLines[c]) {
1090 // We expect at least one stack frame to be shared.
1091 // Typically this will be the root most one. However, stack frames may be
1092 // cut off due to maximum stack limits. In this case, one maybe cut off
1093 // earlier than the other. We assume that the sample is longer or the same
1094 // and there for cut off earlier. So we should find the root most frame in
1095 // the sample somewhere in the control.
1096 c--;
1097 }
1098
1099 for (; s >= 1 && c >= 0; s--, c--) {
1100 // Next we find the first one that isn't the same which should be the
1101 // frame that called our sample function and the control.
1102 if (sampleLines[s] !== controlLines[c]) {
1103 // In V8, the first line is describing the message but other VMs don't.
1104 // If we're about to return the first line, and the control is also on the same
1105 // line, that's a pretty good indicator that our sample threw at same line as
1106 // the control. I.e. before we entered the sample frame. So we ignore this result.
1107 // This can happen if you passed a class to function component, or non-function.
1108 if (s !== 1 || c !== 1) {
1109 do {
1110 s--;
1111 c--; // We may still have similar intermediate frames from the construct call.
1112 // The next one that isn't the same should be our match though.
1113
1114 if (c < 0 || sampleLines[s] !== controlLines[c]) {
1115 // V8 adds a "new" prefix for native classes. Let's remove it to make it prettier.
1116 var _frame = '\n' + sampleLines[s].replace(' at new ', ' at '); // If our component frame is labeled "<anonymous>"
1117 // but we have a user-provided "displayName"
1118 // splice it in to make the stack more readable.
1119
1120
1121 if (fn.displayName && _frame.includes('<anonymous>')) {
1122 _frame = _frame.replace('<anonymous>', fn.displayName);
1123 }
1124
1125 {
1126 if (typeof fn === 'function') {
1127 componentFrameCache.set(fn, _frame);
1128 }
1129 } // Return the line we found.
1130
1131
1132 return _frame;
1133 }
1134 } while (s >= 1 && c >= 0);
1135 }
1136
1137 break;
1138 }
1139 }
1140 }
1141 } finally {
1142 reentry = false;
1143
1144 {
1145 ReactCurrentDispatcher.current = previousDispatcher;
1146 reenableLogs();
1147 }
1148
1149 Error.prepareStackTrace = previousPrepareStackTrace;
1150 } // Fallback to just using the name if we couldn't make it throw.
1151
1152
1153 var name = fn ? fn.displayName || fn.name : '';
1154 var syntheticFrame = name ? describeBuiltInComponentFrame(name) : '';
1155
1156 {
1157 if (typeof fn === 'function') {
1158 componentFrameCache.set(fn, syntheticFrame);
1159 }
1160 }
1161
1162 return syntheticFrame;
1163 }
1164
1165 function describeClassComponentFrame(ctor, source, ownerFn) {
1166 {
1167 return describeNativeComponentFrame(ctor, true);
1168 }
1169 }
1170 function describeFunctionComponentFrame(fn, source, ownerFn) {
1171 {
1172 return describeNativeComponentFrame(fn, false);
1173 }
1174 }
1175
1176 function shouldConstruct(Component) {
1177 var prototype = Component.prototype;
1178 return !!(prototype && prototype.isReactComponent);
1179 }
1180
1181 function describeUnknownElementTypeFrameInDEV(type, source, ownerFn) {
1182
1183 if (type == null) {
1184 return '';
1185 }
1186
1187 if (typeof type === 'function') {
1188 {
1189 return describeNativeComponentFrame(type, shouldConstruct(type));
1190 }
1191 }
1192
1193 if (typeof type === 'string') {
1194 return describeBuiltInComponentFrame(type);
1195 }
1196
1197 switch (type) {
1198 case REACT_SUSPENSE_TYPE:
1199 return describeBuiltInComponentFrame('Suspense');
1200
1201 case REACT_SUSPENSE_LIST_TYPE:
1202 return describeBuiltInComponentFrame('SuspenseList');
1203 }
1204
1205 if (typeof type === 'object') {
1206 switch (type.$$typeof) {
1207 case REACT_FORWARD_REF_TYPE:
1208 return describeFunctionComponentFrame(type.render);
1209
1210 case REACT_MEMO_TYPE:
1211 // Memo may contain any component type so we recursively resolve it.
1212 return describeUnknownElementTypeFrameInDEV(type.type, source, ownerFn);
1213
1214 case REACT_LAZY_TYPE:
1215 {
1216 var lazyComponent = type;
1217 var payload = lazyComponent._payload;
1218 var init = lazyComponent._init;
1219
1220 try {
1221 // Lazy may contain any component type so we recursively resolve it.
1222 return describeUnknownElementTypeFrameInDEV(init(payload), source, ownerFn);
1223 } catch (x) {}
1224 }
1225 }
1226 }
1227
1228 return '';
1229 }
1230
1231 function describeFiber(fiber) {
1232 var owner = fiber._debugOwner ? fiber._debugOwner.type : null ;
1233 var source = fiber._debugSource ;
1234
1235 switch (fiber.tag) {
1236 case HostComponent:
1237 return describeBuiltInComponentFrame(fiber.type);
1238
1239 case LazyComponent:
1240 return describeBuiltInComponentFrame('Lazy');
1241
1242 case SuspenseComponent:
1243 return describeBuiltInComponentFrame('Suspense');
1244
1245 case SuspenseListComponent:
1246 return describeBuiltInComponentFrame('SuspenseList');
1247
1248 case FunctionComponent:
1249 case IndeterminateComponent:
1250 case SimpleMemoComponent:
1251 return describeFunctionComponentFrame(fiber.type);
1252
1253 case ForwardRef:
1254 return describeFunctionComponentFrame(fiber.type.render);
1255
1256 case ClassComponent:
1257 return describeClassComponentFrame(fiber.type);
1258
1259 default:
1260 return '';
1261 }
1262 }
1263
1264 function getStackByFiberInDevAndProd(workInProgress) {
1265 try {
1266 var info = '';
1267 var node = workInProgress;
1268
1269 do {
1270 info += describeFiber(node);
1271 node = node.return;
1272 } while (node);
1273
1274 return info;
1275 } catch (x) {
1276 return '\nError generating stack: ' + x.message + '\n' + x.stack;
1277 }
1278 }
1279
1280 function getWrappedName(outerType, innerType, wrapperName) {
1281 var displayName = outerType.displayName;
1282
1283 if (displayName) {
1284 return displayName;
1285 }
1286
1287 var functionName = innerType.displayName || innerType.name || '';
1288 return functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName;
1289 } // Keep in sync with react-reconciler/getComponentNameFromFiber
1290
1291
1292 function getContextName(type) {
1293 return type.displayName || 'Context';
1294 } // Note that the reconciler package should generally prefer to use getComponentNameFromFiber() instead.
1295
1296
1297 function getComponentNameFromType(type) {
1298 if (type == null) {
1299 // Host root, text node or just invalid type.
1300 return null;
1301 }
1302
1303 {
1304 if (typeof type.tag === 'number') {
1305 error('Received an unexpected object in getComponentNameFromType(). ' + 'This is likely a bug in React. Please file an issue.');
1306 }
1307 }
1308
1309 if (typeof type === 'function') {
1310 return type.displayName || type.name || null;
1311 }
1312
1313 if (typeof type === 'string') {
1314 return type;
1315 }
1316
1317 switch (type) {
1318 case REACT_FRAGMENT_TYPE:
1319 return 'Fragment';
1320
1321 case REACT_PORTAL_TYPE:
1322 return 'Portal';
1323
1324 case REACT_PROFILER_TYPE:
1325 return 'Profiler';
1326
1327 case REACT_STRICT_MODE_TYPE:
1328 return 'StrictMode';
1329
1330 case REACT_SUSPENSE_TYPE:
1331 return 'Suspense';
1332
1333 case REACT_SUSPENSE_LIST_TYPE:
1334 return 'SuspenseList';
1335
1336 }
1337
1338 if (typeof type === 'object') {
1339 switch (type.$$typeof) {
1340 case REACT_CONTEXT_TYPE:
1341 var context = type;
1342 return getContextName(context) + '.Consumer';
1343
1344 case REACT_PROVIDER_TYPE:
1345 var provider = type;
1346 return getContextName(provider._context) + '.Provider';
1347
1348 case REACT_FORWARD_REF_TYPE:
1349 return getWrappedName(type, type.render, 'ForwardRef');
1350
1351 case REACT_MEMO_TYPE:
1352 var outerName = type.displayName || null;
1353
1354 if (outerName !== null) {
1355 return outerName;
1356 }
1357
1358 return getComponentNameFromType(type.type) || 'Memo';
1359
1360 case REACT_LAZY_TYPE:
1361 {
1362 var lazyComponent = type;
1363 var payload = lazyComponent._payload;
1364 var init = lazyComponent._init;
1365
1366 try {
1367 return getComponentNameFromType(init(payload));
1368 } catch (x) {
1369 return null;
1370 }
1371 }
1372
1373 // eslint-disable-next-line no-fallthrough
1374 }
1375 }
1376
1377 return null;
1378 }
1379
1380 function getWrappedName$1(outerType, innerType, wrapperName) {
1381 var functionName = innerType.displayName || innerType.name || '';
1382 return outerType.displayName || (functionName !== '' ? wrapperName + "(" + functionName + ")" : wrapperName);
1383 } // Keep in sync with shared/getComponentNameFromType
1384
1385
1386 function getContextName$1(type) {
1387 return type.displayName || 'Context';
1388 }
1389
1390 function getComponentNameFromFiber(fiber) {
1391 var tag = fiber.tag,
1392 type = fiber.type;
1393
1394 switch (tag) {
1395 case CacheComponent:
1396 return 'Cache';
1397
1398 case ContextConsumer:
1399 var context = type;
1400 return getContextName$1(context) + '.Consumer';
1401
1402 case ContextProvider:
1403 var provider = type;
1404 return getContextName$1(provider._context) + '.Provider';
1405
1406 case DehydratedFragment:
1407 return 'DehydratedFragment';
1408
1409 case ForwardRef:
1410 return getWrappedName$1(type, type.render, 'ForwardRef');
1411
1412 case Fragment:
1413 return 'Fragment';
1414
1415 case HostComponent:
1416 // Host component type is the display name (e.g. "div", "View")
1417 return type;
1418
1419 case HostPortal:
1420 return 'Portal';
1421
1422 case HostRoot:
1423 return 'Root';
1424
1425 case HostText:
1426 return 'Text';
1427
1428 case LazyComponent:
1429 // Name comes from the type in this case; we don't have a tag.
1430 return getComponentNameFromType(type);
1431
1432 case Mode:
1433 if (type === REACT_STRICT_MODE_TYPE) {
1434 // Don't be less specific than shared/getComponentNameFromType
1435 return 'StrictMode';
1436 }
1437
1438 return 'Mode';
1439
1440 case OffscreenComponent:
1441 return 'Offscreen';
1442
1443 case Profiler:
1444 return 'Profiler';
1445
1446 case ScopeComponent:
1447 return 'Scope';
1448
1449 case SuspenseComponent:
1450 return 'Suspense';
1451
1452 case SuspenseListComponent:
1453 return 'SuspenseList';
1454
1455 case TracingMarkerComponent:
1456 return 'TracingMarker';
1457 // The display name for this tags come from the user-provided type:
1458
1459 case ClassComponent:
1460 case FunctionComponent:
1461 case IncompleteClassComponent:
1462 case IndeterminateComponent:
1463 case MemoComponent:
1464 case SimpleMemoComponent:
1465 if (typeof type === 'function') {
1466 return type.displayName || type.name || null;
1467 }
1468
1469 if (typeof type === 'string') {
1470 return type;
1471 }
1472
1473 break;
1474
1475 }
1476
1477 return null;
1478 }
1479
1480 var ReactDebugCurrentFrame = ReactSharedInternals.ReactDebugCurrentFrame;
1481 var current = null;
1482 var isRendering = false;
1483 function getCurrentFiberOwnerNameInDevOrNull() {
1484 {
1485 if (current === null) {
1486 return null;
1487 }
1488
1489 var owner = current._debugOwner;
1490
1491 if (owner !== null && typeof owner !== 'undefined') {
1492 return getComponentNameFromFiber(owner);
1493 }
1494 }
1495
1496 return null;
1497 }
1498
1499 function getCurrentFiberStackInDev() {
1500 {
1501 if (current === null) {
1502 return '';
1503 } // Safe because if current fiber exists, we are reconciling,
1504 // and it is guaranteed to be the work-in-progress version.
1505
1506
1507 return getStackByFiberInDevAndProd(current);
1508 }
1509 }
1510
1511 function resetCurrentFiber() {
1512 {
1513 ReactDebugCurrentFrame.getCurrentStack = null;
1514 current = null;
1515 isRendering = false;
1516 }
1517 }
1518 function setCurrentFiber(fiber) {
1519 {
1520 ReactDebugCurrentFrame.getCurrentStack = getCurrentFiberStackInDev;
1521 current = fiber;
1522 isRendering = false;
1523 }
1524 }
1525 function setIsRendering(rendering) {
1526 {
1527 isRendering = rendering;
1528 }
1529 }
1530
1531 // Flow does not allow string concatenation of most non-string types. To work
1532 // around this limitation, we use an opaque type that can only be obtained by
1533 // passing the value through getToStringValue first.
1534 function toString(value) {
1535 // The coercion safety check is performed in getToStringValue().
1536 // eslint-disable-next-line react-internal/safe-string-coercion
1537 return '' + value;
1538 }
1539 function getToStringValue(value) {
1540 switch (typeof value) {
1541 case 'boolean':
1542 case 'number':
1543 case 'string':
1544 case 'undefined':
1545 return value;
1546
1547 case 'object':
1548 {
1549 checkFormFieldValueStringCoercion(value);
1550 }
1551
1552 return value;
1553
1554 default:
1555 // function, symbol are assigned as empty strings
1556 return '';
1557 }
1558 }
1559
1560 var hasReadOnlyValue = {
1561 button: true,
1562 checkbox: true,
1563 image: true,
1564 hidden: true,
1565 radio: true,
1566 reset: true,
1567 submit: true
1568 };
1569 function checkControlledValueProps(tagName, props) {
1570 {
1571 if (!(hasReadOnlyValue[props.type] || props.onChange || props.onInput || props.readOnly || props.disabled || props.value == null)) {
1572 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`.');
1573 }
1574
1575 if (!(props.onChange || props.readOnly || props.disabled || props.checked == null)) {
1576 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`.');
1577 }
1578 }
1579 }
1580
1581 function isCheckable(elem) {
1582 var type = elem.type;
1583 var nodeName = elem.nodeName;
1584 return nodeName && nodeName.toLowerCase() === 'input' && (type === 'checkbox' || type === 'radio');
1585 }
1586
1587 function getTracker(node) {
1588 return node._valueTracker;
1589 }
1590
1591 function detachTracker(node) {
1592 node._valueTracker = null;
1593 }
1594
1595 function getValueFromNode(node) {
1596 var value = '';
1597
1598 if (!node) {
1599 return value;
1600 }
1601
1602 if (isCheckable(node)) {
1603 value = node.checked ? 'true' : 'false';
1604 } else {
1605 value = node.value;
1606 }
1607
1608 return value;
1609 }
1610
1611 function trackValueOnNode(node) {
1612 var valueField = isCheckable(node) ? 'checked' : 'value';
1613 var descriptor = Object.getOwnPropertyDescriptor(node.constructor.prototype, valueField);
1614
1615 {
1616 checkFormFieldValueStringCoercion(node[valueField]);
1617 }
1618
1619 var currentValue = '' + node[valueField]; // if someone has already defined a value or Safari, then bail
1620 // and don't track value will cause over reporting of changes,
1621 // but it's better then a hard failure
1622 // (needed for certain tests that spyOn input values and Safari)
1623
1624 if (node.hasOwnProperty(valueField) || typeof descriptor === 'undefined' || typeof descriptor.get !== 'function' || typeof descriptor.set !== 'function') {
1625 return;
1626 }
1627
1628 var get = descriptor.get,
1629 set = descriptor.set;
1630 Object.defineProperty(node, valueField, {
1631 configurable: true,
1632 get: function () {
1633 return get.call(this);
1634 },
1635 set: function (value) {
1636 {
1637 checkFormFieldValueStringCoercion(value);
1638 }
1639
1640 currentValue = '' + value;
1641 set.call(this, value);
1642 }
1643 }); // We could've passed this the first time
1644 // but it triggers a bug in IE11 and Edge 14/15.
1645 // Calling defineProperty() again should be equivalent.
1646 // https://github.com/facebook/react/issues/11768
1647
1648 Object.defineProperty(node, valueField, {
1649 enumerable: descriptor.enumerable
1650 });
1651 var tracker = {
1652 getValue: function () {
1653 return currentValue;
1654 },
1655 setValue: function (value) {
1656 {
1657 checkFormFieldValueStringCoercion(value);
1658 }
1659
1660 currentValue = '' + value;
1661 },
1662 stopTracking: function () {
1663 detachTracker(node);
1664 delete node[valueField];
1665 }
1666 };
1667 return tracker;
1668 }
1669
1670 function track(node) {
1671 if (getTracker(node)) {
1672 return;
1673 } // TODO: Once it's just Fiber we can move this to node._wrapperState
1674
1675
1676 node._valueTracker = trackValueOnNode(node);
1677 }
1678 function updateValueIfChanged(node) {
1679 if (!node) {
1680 return false;
1681 }
1682
1683 var tracker = getTracker(node); // if there is no tracker at this point it's unlikely
1684 // that trying again will succeed
1685
1686 if (!tracker) {
1687 return true;
1688 }
1689
1690 var lastValue = tracker.getValue();
1691 var nextValue = getValueFromNode(node);
1692
1693 if (nextValue !== lastValue) {
1694 tracker.setValue(nextValue);
1695 return true;
1696 }
1697
1698 return false;
1699 }
1700
1701 function getActiveElement(doc) {
1702 doc = doc || (typeof document !== 'undefined' ? document : undefined);
1703
1704 if (typeof doc === 'undefined') {
1705 return null;
1706 }
1707
1708 try {
1709 return doc.activeElement || doc.body;
1710 } catch (e) {
1711 return doc.body;
1712 }
1713 }
1714
1715 var didWarnValueDefaultValue = false;
1716 var didWarnCheckedDefaultChecked = false;
1717 var didWarnControlledToUncontrolled = false;
1718 var didWarnUncontrolledToControlled = false;
1719
1720 function isControlled(props) {
1721 var usesChecked = props.type === 'checkbox' || props.type === 'radio';
1722 return usesChecked ? props.checked != null : props.value != null;
1723 }
1724 /**
1725 * Implements an <input> host component that allows setting these optional
1726 * props: `checked`, `value`, `defaultChecked`, and `defaultValue`.
1727 *
1728 * If `checked` or `value` are not supplied (or null/undefined), user actions
1729 * that affect the checked state or value will trigger updates to the element.
1730 *
1731 * If they are supplied (and not null/undefined), the rendered element will not
1732 * trigger updates to the element. Instead, the props must change in order for
1733 * the rendered element to be updated.
1734 *
1735 * The rendered element will be initialized as unchecked (or `defaultChecked`)
1736 * with an empty value (or `defaultValue`).
1737 *
1738 * See http://www.w3.org/TR/2012/WD-html5-20121025/the-input-element.html
1739 */
1740
1741
1742 function getHostProps(element, props) {
1743 var node = element;
1744 var checked = props.checked;
1745 var hostProps = assign({}, props, {
1746 defaultChecked: undefined,
1747 defaultValue: undefined,
1748 value: undefined,
1749 checked: checked != null ? checked : node._wrapperState.initialChecked
1750 });
1751 return hostProps;
1752 }
1753 function initWrapperState(element, props) {
1754 {
1755 checkControlledValueProps('input', props);
1756
1757 if (props.checked !== undefined && props.defaultChecked !== undefined && !didWarnCheckedDefaultChecked) {
1758 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);
1759
1760 didWarnCheckedDefaultChecked = true;
1761 }
1762
1763 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue) {
1764 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);
1765
1766 didWarnValueDefaultValue = true;
1767 }
1768 }
1769
1770 var node = element;
1771 var defaultValue = props.defaultValue == null ? '' : props.defaultValue;
1772 node._wrapperState = {
1773 initialChecked: props.checked != null ? props.checked : props.defaultChecked,
1774 initialValue: getToStringValue(props.value != null ? props.value : defaultValue),
1775 controlled: isControlled(props)
1776 };
1777 }
1778 function updateChecked(element, props) {
1779 var node = element;
1780 var checked = props.checked;
1781
1782 if (checked != null) {
1783 setValueForProperty(node, 'checked', checked, false);
1784 }
1785 }
1786 function updateWrapper(element, props) {
1787 var node = element;
1788
1789 {
1790 var controlled = isControlled(props);
1791
1792 if (!node._wrapperState.controlled && controlled && !didWarnUncontrolledToControlled) {
1793 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');
1794
1795 didWarnUncontrolledToControlled = true;
1796 }
1797
1798 if (node._wrapperState.controlled && !controlled && !didWarnControlledToUncontrolled) {
1799 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');
1800
1801 didWarnControlledToUncontrolled = true;
1802 }
1803 }
1804
1805 updateChecked(element, props);
1806 var value = getToStringValue(props.value);
1807 var type = props.type;
1808
1809 if (value != null) {
1810 if (type === 'number') {
1811 if (value === 0 && node.value === '' || // We explicitly want to coerce to number here if possible.
1812 // eslint-disable-next-line
1813 node.value != value) {
1814 node.value = toString(value);
1815 }
1816 } else if (node.value !== toString(value)) {
1817 node.value = toString(value);
1818 }
1819 } else if (type === 'submit' || type === 'reset') {
1820 // Submit/reset inputs need the attribute removed completely to avoid
1821 // blank-text buttons.
1822 node.removeAttribute('value');
1823 return;
1824 }
1825
1826 {
1827 // When syncing the value attribute, the value comes from a cascade of
1828 // properties:
1829 // 1. The value React property
1830 // 2. The defaultValue React property
1831 // 3. Otherwise there should be no change
1832 if (props.hasOwnProperty('value')) {
1833 setDefaultValue(node, props.type, value);
1834 } else if (props.hasOwnProperty('defaultValue')) {
1835 setDefaultValue(node, props.type, getToStringValue(props.defaultValue));
1836 }
1837 }
1838
1839 {
1840 // When syncing the checked attribute, it only changes when it needs
1841 // to be removed, such as transitioning from a checkbox into a text input
1842 if (props.checked == null && props.defaultChecked != null) {
1843 node.defaultChecked = !!props.defaultChecked;
1844 }
1845 }
1846 }
1847 function postMountWrapper(element, props, isHydrating) {
1848 var node = element; // Do not assign value if it is already set. This prevents user text input
1849 // from being lost during SSR hydration.
1850
1851 if (props.hasOwnProperty('value') || props.hasOwnProperty('defaultValue')) {
1852 var type = props.type;
1853 var isButton = type === 'submit' || type === 'reset'; // Avoid setting value attribute on submit/reset inputs as it overrides the
1854 // default value provided by the browser. See: #12872
1855
1856 if (isButton && (props.value === undefined || props.value === null)) {
1857 return;
1858 }
1859
1860 var initialValue = toString(node._wrapperState.initialValue); // Do not assign value if it is already set. This prevents user text input
1861 // from being lost during SSR hydration.
1862
1863 if (!isHydrating) {
1864 {
1865 // When syncing the value attribute, the value property should use
1866 // the wrapperState._initialValue property. This uses:
1867 //
1868 // 1. The value React property when present
1869 // 2. The defaultValue React property when present
1870 // 3. An empty string
1871 if (initialValue !== node.value) {
1872 node.value = initialValue;
1873 }
1874 }
1875 }
1876
1877 {
1878 // Otherwise, the value attribute is synchronized to the property,
1879 // so we assign defaultValue to the same thing as the value property
1880 // assignment step above.
1881 node.defaultValue = initialValue;
1882 }
1883 } // Normally, we'd just do `node.checked = node.checked` upon initial mount, less this bug
1884 // this is needed to work around a chrome bug where setting defaultChecked
1885 // will sometimes influence the value of checked (even after detachment).
1886 // Reference: https://bugs.chromium.org/p/chromium/issues/detail?id=608416
1887 // We need to temporarily unset name to avoid disrupting radio button groups.
1888
1889
1890 var name = node.name;
1891
1892 if (name !== '') {
1893 node.name = '';
1894 }
1895
1896 {
1897 // When syncing the checked attribute, both the checked property and
1898 // attribute are assigned at the same time using defaultChecked. This uses:
1899 //
1900 // 1. The checked React property when present
1901 // 2. The defaultChecked React property when present
1902 // 3. Otherwise, false
1903 node.defaultChecked = !node.defaultChecked;
1904 node.defaultChecked = !!node._wrapperState.initialChecked;
1905 }
1906
1907 if (name !== '') {
1908 node.name = name;
1909 }
1910 }
1911 function restoreControlledState(element, props) {
1912 var node = element;
1913 updateWrapper(node, props);
1914 updateNamedCousins(node, props);
1915 }
1916
1917 function updateNamedCousins(rootNode, props) {
1918 var name = props.name;
1919
1920 if (props.type === 'radio' && name != null) {
1921 var queryRoot = rootNode;
1922
1923 while (queryRoot.parentNode) {
1924 queryRoot = queryRoot.parentNode;
1925 } // If `rootNode.form` was non-null, then we could try `form.elements`,
1926 // but that sometimes behaves strangely in IE8. We could also try using
1927 // `form.getElementsByName`, but that will only return direct children
1928 // and won't include inputs that use the HTML5 `form=` attribute. Since
1929 // the input might not even be in a form. It might not even be in the
1930 // document. Let's just use the local `querySelectorAll` to ensure we don't
1931 // miss anything.
1932
1933
1934 {
1935 checkAttributeStringCoercion(name, 'name');
1936 }
1937
1938 var group = queryRoot.querySelectorAll('input[name=' + JSON.stringify('' + name) + '][type="radio"]');
1939
1940 for (var i = 0; i < group.length; i++) {
1941 var otherNode = group[i];
1942
1943 if (otherNode === rootNode || otherNode.form !== rootNode.form) {
1944 continue;
1945 } // This will throw if radio buttons rendered by different copies of React
1946 // and the same name are rendered into the same form (same as #1939).
1947 // That's probably okay; we don't support it just as we don't support
1948 // mixing React radio buttons with non-React ones.
1949
1950
1951 var otherProps = getFiberCurrentPropsFromNode(otherNode);
1952
1953 if (!otherProps) {
1954 throw new Error('ReactDOMInput: Mixing React and non-React radio inputs with the ' + 'same `name` is not supported.');
1955 } // We need update the tracked value on the named cousin since the value
1956 // was changed but the input saw no event or value set
1957
1958
1959 updateValueIfChanged(otherNode); // If this is a controlled radio button group, forcing the input that
1960 // was previously checked to update will cause it to be come re-checked
1961 // as appropriate.
1962
1963 updateWrapper(otherNode, otherProps);
1964 }
1965 }
1966 } // In Chrome, assigning defaultValue to certain input types triggers input validation.
1967 // For number inputs, the display value loses trailing decimal points. For email inputs,
1968 // Chrome raises "The specified value <x> is not a valid email address".
1969 //
1970 // Here we check to see if the defaultValue has actually changed, avoiding these problems
1971 // when the user is inputting text
1972 //
1973 // https://github.com/facebook/react/issues/7253
1974
1975
1976 function setDefaultValue(node, type, value) {
1977 if ( // Focused number inputs synchronize on blur. See ChangeEventPlugin.js
1978 type !== 'number' || getActiveElement(node.ownerDocument) !== node) {
1979 if (value == null) {
1980 node.defaultValue = toString(node._wrapperState.initialValue);
1981 } else if (node.defaultValue !== toString(value)) {
1982 node.defaultValue = toString(value);
1983 }
1984 }
1985 }
1986
1987 var didWarnSelectedSetOnOption = false;
1988 var didWarnInvalidChild = false;
1989 var didWarnInvalidInnerHTML = false;
1990 /**
1991 * Implements an <option> host component that warns when `selected` is set.
1992 */
1993
1994 function validateProps(element, props) {
1995 {
1996 // If a value is not provided, then the children must be simple.
1997 if (props.value == null) {
1998 if (typeof props.children === 'object' && props.children !== null) {
1999 React.Children.forEach(props.children, function (child) {
2000 if (child == null) {
2001 return;
2002 }
2003
2004 if (typeof child === 'string' || typeof child === 'number') {
2005 return;
2006 }
2007
2008 if (!didWarnInvalidChild) {
2009 didWarnInvalidChild = true;
2010
2011 error('Cannot infer the option value of complex children. ' + 'Pass a `value` prop or use a plain string as children to <option>.');
2012 }
2013 });
2014 } else if (props.dangerouslySetInnerHTML != null) {
2015 if (!didWarnInvalidInnerHTML) {
2016 didWarnInvalidInnerHTML = true;
2017
2018 error('Pass a `value` prop if you set dangerouslyInnerHTML so React knows ' + 'which value should be selected.');
2019 }
2020 }
2021 } // TODO: Remove support for `selected` in <option>.
2022
2023
2024 if (props.selected != null && !didWarnSelectedSetOnOption) {
2025 error('Use the `defaultValue` or `value` props on <select> instead of ' + 'setting `selected` on <option>.');
2026
2027 didWarnSelectedSetOnOption = true;
2028 }
2029 }
2030 }
2031 function postMountWrapper$1(element, props) {
2032 // value="" should make a value attribute (#6219)
2033 if (props.value != null) {
2034 element.setAttribute('value', toString(getToStringValue(props.value)));
2035 }
2036 }
2037
2038 var isArrayImpl = Array.isArray; // eslint-disable-next-line no-redeclare
2039
2040 function isArray(a) {
2041 return isArrayImpl(a);
2042 }
2043
2044 var didWarnValueDefaultValue$1;
2045
2046 {
2047 didWarnValueDefaultValue$1 = false;
2048 }
2049
2050 function getDeclarationErrorAddendum() {
2051 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
2052
2053 if (ownerName) {
2054 return '\n\nCheck the render method of `' + ownerName + '`.';
2055 }
2056
2057 return '';
2058 }
2059
2060 var valuePropNames = ['value', 'defaultValue'];
2061 /**
2062 * Validation function for `value` and `defaultValue`.
2063 */
2064
2065 function checkSelectPropTypes(props) {
2066 {
2067 checkControlledValueProps('select', props);
2068
2069 for (var i = 0; i < valuePropNames.length; i++) {
2070 var propName = valuePropNames[i];
2071
2072 if (props[propName] == null) {
2073 continue;
2074 }
2075
2076 var propNameIsArray = isArray(props[propName]);
2077
2078 if (props.multiple && !propNameIsArray) {
2079 error('The `%s` prop supplied to <select> must be an array if ' + '`multiple` is true.%s', propName, getDeclarationErrorAddendum());
2080 } else if (!props.multiple && propNameIsArray) {
2081 error('The `%s` prop supplied to <select> must be a scalar ' + 'value if `multiple` is false.%s', propName, getDeclarationErrorAddendum());
2082 }
2083 }
2084 }
2085 }
2086
2087 function updateOptions(node, multiple, propValue, setDefaultSelected) {
2088 var options = node.options;
2089
2090 if (multiple) {
2091 var selectedValues = propValue;
2092 var selectedValue = {};
2093
2094 for (var i = 0; i < selectedValues.length; i++) {
2095 // Prefix to avoid chaos with special keys.
2096 selectedValue['$' + selectedValues[i]] = true;
2097 }
2098
2099 for (var _i = 0; _i < options.length; _i++) {
2100 var selected = selectedValue.hasOwnProperty('$' + options[_i].value);
2101
2102 if (options[_i].selected !== selected) {
2103 options[_i].selected = selected;
2104 }
2105
2106 if (selected && setDefaultSelected) {
2107 options[_i].defaultSelected = true;
2108 }
2109 }
2110 } else {
2111 // Do not set `select.value` as exact behavior isn't consistent across all
2112 // browsers for all cases.
2113 var _selectedValue = toString(getToStringValue(propValue));
2114
2115 var defaultSelected = null;
2116
2117 for (var _i2 = 0; _i2 < options.length; _i2++) {
2118 if (options[_i2].value === _selectedValue) {
2119 options[_i2].selected = true;
2120
2121 if (setDefaultSelected) {
2122 options[_i2].defaultSelected = true;
2123 }
2124
2125 return;
2126 }
2127
2128 if (defaultSelected === null && !options[_i2].disabled) {
2129 defaultSelected = options[_i2];
2130 }
2131 }
2132
2133 if (defaultSelected !== null) {
2134 defaultSelected.selected = true;
2135 }
2136 }
2137 }
2138 /**
2139 * Implements a <select> host component that allows optionally setting the
2140 * props `value` and `defaultValue`. If `multiple` is false, the prop must be a
2141 * stringable. If `multiple` is true, the prop must be an array of stringables.
2142 *
2143 * If `value` is not supplied (or null/undefined), user actions that change the
2144 * selected option will trigger updates to the rendered options.
2145 *
2146 * If it is supplied (and not null/undefined), the rendered options will not
2147 * update in response to user actions. Instead, the `value` prop must change in
2148 * order for the rendered options to update.
2149 *
2150 * If `defaultValue` is provided, any options with the supplied values will be
2151 * selected.
2152 */
2153
2154
2155 function getHostProps$1(element, props) {
2156 return assign({}, props, {
2157 value: undefined
2158 });
2159 }
2160 function initWrapperState$1(element, props) {
2161 var node = element;
2162
2163 {
2164 checkSelectPropTypes(props);
2165 }
2166
2167 node._wrapperState = {
2168 wasMultiple: !!props.multiple
2169 };
2170
2171 {
2172 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValueDefaultValue$1) {
2173 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');
2174
2175 didWarnValueDefaultValue$1 = true;
2176 }
2177 }
2178 }
2179 function postMountWrapper$2(element, props) {
2180 var node = element;
2181 node.multiple = !!props.multiple;
2182 var value = props.value;
2183
2184 if (value != null) {
2185 updateOptions(node, !!props.multiple, value, false);
2186 } else if (props.defaultValue != null) {
2187 updateOptions(node, !!props.multiple, props.defaultValue, true);
2188 }
2189 }
2190 function postUpdateWrapper(element, props) {
2191 var node = element;
2192 var wasMultiple = node._wrapperState.wasMultiple;
2193 node._wrapperState.wasMultiple = !!props.multiple;
2194 var value = props.value;
2195
2196 if (value != null) {
2197 updateOptions(node, !!props.multiple, value, false);
2198 } else if (wasMultiple !== !!props.multiple) {
2199 // For simplicity, reapply `defaultValue` if `multiple` is toggled.
2200 if (props.defaultValue != null) {
2201 updateOptions(node, !!props.multiple, props.defaultValue, true);
2202 } else {
2203 // Revert the select back to its default unselected state.
2204 updateOptions(node, !!props.multiple, props.multiple ? [] : '', false);
2205 }
2206 }
2207 }
2208 function restoreControlledState$1(element, props) {
2209 var node = element;
2210 var value = props.value;
2211
2212 if (value != null) {
2213 updateOptions(node, !!props.multiple, value, false);
2214 }
2215 }
2216
2217 var didWarnValDefaultVal = false;
2218
2219 /**
2220 * Implements a <textarea> host component that allows setting `value`, and
2221 * `defaultValue`. This differs from the traditional DOM API because value is
2222 * usually set as PCDATA children.
2223 *
2224 * If `value` is not supplied (or null/undefined), user actions that affect the
2225 * value will trigger updates to the element.
2226 *
2227 * If `value` is supplied (and not null/undefined), the rendered element will
2228 * not trigger updates to the element. Instead, the `value` prop must change in
2229 * order for the rendered element to be updated.
2230 *
2231 * The rendered element will be initialized with an empty value, the prop
2232 * `defaultValue` if specified, or the children content (deprecated).
2233 */
2234 function getHostProps$2(element, props) {
2235 var node = element;
2236
2237 if (props.dangerouslySetInnerHTML != null) {
2238 throw new Error('`dangerouslySetInnerHTML` does not make sense on <textarea>.');
2239 } // Always set children to the same thing. In IE9, the selection range will
2240 // get reset if `textContent` is mutated. We could add a check in setTextContent
2241 // to only set the value if/when the value differs from the node value (which would
2242 // completely solve this IE9 bug), but Sebastian+Sophie seemed to like this
2243 // solution. The value can be a boolean or object so that's why it's forced
2244 // to be a string.
2245
2246
2247 var hostProps = assign({}, props, {
2248 value: undefined,
2249 defaultValue: undefined,
2250 children: toString(node._wrapperState.initialValue)
2251 });
2252
2253 return hostProps;
2254 }
2255 function initWrapperState$2(element, props) {
2256 var node = element;
2257
2258 {
2259 checkControlledValueProps('textarea', props);
2260
2261 if (props.value !== undefined && props.defaultValue !== undefined && !didWarnValDefaultVal) {
2262 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');
2263
2264 didWarnValDefaultVal = true;
2265 }
2266 }
2267
2268 var initialValue = props.value; // Only bother fetching default value if we're going to use it
2269
2270 if (initialValue == null) {
2271 var children = props.children,
2272 defaultValue = props.defaultValue;
2273
2274 if (children != null) {
2275 {
2276 error('Use the `defaultValue` or `value` props instead of setting ' + 'children on <textarea>.');
2277 }
2278
2279 {
2280 if (defaultValue != null) {
2281 throw new Error('If you supply `defaultValue` on a <textarea>, do not pass children.');
2282 }
2283
2284 if (isArray(children)) {
2285 if (children.length > 1) {
2286 throw new Error('<textarea> can only have at most one child.');
2287 }
2288
2289 children = children[0];
2290 }
2291
2292 defaultValue = children;
2293 }
2294 }
2295
2296 if (defaultValue == null) {
2297 defaultValue = '';
2298 }
2299
2300 initialValue = defaultValue;
2301 }
2302
2303 node._wrapperState = {
2304 initialValue: getToStringValue(initialValue)
2305 };
2306 }
2307 function updateWrapper$1(element, props) {
2308 var node = element;
2309 var value = getToStringValue(props.value);
2310 var defaultValue = getToStringValue(props.defaultValue);
2311
2312 if (value != null) {
2313 // Cast `value` to a string to ensure the value is set correctly. While
2314 // browsers typically do this as necessary, jsdom doesn't.
2315 var newValue = toString(value); // To avoid side effects (such as losing text selection), only set value if changed
2316
2317 if (newValue !== node.value) {
2318 node.value = newValue;
2319 }
2320
2321 if (props.defaultValue == null && node.defaultValue !== newValue) {
2322 node.defaultValue = newValue;
2323 }
2324 }
2325
2326 if (defaultValue != null) {
2327 node.defaultValue = toString(defaultValue);
2328 }
2329 }
2330 function postMountWrapper$3(element, props) {
2331 var node = element; // This is in postMount because we need access to the DOM node, which is not
2332 // available until after the component has mounted.
2333
2334 var textContent = node.textContent; // Only set node.value if textContent is equal to the expected
2335 // initial value. In IE10/IE11 there is a bug where the placeholder attribute
2336 // will populate textContent as well.
2337 // https://developer.microsoft.com/microsoft-edge/platform/issues/101525/
2338
2339 if (textContent === node._wrapperState.initialValue) {
2340 if (textContent !== '' && textContent !== null) {
2341 node.value = textContent;
2342 }
2343 }
2344 }
2345 function restoreControlledState$2(element, props) {
2346 // DOM component is still mounted; update
2347 updateWrapper$1(element, props);
2348 }
2349
2350 var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
2351 var MATH_NAMESPACE = 'http://www.w3.org/1998/Math/MathML';
2352 var SVG_NAMESPACE = 'http://www.w3.org/2000/svg'; // Assumes there is no parent namespace.
2353
2354 function getIntrinsicNamespace(type) {
2355 switch (type) {
2356 case 'svg':
2357 return SVG_NAMESPACE;
2358
2359 case 'math':
2360 return MATH_NAMESPACE;
2361
2362 default:
2363 return HTML_NAMESPACE;
2364 }
2365 }
2366 function getChildNamespace(parentNamespace, type) {
2367 if (parentNamespace == null || parentNamespace === HTML_NAMESPACE) {
2368 // No (or default) parent namespace: potential entry point.
2369 return getIntrinsicNamespace(type);
2370 }
2371
2372 if (parentNamespace === SVG_NAMESPACE && type === 'foreignObject') {
2373 // We're leaving SVG.
2374 return HTML_NAMESPACE;
2375 } // By default, pass namespace below.
2376
2377
2378 return parentNamespace;
2379 }
2380
2381 /* globals MSApp */
2382
2383 /**
2384 * Create a function which has 'unsafe' privileges (required by windows8 apps)
2385 */
2386 var createMicrosoftUnsafeLocalFunction = function (func) {
2387 if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
2388 return function (arg0, arg1, arg2, arg3) {
2389 MSApp.execUnsafeLocalFunction(function () {
2390 return func(arg0, arg1, arg2, arg3);
2391 });
2392 };
2393 } else {
2394 return func;
2395 }
2396 };
2397
2398 var reusableSVGContainer;
2399 /**
2400 * Set the innerHTML property of a node
2401 *
2402 * @param {DOMElement} node
2403 * @param {string} html
2404 * @internal
2405 */
2406
2407 var setInnerHTML = createMicrosoftUnsafeLocalFunction(function (node, html) {
2408 if (node.namespaceURI === SVG_NAMESPACE) {
2409
2410 if (!('innerHTML' in node)) {
2411 // IE does not have innerHTML for SVG nodes, so instead we inject the
2412 // new markup in a temp node and then move the child nodes across into
2413 // the target node
2414 reusableSVGContainer = reusableSVGContainer || document.createElement('div');
2415 reusableSVGContainer.innerHTML = '<svg>' + html.valueOf().toString() + '</svg>';
2416 var svgNode = reusableSVGContainer.firstChild;
2417
2418 while (node.firstChild) {
2419 node.removeChild(node.firstChild);
2420 }
2421
2422 while (svgNode.firstChild) {
2423 node.appendChild(svgNode.firstChild);
2424 }
2425
2426 return;
2427 }
2428 }
2429
2430 node.innerHTML = html;
2431 });
2432
2433 /**
2434 * HTML nodeType values that represent the type of the node
2435 */
2436 var ELEMENT_NODE = 1;
2437 var TEXT_NODE = 3;
2438 var COMMENT_NODE = 8;
2439 var DOCUMENT_NODE = 9;
2440 var DOCUMENT_FRAGMENT_NODE = 11;
2441
2442 /**
2443 * Set the textContent property of a node. For text updates, it's faster
2444 * to set the `nodeValue` of the Text node directly instead of using
2445 * `.textContent` which will remove the existing node and create a new one.
2446 *
2447 * @param {DOMElement} node
2448 * @param {string} text
2449 * @internal
2450 */
2451
2452 var setTextContent = function (node, text) {
2453 if (text) {
2454 var firstChild = node.firstChild;
2455
2456 if (firstChild && firstChild === node.lastChild && firstChild.nodeType === TEXT_NODE) {
2457 firstChild.nodeValue = text;
2458 return;
2459 }
2460 }
2461
2462 node.textContent = text;
2463 };
2464
2465 // List derived from Gecko source code:
2466 // https://github.com/mozilla/gecko-dev/blob/4e638efc71/layout/style/test/property_database.js
2467 var shorthandToLonghand = {
2468 animation: ['animationDelay', 'animationDirection', 'animationDuration', 'animationFillMode', 'animationIterationCount', 'animationName', 'animationPlayState', 'animationTimingFunction'],
2469 background: ['backgroundAttachment', 'backgroundClip', 'backgroundColor', 'backgroundImage', 'backgroundOrigin', 'backgroundPositionX', 'backgroundPositionY', 'backgroundRepeat', 'backgroundSize'],
2470 backgroundPosition: ['backgroundPositionX', 'backgroundPositionY'],
2471 border: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth', 'borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth', 'borderLeftColor', 'borderLeftStyle', 'borderLeftWidth', 'borderRightColor', 'borderRightStyle', 'borderRightWidth', 'borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2472 borderBlockEnd: ['borderBlockEndColor', 'borderBlockEndStyle', 'borderBlockEndWidth'],
2473 borderBlockStart: ['borderBlockStartColor', 'borderBlockStartStyle', 'borderBlockStartWidth'],
2474 borderBottom: ['borderBottomColor', 'borderBottomStyle', 'borderBottomWidth'],
2475 borderColor: ['borderBottomColor', 'borderLeftColor', 'borderRightColor', 'borderTopColor'],
2476 borderImage: ['borderImageOutset', 'borderImageRepeat', 'borderImageSlice', 'borderImageSource', 'borderImageWidth'],
2477 borderInlineEnd: ['borderInlineEndColor', 'borderInlineEndStyle', 'borderInlineEndWidth'],
2478 borderInlineStart: ['borderInlineStartColor', 'borderInlineStartStyle', 'borderInlineStartWidth'],
2479 borderLeft: ['borderLeftColor', 'borderLeftStyle', 'borderLeftWidth'],
2480 borderRadius: ['borderBottomLeftRadius', 'borderBottomRightRadius', 'borderTopLeftRadius', 'borderTopRightRadius'],
2481 borderRight: ['borderRightColor', 'borderRightStyle', 'borderRightWidth'],
2482 borderStyle: ['borderBottomStyle', 'borderLeftStyle', 'borderRightStyle', 'borderTopStyle'],
2483 borderTop: ['borderTopColor', 'borderTopStyle', 'borderTopWidth'],
2484 borderWidth: ['borderBottomWidth', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth'],
2485 columnRule: ['columnRuleColor', 'columnRuleStyle', 'columnRuleWidth'],
2486 columns: ['columnCount', 'columnWidth'],
2487 flex: ['flexBasis', 'flexGrow', 'flexShrink'],
2488 flexFlow: ['flexDirection', 'flexWrap'],
2489 font: ['fontFamily', 'fontFeatureSettings', 'fontKerning', 'fontLanguageOverride', 'fontSize', 'fontSizeAdjust', 'fontStretch', 'fontStyle', 'fontVariant', 'fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition', 'fontWeight', 'lineHeight'],
2490 fontVariant: ['fontVariantAlternates', 'fontVariantCaps', 'fontVariantEastAsian', 'fontVariantLigatures', 'fontVariantNumeric', 'fontVariantPosition'],
2491 gap: ['columnGap', 'rowGap'],
2492 grid: ['gridAutoColumns', 'gridAutoFlow', 'gridAutoRows', 'gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2493 gridArea: ['gridColumnEnd', 'gridColumnStart', 'gridRowEnd', 'gridRowStart'],
2494 gridColumn: ['gridColumnEnd', 'gridColumnStart'],
2495 gridColumnGap: ['columnGap'],
2496 gridGap: ['columnGap', 'rowGap'],
2497 gridRow: ['gridRowEnd', 'gridRowStart'],
2498 gridRowGap: ['rowGap'],
2499 gridTemplate: ['gridTemplateAreas', 'gridTemplateColumns', 'gridTemplateRows'],
2500 listStyle: ['listStyleImage', 'listStylePosition', 'listStyleType'],
2501 margin: ['marginBottom', 'marginLeft', 'marginRight', 'marginTop'],
2502 marker: ['markerEnd', 'markerMid', 'markerStart'],
2503 mask: ['maskClip', 'maskComposite', 'maskImage', 'maskMode', 'maskOrigin', 'maskPositionX', 'maskPositionY', 'maskRepeat', 'maskSize'],
2504 maskPosition: ['maskPositionX', 'maskPositionY'],
2505 outline: ['outlineColor', 'outlineStyle', 'outlineWidth'],
2506 overflow: ['overflowX', 'overflowY'],
2507 padding: ['paddingBottom', 'paddingLeft', 'paddingRight', 'paddingTop'],
2508 placeContent: ['alignContent', 'justifyContent'],
2509 placeItems: ['alignItems', 'justifyItems'],
2510 placeSelf: ['alignSelf', 'justifySelf'],
2511 textDecoration: ['textDecorationColor', 'textDecorationLine', 'textDecorationStyle'],
2512 textEmphasis: ['textEmphasisColor', 'textEmphasisStyle'],
2513 transition: ['transitionDelay', 'transitionDuration', 'transitionProperty', 'transitionTimingFunction'],
2514 wordWrap: ['overflowWrap']
2515 };
2516
2517 /**
2518 * CSS properties which accept numbers but are not in units of "px".
2519 */
2520 var isUnitlessNumber = {
2521 animationIterationCount: true,
2522 aspectRatio: true,
2523 borderImageOutset: true,
2524 borderImageSlice: true,
2525 borderImageWidth: true,
2526 boxFlex: true,
2527 boxFlexGroup: true,
2528 boxOrdinalGroup: true,
2529 columnCount: true,
2530 columns: true,
2531 flex: true,
2532 flexGrow: true,
2533 flexPositive: true,
2534 flexShrink: true,
2535 flexNegative: true,
2536 flexOrder: true,
2537 gridArea: true,
2538 gridRow: true,
2539 gridRowEnd: true,
2540 gridRowSpan: true,
2541 gridRowStart: true,
2542 gridColumn: true,
2543 gridColumnEnd: true,
2544 gridColumnSpan: true,
2545 gridColumnStart: true,
2546 fontWeight: true,
2547 lineClamp: true,
2548 lineHeight: true,
2549 opacity: true,
2550 order: true,
2551 orphans: true,
2552 tabSize: true,
2553 widows: true,
2554 zIndex: true,
2555 zoom: true,
2556 // SVG-related properties
2557 fillOpacity: true,
2558 floodOpacity: true,
2559 stopOpacity: true,
2560 strokeDasharray: true,
2561 strokeDashoffset: true,
2562 strokeMiterlimit: true,
2563 strokeOpacity: true,
2564 strokeWidth: true
2565 };
2566 /**
2567 * @param {string} prefix vendor-specific prefix, eg: Webkit
2568 * @param {string} key style name, eg: transitionDuration
2569 * @return {string} style name prefixed with `prefix`, properly camelCased, eg:
2570 * WebkitTransitionDuration
2571 */
2572
2573 function prefixKey(prefix, key) {
2574 return prefix + key.charAt(0).toUpperCase() + key.substring(1);
2575 }
2576 /**
2577 * Support style names that may come passed in prefixed by adding permutations
2578 * of vendor prefixes.
2579 */
2580
2581
2582 var prefixes = ['Webkit', 'ms', 'Moz', 'O']; // Using Object.keys here, or else the vanilla for-in loop makes IE8 go into an
2583 // infinite loop, because it iterates over the newly added props too.
2584
2585 Object.keys(isUnitlessNumber).forEach(function (prop) {
2586 prefixes.forEach(function (prefix) {
2587 isUnitlessNumber[prefixKey(prefix, prop)] = isUnitlessNumber[prop];
2588 });
2589 });
2590
2591 /**
2592 * Convert a value into the proper css writable value. The style name `name`
2593 * should be logical (no hyphens), as specified
2594 * in `CSSProperty.isUnitlessNumber`.
2595 *
2596 * @param {string} name CSS property name such as `topMargin`.
2597 * @param {*} value CSS property value such as `10px`.
2598 * @return {string} Normalized style value with dimensions applied.
2599 */
2600
2601 function dangerousStyleValue(name, value, isCustomProperty) {
2602 // Note that we've removed escapeTextForBrowser() calls here since the
2603 // whole string will be escaped when the attribute is injected into
2604 // the markup. If you provide unsafe user data here they can inject
2605 // arbitrary CSS which may be problematic (I couldn't repro this):
2606 // https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
2607 // http://www.thespanner.co.uk/2007/11/26/ultimate-xss-css-injection/
2608 // This is not an XSS hole but instead a potential CSS injection issue
2609 // which has lead to a greater discussion about how we're going to
2610 // trust URLs moving forward. See #2115901
2611 var isEmpty = value == null || typeof value === 'boolean' || value === '';
2612
2613 if (isEmpty) {
2614 return '';
2615 }
2616
2617 if (!isCustomProperty && typeof value === 'number' && value !== 0 && !(isUnitlessNumber.hasOwnProperty(name) && isUnitlessNumber[name])) {
2618 return value + 'px'; // Presumes implicit 'px' suffix for unitless numbers
2619 }
2620
2621 {
2622 checkCSSPropertyStringCoercion(value, name);
2623 }
2624
2625 return ('' + value).trim();
2626 }
2627
2628 var uppercasePattern = /([A-Z])/g;
2629 var msPattern = /^ms-/;
2630 /**
2631 * Hyphenates a camelcased CSS property name, for example:
2632 *
2633 * > hyphenateStyleName('backgroundColor')
2634 * < "background-color"
2635 * > hyphenateStyleName('MozTransition')
2636 * < "-moz-transition"
2637 * > hyphenateStyleName('msTransition')
2638 * < "-ms-transition"
2639 *
2640 * As Modernizr suggests (http://modernizr.com/docs/#prefixed), an `ms` prefix
2641 * is converted to `-ms-`.
2642 */
2643
2644 function hyphenateStyleName(name) {
2645 return name.replace(uppercasePattern, '-$1').toLowerCase().replace(msPattern, '-ms-');
2646 }
2647
2648 var warnValidStyle = function () {};
2649
2650 {
2651 // 'msTransform' is correct, but the other prefixes should be capitalized
2652 var badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
2653 var msPattern$1 = /^-ms-/;
2654 var hyphenPattern = /-(.)/g; // style values shouldn't contain a semicolon
2655
2656 var badStyleValueWithSemicolonPattern = /;\s*$/;
2657 var warnedStyleNames = {};
2658 var warnedStyleValues = {};
2659 var warnedForNaNValue = false;
2660 var warnedForInfinityValue = false;
2661
2662 var camelize = function (string) {
2663 return string.replace(hyphenPattern, function (_, character) {
2664 return character.toUpperCase();
2665 });
2666 };
2667
2668 var warnHyphenatedStyleName = function (name) {
2669 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2670 return;
2671 }
2672
2673 warnedStyleNames[name] = true;
2674
2675 error('Unsupported style property %s. Did you mean %s?', name, // As Andi Smith suggests
2676 // (http://www.andismith.com/blog/2012/02/modernizr-prefixed/), an `-ms` prefix
2677 // is converted to lowercase `ms`.
2678 camelize(name.replace(msPattern$1, 'ms-')));
2679 };
2680
2681 var warnBadVendoredStyleName = function (name) {
2682 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
2683 return;
2684 }
2685
2686 warnedStyleNames[name] = true;
2687
2688 error('Unsupported vendor-prefixed style property %s. Did you mean %s?', name, name.charAt(0).toUpperCase() + name.slice(1));
2689 };
2690
2691 var warnStyleValueWithSemicolon = function (name, value) {
2692 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
2693 return;
2694 }
2695
2696 warnedStyleValues[value] = true;
2697
2698 error("Style property values shouldn't contain a semicolon. " + 'Try "%s: %s" instead.', name, value.replace(badStyleValueWithSemicolonPattern, ''));
2699 };
2700
2701 var warnStyleValueIsNaN = function (name, value) {
2702 if (warnedForNaNValue) {
2703 return;
2704 }
2705
2706 warnedForNaNValue = true;
2707
2708 error('`NaN` is an invalid value for the `%s` css style property.', name);
2709 };
2710
2711 var warnStyleValueIsInfinity = function (name, value) {
2712 if (warnedForInfinityValue) {
2713 return;
2714 }
2715
2716 warnedForInfinityValue = true;
2717
2718 error('`Infinity` is an invalid value for the `%s` css style property.', name);
2719 };
2720
2721 warnValidStyle = function (name, value) {
2722 if (name.indexOf('-') > -1) {
2723 warnHyphenatedStyleName(name);
2724 } else if (badVendoredStyleNamePattern.test(name)) {
2725 warnBadVendoredStyleName(name);
2726 } else if (badStyleValueWithSemicolonPattern.test(value)) {
2727 warnStyleValueWithSemicolon(name, value);
2728 }
2729
2730 if (typeof value === 'number') {
2731 if (isNaN(value)) {
2732 warnStyleValueIsNaN(name, value);
2733 } else if (!isFinite(value)) {
2734 warnStyleValueIsInfinity(name, value);
2735 }
2736 }
2737 };
2738 }
2739
2740 var warnValidStyle$1 = warnValidStyle;
2741
2742 /**
2743 * Operations for dealing with CSS properties.
2744 */
2745
2746 /**
2747 * This creates a string that is expected to be equivalent to the style
2748 * attribute generated by server-side rendering. It by-passes warnings and
2749 * security checks so it's not safe to use this value for anything other than
2750 * comparison. It is only used in DEV for SSR validation.
2751 */
2752
2753 function createDangerousStringForStyles(styles) {
2754 {
2755 var serialized = '';
2756 var delimiter = '';
2757
2758 for (var styleName in styles) {
2759 if (!styles.hasOwnProperty(styleName)) {
2760 continue;
2761 }
2762
2763 var styleValue = styles[styleName];
2764
2765 if (styleValue != null) {
2766 var isCustomProperty = styleName.indexOf('--') === 0;
2767 serialized += delimiter + (isCustomProperty ? styleName : hyphenateStyleName(styleName)) + ':';
2768 serialized += dangerousStyleValue(styleName, styleValue, isCustomProperty);
2769 delimiter = ';';
2770 }
2771 }
2772
2773 return serialized || null;
2774 }
2775 }
2776 /**
2777 * Sets the value for multiple styles on a node. If a value is specified as
2778 * '' (empty string), the corresponding style property will be unset.
2779 *
2780 * @param {DOMElement} node
2781 * @param {object} styles
2782 */
2783
2784 function setValueForStyles(node, styles) {
2785 var style = node.style;
2786
2787 for (var styleName in styles) {
2788 if (!styles.hasOwnProperty(styleName)) {
2789 continue;
2790 }
2791
2792 var isCustomProperty = styleName.indexOf('--') === 0;
2793
2794 {
2795 if (!isCustomProperty) {
2796 warnValidStyle$1(styleName, styles[styleName]);
2797 }
2798 }
2799
2800 var styleValue = dangerousStyleValue(styleName, styles[styleName], isCustomProperty);
2801
2802 if (styleName === 'float') {
2803 styleName = 'cssFloat';
2804 }
2805
2806 if (isCustomProperty) {
2807 style.setProperty(styleName, styleValue);
2808 } else {
2809 style[styleName] = styleValue;
2810 }
2811 }
2812 }
2813
2814 function isValueEmpty(value) {
2815 return value == null || typeof value === 'boolean' || value === '';
2816 }
2817 /**
2818 * Given {color: 'red', overflow: 'hidden'} returns {
2819 * color: 'color',
2820 * overflowX: 'overflow',
2821 * overflowY: 'overflow',
2822 * }. This can be read as "the overflowY property was set by the overflow
2823 * shorthand". That is, the values are the property that each was derived from.
2824 */
2825
2826
2827 function expandShorthandMap(styles) {
2828 var expanded = {};
2829
2830 for (var key in styles) {
2831 var longhands = shorthandToLonghand[key] || [key];
2832
2833 for (var i = 0; i < longhands.length; i++) {
2834 expanded[longhands[i]] = key;
2835 }
2836 }
2837
2838 return expanded;
2839 }
2840 /**
2841 * When mixing shorthand and longhand property names, we warn during updates if
2842 * we expect an incorrect result to occur. In particular, we warn for:
2843 *
2844 * Updating a shorthand property (longhand gets overwritten):
2845 * {font: 'foo', fontVariant: 'bar'} -> {font: 'baz', fontVariant: 'bar'}
2846 * becomes .style.font = 'baz'
2847 * Removing a shorthand property (longhand gets lost too):
2848 * {font: 'foo', fontVariant: 'bar'} -> {fontVariant: 'bar'}
2849 * becomes .style.font = ''
2850 * Removing a longhand property (should revert to shorthand; doesn't):
2851 * {font: 'foo', fontVariant: 'bar'} -> {font: 'foo'}
2852 * becomes .style.fontVariant = ''
2853 */
2854
2855
2856 function validateShorthandPropertyCollisionInDev(styleUpdates, nextStyles) {
2857 {
2858 if (!nextStyles) {
2859 return;
2860 }
2861
2862 var expandedUpdates = expandShorthandMap(styleUpdates);
2863 var expandedStyles = expandShorthandMap(nextStyles);
2864 var warnedAbout = {};
2865
2866 for (var key in expandedUpdates) {
2867 var originalKey = expandedUpdates[key];
2868 var correctOriginalKey = expandedStyles[key];
2869
2870 if (correctOriginalKey && originalKey !== correctOriginalKey) {
2871 var warningKey = originalKey + ',' + correctOriginalKey;
2872
2873 if (warnedAbout[warningKey]) {
2874 continue;
2875 }
2876
2877 warnedAbout[warningKey] = true;
2878
2879 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);
2880 }
2881 }
2882 }
2883 }
2884
2885 // For HTML, certain tags should omit their close tag. We keep a list for
2886 // those special-case tags.
2887 var omittedCloseTags = {
2888 area: true,
2889 base: true,
2890 br: true,
2891 col: true,
2892 embed: true,
2893 hr: true,
2894 img: true,
2895 input: true,
2896 keygen: true,
2897 link: true,
2898 meta: true,
2899 param: true,
2900 source: true,
2901 track: true,
2902 wbr: true // NOTE: menuitem's close tag should be omitted, but that causes problems.
2903
2904 };
2905
2906 // `omittedCloseTags` except that `menuitem` should still have its closing tag.
2907
2908 var voidElementTags = assign({
2909 menuitem: true
2910 }, omittedCloseTags);
2911
2912 var HTML = '__html';
2913
2914 function assertValidProps(tag, props) {
2915 if (!props) {
2916 return;
2917 } // Note the use of `==` which checks for null or undefined.
2918
2919
2920 if (voidElementTags[tag]) {
2921 if (props.children != null || props.dangerouslySetInnerHTML != null) {
2922 throw new Error(tag + " is a void element tag and must neither have `children` nor " + 'use `dangerouslySetInnerHTML`.');
2923 }
2924 }
2925
2926 if (props.dangerouslySetInnerHTML != null) {
2927 if (props.children != null) {
2928 throw new Error('Can only set one of `children` or `props.dangerouslySetInnerHTML`.');
2929 }
2930
2931 if (typeof props.dangerouslySetInnerHTML !== 'object' || !(HTML in props.dangerouslySetInnerHTML)) {
2932 throw new Error('`props.dangerouslySetInnerHTML` must be in the form `{__html: ...}`. ' + 'Please visit https://reactjs.org/link/dangerously-set-inner-html ' + 'for more information.');
2933 }
2934 }
2935
2936 {
2937 if (!props.suppressContentEditableWarning && props.contentEditable && props.children != null) {
2938 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.');
2939 }
2940 }
2941
2942 if (props.style != null && typeof props.style !== 'object') {
2943 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.');
2944 }
2945 }
2946
2947 function isCustomComponent(tagName, props) {
2948 if (tagName.indexOf('-') === -1) {
2949 return typeof props.is === 'string';
2950 }
2951
2952 switch (tagName) {
2953 // These are reserved SVG and MathML elements.
2954 // We don't mind this list too much because we expect it to never grow.
2955 // The alternative is to track the namespace in a few places which is convoluted.
2956 // https://w3c.github.io/webcomponents/spec/custom/#custom-elements-core-concepts
2957 case 'annotation-xml':
2958 case 'color-profile':
2959 case 'font-face':
2960 case 'font-face-src':
2961 case 'font-face-uri':
2962 case 'font-face-format':
2963 case 'font-face-name':
2964 case 'missing-glyph':
2965 return false;
2966
2967 default:
2968 return true;
2969 }
2970 }
2971
2972 // When adding attributes to the HTML or SVG allowed attribute list, be sure to
2973 // also add them to this module to ensure casing and incorrect name
2974 // warnings.
2975 var possibleStandardNames = {
2976 // HTML
2977 accept: 'accept',
2978 acceptcharset: 'acceptCharset',
2979 'accept-charset': 'acceptCharset',
2980 accesskey: 'accessKey',
2981 action: 'action',
2982 allowfullscreen: 'allowFullScreen',
2983 alt: 'alt',
2984 as: 'as',
2985 async: 'async',
2986 autocapitalize: 'autoCapitalize',
2987 autocomplete: 'autoComplete',
2988 autocorrect: 'autoCorrect',
2989 autofocus: 'autoFocus',
2990 autoplay: 'autoPlay',
2991 autosave: 'autoSave',
2992 capture: 'capture',
2993 cellpadding: 'cellPadding',
2994 cellspacing: 'cellSpacing',
2995 challenge: 'challenge',
2996 charset: 'charSet',
2997 checked: 'checked',
2998 children: 'children',
2999 cite: 'cite',
3000 class: 'className',
3001 classid: 'classID',
3002 classname: 'className',
3003 cols: 'cols',
3004 colspan: 'colSpan',
3005 content: 'content',
3006 contenteditable: 'contentEditable',
3007 contextmenu: 'contextMenu',
3008 controls: 'controls',
3009 controlslist: 'controlsList',
3010 coords: 'coords',
3011 crossorigin: 'crossOrigin',
3012 dangerouslysetinnerhtml: 'dangerouslySetInnerHTML',
3013 data: 'data',
3014 datetime: 'dateTime',
3015 default: 'default',
3016 defaultchecked: 'defaultChecked',
3017 defaultvalue: 'defaultValue',
3018 defer: 'defer',
3019 dir: 'dir',
3020 disabled: 'disabled',
3021 disablepictureinpicture: 'disablePictureInPicture',
3022 disableremoteplayback: 'disableRemotePlayback',
3023 download: 'download',
3024 draggable: 'draggable',
3025 enctype: 'encType',
3026 enterkeyhint: 'enterKeyHint',
3027 for: 'htmlFor',
3028 form: 'form',
3029 formmethod: 'formMethod',
3030 formaction: 'formAction',
3031 formenctype: 'formEncType',
3032 formnovalidate: 'formNoValidate',
3033 formtarget: 'formTarget',
3034 frameborder: 'frameBorder',
3035 headers: 'headers',
3036 height: 'height',
3037 hidden: 'hidden',
3038 high: 'high',
3039 href: 'href',
3040 hreflang: 'hrefLang',
3041 htmlfor: 'htmlFor',
3042 httpequiv: 'httpEquiv',
3043 'http-equiv': 'httpEquiv',
3044 icon: 'icon',
3045 id: 'id',
3046 imagesizes: 'imageSizes',
3047 imagesrcset: 'imageSrcSet',
3048 innerhtml: 'innerHTML',
3049 inputmode: 'inputMode',
3050 integrity: 'integrity',
3051 is: 'is',
3052 itemid: 'itemID',
3053 itemprop: 'itemProp',
3054 itemref: 'itemRef',
3055 itemscope: 'itemScope',
3056 itemtype: 'itemType',
3057 keyparams: 'keyParams',
3058 keytype: 'keyType',
3059 kind: 'kind',
3060 label: 'label',
3061 lang: 'lang',
3062 list: 'list',
3063 loop: 'loop',
3064 low: 'low',
3065 manifest: 'manifest',
3066 marginwidth: 'marginWidth',
3067 marginheight: 'marginHeight',
3068 max: 'max',
3069 maxlength: 'maxLength',
3070 media: 'media',
3071 mediagroup: 'mediaGroup',
3072 method: 'method',
3073 min: 'min',
3074 minlength: 'minLength',
3075 multiple: 'multiple',
3076 muted: 'muted',
3077 name: 'name',
3078 nomodule: 'noModule',
3079 nonce: 'nonce',
3080 novalidate: 'noValidate',
3081 open: 'open',
3082 optimum: 'optimum',
3083 pattern: 'pattern',
3084 placeholder: 'placeholder',
3085 playsinline: 'playsInline',
3086 poster: 'poster',
3087 preload: 'preload',
3088 profile: 'profile',
3089 radiogroup: 'radioGroup',
3090 readonly: 'readOnly',
3091 referrerpolicy: 'referrerPolicy',
3092 rel: 'rel',
3093 required: 'required',
3094 reversed: 'reversed',
3095 role: 'role',
3096 rows: 'rows',
3097 rowspan: 'rowSpan',
3098 sandbox: 'sandbox',
3099 scope: 'scope',
3100 scoped: 'scoped',
3101 scrolling: 'scrolling',
3102 seamless: 'seamless',
3103 selected: 'selected',
3104 shape: 'shape',
3105 size: 'size',
3106 sizes: 'sizes',
3107 span: 'span',
3108 spellcheck: 'spellCheck',
3109 src: 'src',
3110 srcdoc: 'srcDoc',
3111 srclang: 'srcLang',
3112 srcset: 'srcSet',
3113 start: 'start',
3114 step: 'step',
3115 style: 'style',
3116 summary: 'summary',
3117 tabindex: 'tabIndex',
3118 target: 'target',
3119 title: 'title',
3120 type: 'type',
3121 usemap: 'useMap',
3122 value: 'value',
3123 width: 'width',
3124 wmode: 'wmode',
3125 wrap: 'wrap',
3126 // SVG
3127 about: 'about',
3128 accentheight: 'accentHeight',
3129 'accent-height': 'accentHeight',
3130 accumulate: 'accumulate',
3131 additive: 'additive',
3132 alignmentbaseline: 'alignmentBaseline',
3133 'alignment-baseline': 'alignmentBaseline',
3134 allowreorder: 'allowReorder',
3135 alphabetic: 'alphabetic',
3136 amplitude: 'amplitude',
3137 arabicform: 'arabicForm',
3138 'arabic-form': 'arabicForm',
3139 ascent: 'ascent',
3140 attributename: 'attributeName',
3141 attributetype: 'attributeType',
3142 autoreverse: 'autoReverse',
3143 azimuth: 'azimuth',
3144 basefrequency: 'baseFrequency',
3145 baselineshift: 'baselineShift',
3146 'baseline-shift': 'baselineShift',
3147 baseprofile: 'baseProfile',
3148 bbox: 'bbox',
3149 begin: 'begin',
3150 bias: 'bias',
3151 by: 'by',
3152 calcmode: 'calcMode',
3153 capheight: 'capHeight',
3154 'cap-height': 'capHeight',
3155 clip: 'clip',
3156 clippath: 'clipPath',
3157 'clip-path': 'clipPath',
3158 clippathunits: 'clipPathUnits',
3159 cliprule: 'clipRule',
3160 'clip-rule': 'clipRule',
3161 color: 'color',
3162 colorinterpolation: 'colorInterpolation',
3163 'color-interpolation': 'colorInterpolation',
3164 colorinterpolationfilters: 'colorInterpolationFilters',
3165 'color-interpolation-filters': 'colorInterpolationFilters',
3166 colorprofile: 'colorProfile',
3167 'color-profile': 'colorProfile',
3168 colorrendering: 'colorRendering',
3169 'color-rendering': 'colorRendering',
3170 contentscripttype: 'contentScriptType',
3171 contentstyletype: 'contentStyleType',
3172 cursor: 'cursor',
3173 cx: 'cx',
3174 cy: 'cy',
3175 d: 'd',
3176 datatype: 'datatype',
3177 decelerate: 'decelerate',
3178 descent: 'descent',
3179 diffuseconstant: 'diffuseConstant',
3180 direction: 'direction',
3181 display: 'display',
3182 divisor: 'divisor',
3183 dominantbaseline: 'dominantBaseline',
3184 'dominant-baseline': 'dominantBaseline',
3185 dur: 'dur',
3186 dx: 'dx',
3187 dy: 'dy',
3188 edgemode: 'edgeMode',
3189 elevation: 'elevation',
3190 enablebackground: 'enableBackground',
3191 'enable-background': 'enableBackground',
3192 end: 'end',
3193 exponent: 'exponent',
3194 externalresourcesrequired: 'externalResourcesRequired',
3195 fill: 'fill',
3196 fillopacity: 'fillOpacity',
3197 'fill-opacity': 'fillOpacity',
3198 fillrule: 'fillRule',
3199 'fill-rule': 'fillRule',
3200 filter: 'filter',
3201 filterres: 'filterRes',
3202 filterunits: 'filterUnits',
3203 floodopacity: 'floodOpacity',
3204 'flood-opacity': 'floodOpacity',
3205 floodcolor: 'floodColor',
3206 'flood-color': 'floodColor',
3207 focusable: 'focusable',
3208 fontfamily: 'fontFamily',
3209 'font-family': 'fontFamily',
3210 fontsize: 'fontSize',
3211 'font-size': 'fontSize',
3212 fontsizeadjust: 'fontSizeAdjust',
3213 'font-size-adjust': 'fontSizeAdjust',
3214 fontstretch: 'fontStretch',
3215 'font-stretch': 'fontStretch',
3216 fontstyle: 'fontStyle',
3217 'font-style': 'fontStyle',
3218 fontvariant: 'fontVariant',
3219 'font-variant': 'fontVariant',
3220 fontweight: 'fontWeight',
3221 'font-weight': 'fontWeight',
3222 format: 'format',
3223 from: 'from',
3224 fx: 'fx',
3225 fy: 'fy',
3226 g1: 'g1',
3227 g2: 'g2',
3228 glyphname: 'glyphName',
3229 'glyph-name': 'glyphName',
3230 glyphorientationhorizontal: 'glyphOrientationHorizontal',
3231 'glyph-orientation-horizontal': 'glyphOrientationHorizontal',
3232 glyphorientationvertical: 'glyphOrientationVertical',
3233 'glyph-orientation-vertical': 'glyphOrientationVertical',
3234 glyphref: 'glyphRef',
3235 gradienttransform: 'gradientTransform',
3236 gradientunits: 'gradientUnits',
3237 hanging: 'hanging',
3238 horizadvx: 'horizAdvX',
3239 'horiz-adv-x': 'horizAdvX',
3240 horizoriginx: 'horizOriginX',
3241 'horiz-origin-x': 'horizOriginX',
3242 ideographic: 'ideographic',
3243 imagerendering: 'imageRendering',
3244 'image-rendering': 'imageRendering',
3245 in2: 'in2',
3246 in: 'in',
3247 inlist: 'inlist',
3248 intercept: 'intercept',
3249 k1: 'k1',
3250 k2: 'k2',
3251 k3: 'k3',
3252 k4: 'k4',
3253 k: 'k',
3254 kernelmatrix: 'kernelMatrix',
3255 kernelunitlength: 'kernelUnitLength',
3256 kerning: 'kerning',
3257 keypoints: 'keyPoints',
3258 keysplines: 'keySplines',
3259 keytimes: 'keyTimes',
3260 lengthadjust: 'lengthAdjust',
3261 letterspacing: 'letterSpacing',
3262 'letter-spacing': 'letterSpacing',
3263 lightingcolor: 'lightingColor',
3264 'lighting-color': 'lightingColor',
3265 limitingconeangle: 'limitingConeAngle',
3266 local: 'local',
3267 markerend: 'markerEnd',
3268 'marker-end': 'markerEnd',
3269 markerheight: 'markerHeight',
3270 markermid: 'markerMid',
3271 'marker-mid': 'markerMid',
3272 markerstart: 'markerStart',
3273 'marker-start': 'markerStart',
3274 markerunits: 'markerUnits',
3275 markerwidth: 'markerWidth',
3276 mask: 'mask',
3277 maskcontentunits: 'maskContentUnits',
3278 maskunits: 'maskUnits',
3279 mathematical: 'mathematical',
3280 mode: 'mode',
3281 numoctaves: 'numOctaves',
3282 offset: 'offset',
3283 opacity: 'opacity',
3284 operator: 'operator',
3285 order: 'order',
3286 orient: 'orient',
3287 orientation: 'orientation',
3288 origin: 'origin',
3289 overflow: 'overflow',
3290 overlineposition: 'overlinePosition',
3291 'overline-position': 'overlinePosition',
3292 overlinethickness: 'overlineThickness',
3293 'overline-thickness': 'overlineThickness',
3294 paintorder: 'paintOrder',
3295 'paint-order': 'paintOrder',
3296 panose1: 'panose1',
3297 'panose-1': 'panose1',
3298 pathlength: 'pathLength',
3299 patterncontentunits: 'patternContentUnits',
3300 patterntransform: 'patternTransform',
3301 patternunits: 'patternUnits',
3302 pointerevents: 'pointerEvents',
3303 'pointer-events': 'pointerEvents',
3304 points: 'points',
3305 pointsatx: 'pointsAtX',
3306 pointsaty: 'pointsAtY',
3307 pointsatz: 'pointsAtZ',
3308 prefix: 'prefix',
3309 preservealpha: 'preserveAlpha',
3310 preserveaspectratio: 'preserveAspectRatio',
3311 primitiveunits: 'primitiveUnits',
3312 property: 'property',
3313 r: 'r',
3314 radius: 'radius',
3315 refx: 'refX',
3316 refy: 'refY',
3317 renderingintent: 'renderingIntent',
3318 'rendering-intent': 'renderingIntent',
3319 repeatcount: 'repeatCount',
3320 repeatdur: 'repeatDur',
3321 requiredextensions: 'requiredExtensions',
3322 requiredfeatures: 'requiredFeatures',
3323 resource: 'resource',
3324 restart: 'restart',
3325 result: 'result',
3326 results: 'results',
3327 rotate: 'rotate',
3328 rx: 'rx',
3329 ry: 'ry',
3330 scale: 'scale',
3331 security: 'security',
3332 seed: 'seed',
3333 shaperendering: 'shapeRendering',
3334 'shape-rendering': 'shapeRendering',
3335 slope: 'slope',
3336 spacing: 'spacing',
3337 specularconstant: 'specularConstant',
3338 specularexponent: 'specularExponent',
3339 speed: 'speed',
3340 spreadmethod: 'spreadMethod',
3341 startoffset: 'startOffset',
3342 stddeviation: 'stdDeviation',
3343 stemh: 'stemh',
3344 stemv: 'stemv',
3345 stitchtiles: 'stitchTiles',
3346 stopcolor: 'stopColor',
3347 'stop-color': 'stopColor',
3348 stopopacity: 'stopOpacity',
3349 'stop-opacity': 'stopOpacity',
3350 strikethroughposition: 'strikethroughPosition',
3351 'strikethrough-position': 'strikethroughPosition',
3352 strikethroughthickness: 'strikethroughThickness',
3353 'strikethrough-thickness': 'strikethroughThickness',
3354 string: 'string',
3355 stroke: 'stroke',
3356 strokedasharray: 'strokeDasharray',
3357 'stroke-dasharray': 'strokeDasharray',
3358 strokedashoffset: 'strokeDashoffset',
3359 'stroke-dashoffset': 'strokeDashoffset',
3360 strokelinecap: 'strokeLinecap',
3361 'stroke-linecap': 'strokeLinecap',
3362 strokelinejoin: 'strokeLinejoin',
3363 'stroke-linejoin': 'strokeLinejoin',
3364 strokemiterlimit: 'strokeMiterlimit',
3365 'stroke-miterlimit': 'strokeMiterlimit',
3366 strokewidth: 'strokeWidth',
3367 'stroke-width': 'strokeWidth',
3368 strokeopacity: 'strokeOpacity',
3369 'stroke-opacity': 'strokeOpacity',
3370 suppresscontenteditablewarning: 'suppressContentEditableWarning',
3371 suppresshydrationwarning: 'suppressHydrationWarning',
3372 surfacescale: 'surfaceScale',
3373 systemlanguage: 'systemLanguage',
3374 tablevalues: 'tableValues',
3375 targetx: 'targetX',
3376 targety: 'targetY',
3377 textanchor: 'textAnchor',
3378 'text-anchor': 'textAnchor',
3379 textdecoration: 'textDecoration',
3380 'text-decoration': 'textDecoration',
3381 textlength: 'textLength',
3382 textrendering: 'textRendering',
3383 'text-rendering': 'textRendering',
3384 to: 'to',
3385 transform: 'transform',
3386 typeof: 'typeof',
3387 u1: 'u1',
3388 u2: 'u2',
3389 underlineposition: 'underlinePosition',
3390 'underline-position': 'underlinePosition',
3391 underlinethickness: 'underlineThickness',
3392 'underline-thickness': 'underlineThickness',
3393 unicode: 'unicode',
3394 unicodebidi: 'unicodeBidi',
3395 'unicode-bidi': 'unicodeBidi',
3396 unicoderange: 'unicodeRange',
3397 'unicode-range': 'unicodeRange',
3398 unitsperem: 'unitsPerEm',
3399 'units-per-em': 'unitsPerEm',
3400 unselectable: 'unselectable',
3401 valphabetic: 'vAlphabetic',
3402 'v-alphabetic': 'vAlphabetic',
3403 values: 'values',
3404 vectoreffect: 'vectorEffect',
3405 'vector-effect': 'vectorEffect',
3406 version: 'version',
3407 vertadvy: 'vertAdvY',
3408 'vert-adv-y': 'vertAdvY',
3409 vertoriginx: 'vertOriginX',
3410 'vert-origin-x': 'vertOriginX',
3411 vertoriginy: 'vertOriginY',
3412 'vert-origin-y': 'vertOriginY',
3413 vhanging: 'vHanging',
3414 'v-hanging': 'vHanging',
3415 videographic: 'vIdeographic',
3416 'v-ideographic': 'vIdeographic',
3417 viewbox: 'viewBox',
3418 viewtarget: 'viewTarget',
3419 visibility: 'visibility',
3420 vmathematical: 'vMathematical',
3421 'v-mathematical': 'vMathematical',
3422 vocab: 'vocab',
3423 widths: 'widths',
3424 wordspacing: 'wordSpacing',
3425 'word-spacing': 'wordSpacing',
3426 writingmode: 'writingMode',
3427 'writing-mode': 'writingMode',
3428 x1: 'x1',
3429 x2: 'x2',
3430 x: 'x',
3431 xchannelselector: 'xChannelSelector',
3432 xheight: 'xHeight',
3433 'x-height': 'xHeight',
3434 xlinkactuate: 'xlinkActuate',
3435 'xlink:actuate': 'xlinkActuate',
3436 xlinkarcrole: 'xlinkArcrole',
3437 'xlink:arcrole': 'xlinkArcrole',
3438 xlinkhref: 'xlinkHref',
3439 'xlink:href': 'xlinkHref',
3440 xlinkrole: 'xlinkRole',
3441 'xlink:role': 'xlinkRole',
3442 xlinkshow: 'xlinkShow',
3443 'xlink:show': 'xlinkShow',
3444 xlinktitle: 'xlinkTitle',
3445 'xlink:title': 'xlinkTitle',
3446 xlinktype: 'xlinkType',
3447 'xlink:type': 'xlinkType',
3448 xmlbase: 'xmlBase',
3449 'xml:base': 'xmlBase',
3450 xmllang: 'xmlLang',
3451 'xml:lang': 'xmlLang',
3452 xmlns: 'xmlns',
3453 'xml:space': 'xmlSpace',
3454 xmlnsxlink: 'xmlnsXlink',
3455 'xmlns:xlink': 'xmlnsXlink',
3456 xmlspace: 'xmlSpace',
3457 y1: 'y1',
3458 y2: 'y2',
3459 y: 'y',
3460 ychannelselector: 'yChannelSelector',
3461 z: 'z',
3462 zoomandpan: 'zoomAndPan'
3463 };
3464
3465 var ariaProperties = {
3466 'aria-current': 0,
3467 // state
3468 'aria-description': 0,
3469 'aria-details': 0,
3470 'aria-disabled': 0,
3471 // state
3472 'aria-hidden': 0,
3473 // state
3474 'aria-invalid': 0,
3475 // state
3476 'aria-keyshortcuts': 0,
3477 'aria-label': 0,
3478 'aria-roledescription': 0,
3479 // Widget Attributes
3480 'aria-autocomplete': 0,
3481 'aria-checked': 0,
3482 'aria-expanded': 0,
3483 'aria-haspopup': 0,
3484 'aria-level': 0,
3485 'aria-modal': 0,
3486 'aria-multiline': 0,
3487 'aria-multiselectable': 0,
3488 'aria-orientation': 0,
3489 'aria-placeholder': 0,
3490 'aria-pressed': 0,
3491 'aria-readonly': 0,
3492 'aria-required': 0,
3493 'aria-selected': 0,
3494 'aria-sort': 0,
3495 'aria-valuemax': 0,
3496 'aria-valuemin': 0,
3497 'aria-valuenow': 0,
3498 'aria-valuetext': 0,
3499 // Live Region Attributes
3500 'aria-atomic': 0,
3501 'aria-busy': 0,
3502 'aria-live': 0,
3503 'aria-relevant': 0,
3504 // Drag-and-Drop Attributes
3505 'aria-dropeffect': 0,
3506 'aria-grabbed': 0,
3507 // Relationship Attributes
3508 'aria-activedescendant': 0,
3509 'aria-colcount': 0,
3510 'aria-colindex': 0,
3511 'aria-colspan': 0,
3512 'aria-controls': 0,
3513 'aria-describedby': 0,
3514 'aria-errormessage': 0,
3515 'aria-flowto': 0,
3516 'aria-labelledby': 0,
3517 'aria-owns': 0,
3518 'aria-posinset': 0,
3519 'aria-rowcount': 0,
3520 'aria-rowindex': 0,
3521 'aria-rowspan': 0,
3522 'aria-setsize': 0
3523 };
3524
3525 var warnedProperties = {};
3526 var rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3527 var rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3528
3529 function validateProperty(tagName, name) {
3530 {
3531 if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
3532 return true;
3533 }
3534
3535 if (rARIACamel.test(name)) {
3536 var ariaName = 'aria-' + name.slice(4).toLowerCase();
3537 var correctName = ariaProperties.hasOwnProperty(ariaName) ? ariaName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3538 // DOM properties, then it is an invalid aria-* attribute.
3539
3540 if (correctName == null) {
3541 error('Invalid ARIA attribute `%s`. ARIA attributes follow the pattern aria-* and must be lowercase.', name);
3542
3543 warnedProperties[name] = true;
3544 return true;
3545 } // aria-* attributes should be lowercase; suggest the lowercase version.
3546
3547
3548 if (name !== correctName) {
3549 error('Invalid ARIA attribute `%s`. Did you mean `%s`?', name, correctName);
3550
3551 warnedProperties[name] = true;
3552 return true;
3553 }
3554 }
3555
3556 if (rARIA.test(name)) {
3557 var lowerCasedName = name.toLowerCase();
3558 var standardName = ariaProperties.hasOwnProperty(lowerCasedName) ? lowerCasedName : null; // If this is an aria-* attribute, but is not listed in the known DOM
3559 // DOM properties, then it is an invalid aria-* attribute.
3560
3561 if (standardName == null) {
3562 warnedProperties[name] = true;
3563 return false;
3564 } // aria-* attributes should be lowercase; suggest the lowercase version.
3565
3566
3567 if (name !== standardName) {
3568 error('Unknown ARIA attribute `%s`. Did you mean `%s`?', name, standardName);
3569
3570 warnedProperties[name] = true;
3571 return true;
3572 }
3573 }
3574 }
3575
3576 return true;
3577 }
3578
3579 function warnInvalidARIAProps(type, props) {
3580 {
3581 var invalidProps = [];
3582
3583 for (var key in props) {
3584 var isValid = validateProperty(type, key);
3585
3586 if (!isValid) {
3587 invalidProps.push(key);
3588 }
3589 }
3590
3591 var unknownPropString = invalidProps.map(function (prop) {
3592 return '`' + prop + '`';
3593 }).join(', ');
3594
3595 if (invalidProps.length === 1) {
3596 error('Invalid aria prop %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3597 } else if (invalidProps.length > 1) {
3598 error('Invalid aria props %s on <%s> tag. ' + 'For details, see https://reactjs.org/link/invalid-aria-props', unknownPropString, type);
3599 }
3600 }
3601 }
3602
3603 function validateProperties(type, props) {
3604 if (isCustomComponent(type, props)) {
3605 return;
3606 }
3607
3608 warnInvalidARIAProps(type, props);
3609 }
3610
3611 var didWarnValueNull = false;
3612 function validateProperties$1(type, props) {
3613 {
3614 if (type !== 'input' && type !== 'textarea' && type !== 'select') {
3615 return;
3616 }
3617
3618 if (props != null && props.value === null && !didWarnValueNull) {
3619 didWarnValueNull = true;
3620
3621 if (type === 'select' && props.multiple) {
3622 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);
3623 } else {
3624 error('`value` prop on `%s` should not be null. ' + 'Consider using an empty string to clear the component or `undefined` ' + 'for uncontrolled components.', type);
3625 }
3626 }
3627 }
3628 }
3629
3630 var validateProperty$1 = function () {};
3631
3632 {
3633 var warnedProperties$1 = {};
3634 var EVENT_NAME_REGEX = /^on./;
3635 var INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
3636 var rARIA$1 = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
3637 var rARIACamel$1 = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
3638
3639 validateProperty$1 = function (tagName, name, value, eventRegistry) {
3640 if (hasOwnProperty.call(warnedProperties$1, name) && warnedProperties$1[name]) {
3641 return true;
3642 }
3643
3644 var lowerCasedName = name.toLowerCase();
3645
3646 if (lowerCasedName === 'onfocusin' || lowerCasedName === 'onfocusout') {
3647 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.');
3648
3649 warnedProperties$1[name] = true;
3650 return true;
3651 } // We can't rely on the event system being injected on the server.
3652
3653
3654 if (eventRegistry != null) {
3655 var registrationNameDependencies = eventRegistry.registrationNameDependencies,
3656 possibleRegistrationNames = eventRegistry.possibleRegistrationNames;
3657
3658 if (registrationNameDependencies.hasOwnProperty(name)) {
3659 return true;
3660 }
3661
3662 var registrationName = possibleRegistrationNames.hasOwnProperty(lowerCasedName) ? possibleRegistrationNames[lowerCasedName] : null;
3663
3664 if (registrationName != null) {
3665 error('Invalid event handler property `%s`. Did you mean `%s`?', name, registrationName);
3666
3667 warnedProperties$1[name] = true;
3668 return true;
3669 }
3670
3671 if (EVENT_NAME_REGEX.test(name)) {
3672 error('Unknown event handler property `%s`. It will be ignored.', name);
3673
3674 warnedProperties$1[name] = true;
3675 return true;
3676 }
3677 } else if (EVENT_NAME_REGEX.test(name)) {
3678 // If no event plugins have been injected, we are in a server environment.
3679 // So we can't tell if the event name is correct for sure, but we can filter
3680 // out known bad ones like `onclick`. We can't suggest a specific replacement though.
3681 if (INVALID_EVENT_NAME_REGEX.test(name)) {
3682 error('Invalid event handler property `%s`. ' + 'React events use the camelCase naming convention, for example `onClick`.', name);
3683 }
3684
3685 warnedProperties$1[name] = true;
3686 return true;
3687 } // Let the ARIA attribute hook validate ARIA attributes
3688
3689
3690 if (rARIA$1.test(name) || rARIACamel$1.test(name)) {
3691 return true;
3692 }
3693
3694 if (lowerCasedName === 'innerhtml') {
3695 error('Directly setting property `innerHTML` is not permitted. ' + 'For more information, lookup documentation on `dangerouslySetInnerHTML`.');
3696
3697 warnedProperties$1[name] = true;
3698 return true;
3699 }
3700
3701 if (lowerCasedName === 'aria') {
3702 error('The `aria` attribute is reserved for future use in React. ' + 'Pass individual `aria-` attributes instead.');
3703
3704 warnedProperties$1[name] = true;
3705 return true;
3706 }
3707
3708 if (lowerCasedName === 'is' && value !== null && value !== undefined && typeof value !== 'string') {
3709 error('Received a `%s` for a string attribute `is`. If this is expected, cast ' + 'the value to a string.', typeof value);
3710
3711 warnedProperties$1[name] = true;
3712 return true;
3713 }
3714
3715 if (typeof value === 'number' && isNaN(value)) {
3716 error('Received NaN for the `%s` attribute. If this is expected, cast ' + 'the value to a string.', name);
3717
3718 warnedProperties$1[name] = true;
3719 return true;
3720 }
3721
3722 var propertyInfo = getPropertyInfo(name);
3723 var isReserved = propertyInfo !== null && propertyInfo.type === RESERVED; // Known attributes should match the casing specified in the property config.
3724
3725 if (possibleStandardNames.hasOwnProperty(lowerCasedName)) {
3726 var standardName = possibleStandardNames[lowerCasedName];
3727
3728 if (standardName !== name) {
3729 error('Invalid DOM property `%s`. Did you mean `%s`?', name, standardName);
3730
3731 warnedProperties$1[name] = true;
3732 return true;
3733 }
3734 } else if (!isReserved && name !== lowerCasedName) {
3735 // Unknown attributes should have lowercase casing since that's how they
3736 // will be cased anyway with server rendering.
3737 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);
3738
3739 warnedProperties$1[name] = true;
3740 return true;
3741 }
3742
3743 if (typeof value === 'boolean' && shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3744 if (value) {
3745 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);
3746 } else {
3747 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);
3748 }
3749
3750 warnedProperties$1[name] = true;
3751 return true;
3752 } // Now that we've validated casing, do not validate
3753 // data types for reserved props
3754
3755
3756 if (isReserved) {
3757 return true;
3758 } // Warn when a known attribute is a bad type
3759
3760
3761 if (shouldRemoveAttributeWithWarning(name, value, propertyInfo, false)) {
3762 warnedProperties$1[name] = true;
3763 return false;
3764 } // Warn when passing the strings 'false' or 'true' into a boolean prop
3765
3766
3767 if ((value === 'false' || value === 'true') && propertyInfo !== null && propertyInfo.type === BOOLEAN) {
3768 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);
3769
3770 warnedProperties$1[name] = true;
3771 return true;
3772 }
3773
3774 return true;
3775 };
3776 }
3777
3778 var warnUnknownProperties = function (type, props, eventRegistry) {
3779 {
3780 var unknownProps = [];
3781
3782 for (var key in props) {
3783 var isValid = validateProperty$1(type, key, props[key], eventRegistry);
3784
3785 if (!isValid) {
3786 unknownProps.push(key);
3787 }
3788 }
3789
3790 var unknownPropString = unknownProps.map(function (prop) {
3791 return '`' + prop + '`';
3792 }).join(', ');
3793
3794 if (unknownProps.length === 1) {
3795 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);
3796 } else if (unknownProps.length > 1) {
3797 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);
3798 }
3799 }
3800 };
3801
3802 function validateProperties$2(type, props, eventRegistry) {
3803 if (isCustomComponent(type, props)) {
3804 return;
3805 }
3806
3807 warnUnknownProperties(type, props, eventRegistry);
3808 }
3809
3810 var IS_EVENT_HANDLE_NON_MANAGED_NODE = 1;
3811 var IS_NON_DELEGATED = 1 << 1;
3812 var IS_CAPTURE_PHASE = 1 << 2;
3813 // set to LEGACY_FB_SUPPORT. LEGACY_FB_SUPPORT only gets set when
3814 // we call willDeferLaterForLegacyFBSupport, thus not bailing out
3815 // will result in endless cycles like an infinite loop.
3816 // We also don't want to defer during event replaying.
3817
3818 var SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS = IS_EVENT_HANDLE_NON_MANAGED_NODE | IS_NON_DELEGATED | IS_CAPTURE_PHASE;
3819
3820 // This exists to avoid circular dependency between ReactDOMEventReplaying
3821 // and DOMPluginEventSystem.
3822 var currentReplayingEvent = null;
3823 function setReplayingEvent(event) {
3824 {
3825 if (currentReplayingEvent !== null) {
3826 error('Expected currently replaying event to be null. This error ' + 'is likely caused by a bug in React. Please file an issue.');
3827 }
3828 }
3829
3830 currentReplayingEvent = event;
3831 }
3832 function resetReplayingEvent() {
3833 {
3834 if (currentReplayingEvent === null) {
3835 error('Expected currently replaying event to not be null. This error ' + 'is likely caused by a bug in React. Please file an issue.');
3836 }
3837 }
3838
3839 currentReplayingEvent = null;
3840 }
3841 function isReplayingEvent(event) {
3842 return event === currentReplayingEvent;
3843 }
3844
3845 /**
3846 * Gets the target node from a native browser event by accounting for
3847 * inconsistencies in browser DOM APIs.
3848 *
3849 * @param {object} nativeEvent Native browser event.
3850 * @return {DOMEventTarget} Target node.
3851 */
3852
3853 function getEventTarget(nativeEvent) {
3854 // Fallback to nativeEvent.srcElement for IE9
3855 // https://github.com/facebook/react/issues/12506
3856 var target = nativeEvent.target || nativeEvent.srcElement || window; // Normalize SVG <use> element events #4963
3857
3858 if (target.correspondingUseElement) {
3859 target = target.correspondingUseElement;
3860 } // Safari may fire events on text nodes (Node.TEXT_NODE is 3).
3861 // @see http://www.quirksmode.org/js/events_properties.html
3862
3863
3864 return target.nodeType === TEXT_NODE ? target.parentNode : target;
3865 }
3866
3867 var restoreImpl = null;
3868 var restoreTarget = null;
3869 var restoreQueue = null;
3870
3871 function restoreStateOfTarget(target) {
3872 // We perform this translation at the end of the event loop so that we
3873 // always receive the correct fiber here
3874 var internalInstance = getInstanceFromNode(target);
3875
3876 if (!internalInstance) {
3877 // Unmounted
3878 return;
3879 }
3880
3881 if (typeof restoreImpl !== 'function') {
3882 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.');
3883 }
3884
3885 var stateNode = internalInstance.stateNode; // Guard against Fiber being unmounted.
3886
3887 if (stateNode) {
3888 var _props = getFiberCurrentPropsFromNode(stateNode);
3889
3890 restoreImpl(internalInstance.stateNode, internalInstance.type, _props);
3891 }
3892 }
3893
3894 function setRestoreImplementation(impl) {
3895 restoreImpl = impl;
3896 }
3897 function enqueueStateRestore(target) {
3898 if (restoreTarget) {
3899 if (restoreQueue) {
3900 restoreQueue.push(target);
3901 } else {
3902 restoreQueue = [target];
3903 }
3904 } else {
3905 restoreTarget = target;
3906 }
3907 }
3908 function needsStateRestore() {
3909 return restoreTarget !== null || restoreQueue !== null;
3910 }
3911 function restoreStateIfNeeded() {
3912 if (!restoreTarget) {
3913 return;
3914 }
3915
3916 var target = restoreTarget;
3917 var queuedTargets = restoreQueue;
3918 restoreTarget = null;
3919 restoreQueue = null;
3920 restoreStateOfTarget(target);
3921
3922 if (queuedTargets) {
3923 for (var i = 0; i < queuedTargets.length; i++) {
3924 restoreStateOfTarget(queuedTargets[i]);
3925 }
3926 }
3927 }
3928
3929 // the renderer. Such as when we're dispatching events or if third party
3930 // libraries need to call batchedUpdates. Eventually, this API will go away when
3931 // everything is batched by default. We'll then have a similar API to opt-out of
3932 // scheduled work and instead do synchronous work.
3933 // Defaults
3934
3935 var batchedUpdatesImpl = function (fn, bookkeeping) {
3936 return fn(bookkeeping);
3937 };
3938
3939 var flushSyncImpl = function () {};
3940
3941 var isInsideEventHandler = false;
3942
3943 function finishEventHandler() {
3944 // Here we wait until all updates have propagated, which is important
3945 // when using controlled components within layers:
3946 // https://github.com/facebook/react/issues/1698
3947 // Then we restore state of any controlled component.
3948 var controlledComponentsHavePendingUpdates = needsStateRestore();
3949
3950 if (controlledComponentsHavePendingUpdates) {
3951 // If a controlled event was fired, we may need to restore the state of
3952 // the DOM node back to the controlled value. This is necessary when React
3953 // bails out of the update without touching the DOM.
3954 // TODO: Restore state in the microtask, after the discrete updates flush,
3955 // instead of early flushing them here.
3956 flushSyncImpl();
3957 restoreStateIfNeeded();
3958 }
3959 }
3960
3961 function batchedUpdates(fn, a, b) {
3962 if (isInsideEventHandler) {
3963 // If we are currently inside another batch, we need to wait until it
3964 // fully completes before restoring state.
3965 return fn(a, b);
3966 }
3967
3968 isInsideEventHandler = true;
3969
3970 try {
3971 return batchedUpdatesImpl(fn, a, b);
3972 } finally {
3973 isInsideEventHandler = false;
3974 finishEventHandler();
3975 }
3976 } // TODO: Replace with flushSync
3977 function setBatchingImplementation(_batchedUpdatesImpl, _discreteUpdatesImpl, _flushSyncImpl) {
3978 batchedUpdatesImpl = _batchedUpdatesImpl;
3979 flushSyncImpl = _flushSyncImpl;
3980 }
3981
3982 function isInteractive(tag) {
3983 return tag === 'button' || tag === 'input' || tag === 'select' || tag === 'textarea';
3984 }
3985
3986 function shouldPreventMouseEvent(name, type, props) {
3987 switch (name) {
3988 case 'onClick':
3989 case 'onClickCapture':
3990 case 'onDoubleClick':
3991 case 'onDoubleClickCapture':
3992 case 'onMouseDown':
3993 case 'onMouseDownCapture':
3994 case 'onMouseMove':
3995 case 'onMouseMoveCapture':
3996 case 'onMouseUp':
3997 case 'onMouseUpCapture':
3998 case 'onMouseEnter':
3999 return !!(props.disabled && isInteractive(type));
4000
4001 default:
4002 return false;
4003 }
4004 }
4005 /**
4006 * @param {object} inst The instance, which is the source of events.
4007 * @param {string} registrationName Name of listener (e.g. `onClick`).
4008 * @return {?function} The stored callback.
4009 */
4010
4011
4012 function getListener(inst, registrationName) {
4013 var stateNode = inst.stateNode;
4014
4015 if (stateNode === null) {
4016 // Work in progress (ex: onload events in incremental mode).
4017 return null;
4018 }
4019
4020 var props = getFiberCurrentPropsFromNode(stateNode);
4021
4022 if (props === null) {
4023 // Work in progress.
4024 return null;
4025 }
4026
4027 var listener = props[registrationName];
4028
4029 if (shouldPreventMouseEvent(registrationName, inst.type, props)) {
4030 return null;
4031 }
4032
4033 if (listener && typeof listener !== 'function') {
4034 throw new Error("Expected `" + registrationName + "` listener to be a function, instead got a value of `" + typeof listener + "` type.");
4035 }
4036
4037 return listener;
4038 }
4039
4040 var passiveBrowserEventsSupported = false; // Check if browser support events with passive listeners
4041 // https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#Safely_detecting_option_support
4042
4043 if (canUseDOM) {
4044 try {
4045 var options = {}; // $FlowFixMe: Ignore Flow complaining about needing a value
4046
4047 Object.defineProperty(options, 'passive', {
4048 get: function () {
4049 passiveBrowserEventsSupported = true;
4050 }
4051 });
4052 window.addEventListener('test', options, options);
4053 window.removeEventListener('test', options, options);
4054 } catch (e) {
4055 passiveBrowserEventsSupported = false;
4056 }
4057 }
4058
4059 function invokeGuardedCallbackProd(name, func, context, a, b, c, d, e, f) {
4060 var funcArgs = Array.prototype.slice.call(arguments, 3);
4061
4062 try {
4063 func.apply(context, funcArgs);
4064 } catch (error) {
4065 this.onError(error);
4066 }
4067 }
4068
4069 var invokeGuardedCallbackImpl = invokeGuardedCallbackProd;
4070
4071 {
4072 // In DEV mode, we swap out invokeGuardedCallback for a special version
4073 // that plays more nicely with the browser's DevTools. The idea is to preserve
4074 // "Pause on exceptions" behavior. Because React wraps all user-provided
4075 // functions in invokeGuardedCallback, and the production version of
4076 // invokeGuardedCallback uses a try-catch, all user exceptions are treated
4077 // like caught exceptions, and the DevTools won't pause unless the developer
4078 // takes the extra step of enabling pause on caught exceptions. This is
4079 // unintuitive, though, because even though React has caught the error, from
4080 // the developer's perspective, the error is uncaught.
4081 //
4082 // To preserve the expected "Pause on exceptions" behavior, we don't use a
4083 // try-catch in DEV. Instead, we synchronously dispatch a fake event to a fake
4084 // DOM node, and call the user-provided callback from inside an event handler
4085 // for that fake event. If the callback throws, the error is "captured" using
4086 // a global event handler. But because the error happens in a different
4087 // event loop context, it does not interrupt the normal program flow.
4088 // Effectively, this gives us try-catch behavior without actually using
4089 // try-catch. Neat!
4090 // Check that the browser supports the APIs we need to implement our special
4091 // DEV version of invokeGuardedCallback
4092 if (typeof window !== 'undefined' && typeof window.dispatchEvent === 'function' && typeof document !== 'undefined' && typeof document.createEvent === 'function') {
4093 var fakeNode = document.createElement('react');
4094
4095 invokeGuardedCallbackImpl = function invokeGuardedCallbackDev(name, func, context, a, b, c, d, e, f) {
4096 // If document doesn't exist we know for sure we will crash in this method
4097 // when we call document.createEvent(). However this can cause confusing
4098 // errors: https://github.com/facebook/create-react-app/issues/3482
4099 // So we preemptively throw with a better message instead.
4100 if (typeof document === 'undefined' || document === null) {
4101 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.');
4102 }
4103
4104 var evt = document.createEvent('Event');
4105 var didCall = false; // Keeps track of whether the user-provided callback threw an error. We
4106 // set this to true at the beginning, then set it to false right after
4107 // calling the function. If the function errors, `didError` will never be
4108 // set to false. This strategy works even if the browser is flaky and
4109 // fails to call our global error handler, because it doesn't rely on
4110 // the error event at all.
4111
4112 var didError = true; // Keeps track of the value of window.event so that we can reset it
4113 // during the callback to let user code access window.event in the
4114 // browsers that support it.
4115
4116 var windowEvent = window.event; // Keeps track of the descriptor of window.event to restore it after event
4117 // dispatching: https://github.com/facebook/react/issues/13688
4118
4119 var windowEventDescriptor = Object.getOwnPropertyDescriptor(window, 'event');
4120
4121 function restoreAfterDispatch() {
4122 // We immediately remove the callback from event listeners so that
4123 // nested `invokeGuardedCallback` calls do not clash. Otherwise, a
4124 // nested call would trigger the fake event handlers of any call higher
4125 // in the stack.
4126 fakeNode.removeEventListener(evtType, callCallback, false); // We check for window.hasOwnProperty('event') to prevent the
4127 // window.event assignment in both IE <= 10 as they throw an error
4128 // "Member not found" in strict mode, and in Firefox which does not
4129 // support window.event.
4130
4131 if (typeof window.event !== 'undefined' && window.hasOwnProperty('event')) {
4132 window.event = windowEvent;
4133 }
4134 } // Create an event handler for our fake event. We will synchronously
4135 // dispatch our fake event using `dispatchEvent`. Inside the handler, we
4136 // call the user-provided callback.
4137
4138
4139 var funcArgs = Array.prototype.slice.call(arguments, 3);
4140
4141 function callCallback() {
4142 didCall = true;
4143 restoreAfterDispatch();
4144 func.apply(context, funcArgs);
4145 didError = false;
4146 } // Create a global error event handler. We use this to capture the value
4147 // that was thrown. It's possible that this error handler will fire more
4148 // than once; for example, if non-React code also calls `dispatchEvent`
4149 // and a handler for that event throws. We should be resilient to most of
4150 // those cases. Even if our error event handler fires more than once, the
4151 // last error event is always used. If the callback actually does error,
4152 // we know that the last error event is the correct one, because it's not
4153 // possible for anything else to have happened in between our callback
4154 // erroring and the code that follows the `dispatchEvent` call below. If
4155 // the callback doesn't error, but the error event was fired, we know to
4156 // ignore it because `didError` will be false, as described above.
4157
4158
4159 var error; // Use this to track whether the error event is ever called.
4160
4161 var didSetError = false;
4162 var isCrossOriginError = false;
4163
4164 function handleWindowError(event) {
4165 error = event.error;
4166 didSetError = true;
4167
4168 if (error === null && event.colno === 0 && event.lineno === 0) {
4169 isCrossOriginError = true;
4170 }
4171
4172 if (event.defaultPrevented) {
4173 // Some other error handler has prevented default.
4174 // Browsers silence the error report if this happens.
4175 // We'll remember this to later decide whether to log it or not.
4176 if (error != null && typeof error === 'object') {
4177 try {
4178 error._suppressLogging = true;
4179 } catch (inner) {// Ignore.
4180 }
4181 }
4182 }
4183 } // Create a fake event type.
4184
4185
4186 var evtType = "react-" + (name ? name : 'invokeguardedcallback'); // Attach our event handlers
4187
4188 window.addEventListener('error', handleWindowError);
4189 fakeNode.addEventListener(evtType, callCallback, false); // Synchronously dispatch our fake event. If the user-provided function
4190 // errors, it will trigger our global error handler.
4191
4192 evt.initEvent(evtType, false, false);
4193 fakeNode.dispatchEvent(evt);
4194
4195 if (windowEventDescriptor) {
4196 Object.defineProperty(window, 'event', windowEventDescriptor);
4197 }
4198
4199 if (didCall && didError) {
4200 if (!didSetError) {
4201 // The callback errored, but the error event never fired.
4202 // eslint-disable-next-line react-internal/prod-error-codes
4203 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.');
4204 } else if (isCrossOriginError) {
4205 // eslint-disable-next-line react-internal/prod-error-codes
4206 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.');
4207 }
4208
4209 this.onError(error);
4210 } // Remove our event listeners
4211
4212
4213 window.removeEventListener('error', handleWindowError);
4214
4215 if (!didCall) {
4216 // Something went really wrong, and our event was not dispatched.
4217 // https://github.com/facebook/react/issues/16734
4218 // https://github.com/facebook/react/issues/16585
4219 // Fall back to the production implementation.
4220 restoreAfterDispatch();
4221 return invokeGuardedCallbackProd.apply(this, arguments);
4222 }
4223 };
4224 }
4225 }
4226
4227 var invokeGuardedCallbackImpl$1 = invokeGuardedCallbackImpl;
4228
4229 var hasError = false;
4230 var caughtError = null; // Used by event system to capture/rethrow the first error.
4231
4232 var hasRethrowError = false;
4233 var rethrowError = null;
4234 var reporter = {
4235 onError: function (error) {
4236 hasError = true;
4237 caughtError = error;
4238 }
4239 };
4240 /**
4241 * Call a function while guarding against errors that happens within it.
4242 * Returns an error if it throws, otherwise null.
4243 *
4244 * In production, this is implemented using a try-catch. The reason we don't
4245 * use a try-catch directly is so that we can swap out a different
4246 * implementation in DEV mode.
4247 *
4248 * @param {String} name of the guard to use for logging or debugging
4249 * @param {Function} func The function to invoke
4250 * @param {*} context The context to use when calling the function
4251 * @param {...*} args Arguments for function
4252 */
4253
4254 function invokeGuardedCallback(name, func, context, a, b, c, d, e, f) {
4255 hasError = false;
4256 caughtError = null;
4257 invokeGuardedCallbackImpl$1.apply(reporter, arguments);
4258 }
4259 /**
4260 * Same as invokeGuardedCallback, but instead of returning an error, it stores
4261 * it in a global so it can be rethrown by `rethrowCaughtError` later.
4262 * TODO: See if caughtError and rethrowError can be unified.
4263 *
4264 * @param {String} name of the guard to use for logging or debugging
4265 * @param {Function} func The function to invoke
4266 * @param {*} context The context to use when calling the function
4267 * @param {...*} args Arguments for function
4268 */
4269
4270 function invokeGuardedCallbackAndCatchFirstError(name, func, context, a, b, c, d, e, f) {
4271 invokeGuardedCallback.apply(this, arguments);
4272
4273 if (hasError) {
4274 var error = clearCaughtError();
4275
4276 if (!hasRethrowError) {
4277 hasRethrowError = true;
4278 rethrowError = error;
4279 }
4280 }
4281 }
4282 /**
4283 * During execution of guarded functions we will capture the first error which
4284 * we will rethrow to be handled by the top level error handler.
4285 */
4286
4287 function rethrowCaughtError() {
4288 if (hasRethrowError) {
4289 var error = rethrowError;
4290 hasRethrowError = false;
4291 rethrowError = null;
4292 throw error;
4293 }
4294 }
4295 function hasCaughtError() {
4296 return hasError;
4297 }
4298 function clearCaughtError() {
4299 if (hasError) {
4300 var error = caughtError;
4301 hasError = false;
4302 caughtError = null;
4303 return error;
4304 } else {
4305 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.');
4306 }
4307 }
4308
4309 var ReactInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
4310 var _ReactInternals$Sched = ReactInternals.Scheduler,
4311 unstable_cancelCallback = _ReactInternals$Sched.unstable_cancelCallback,
4312 unstable_now = _ReactInternals$Sched.unstable_now,
4313 unstable_scheduleCallback = _ReactInternals$Sched.unstable_scheduleCallback,
4314 unstable_shouldYield = _ReactInternals$Sched.unstable_shouldYield,
4315 unstable_requestPaint = _ReactInternals$Sched.unstable_requestPaint,
4316 unstable_getFirstCallbackNode = _ReactInternals$Sched.unstable_getFirstCallbackNode,
4317 unstable_runWithPriority = _ReactInternals$Sched.unstable_runWithPriority,
4318 unstable_next = _ReactInternals$Sched.unstable_next,
4319 unstable_continueExecution = _ReactInternals$Sched.unstable_continueExecution,
4320 unstable_pauseExecution = _ReactInternals$Sched.unstable_pauseExecution,
4321 unstable_getCurrentPriorityLevel = _ReactInternals$Sched.unstable_getCurrentPriorityLevel,
4322 unstable_ImmediatePriority = _ReactInternals$Sched.unstable_ImmediatePriority,
4323 unstable_UserBlockingPriority = _ReactInternals$Sched.unstable_UserBlockingPriority,
4324 unstable_NormalPriority = _ReactInternals$Sched.unstable_NormalPriority,
4325 unstable_LowPriority = _ReactInternals$Sched.unstable_LowPriority,
4326 unstable_IdlePriority = _ReactInternals$Sched.unstable_IdlePriority,
4327 unstable_forceFrameRate = _ReactInternals$Sched.unstable_forceFrameRate,
4328 unstable_flushAllWithoutAsserting = _ReactInternals$Sched.unstable_flushAllWithoutAsserting,
4329 unstable_yieldValue = _ReactInternals$Sched.unstable_yieldValue,
4330 unstable_setDisableYieldValue = _ReactInternals$Sched.unstable_setDisableYieldValue;
4331
4332 /**
4333 * `ReactInstanceMap` maintains a mapping from a public facing stateful
4334 * instance (key) and the internal representation (value). This allows public
4335 * methods to accept the user facing instance as an argument and map them back
4336 * to internal methods.
4337 *
4338 * Note that this module is currently shared and assumed to be stateless.
4339 * If this becomes an actual Map, that will break.
4340 */
4341 function get(key) {
4342 return key._reactInternals;
4343 }
4344 function has(key) {
4345 return key._reactInternals !== undefined;
4346 }
4347 function set(key, value) {
4348 key._reactInternals = value;
4349 }
4350
4351 // Don't change these two values. They're used by React Dev Tools.
4352 var NoFlags =
4353 /* */
4354 0;
4355 var PerformedWork =
4356 /* */
4357 1; // You can change the rest (and add more).
4358
4359 var Placement =
4360 /* */
4361 2;
4362 var Update =
4363 /* */
4364 4;
4365 var PlacementAndUpdate =
4366 /* */
4367 Placement | Update;
4368 var ChildDeletion =
4369 /* */
4370 16;
4371 var ContentReset =
4372 /* */
4373 32;
4374 var Callback =
4375 /* */
4376 64;
4377 var DidCapture =
4378 /* */
4379 128;
4380 var ForceClientRender =
4381 /* */
4382 256;
4383 var Ref =
4384 /* */
4385 512;
4386 var Snapshot =
4387 /* */
4388 1024;
4389 var Passive =
4390 /* */
4391 2048;
4392 var Hydrating =
4393 /* */
4394 4096;
4395 var HydratingAndUpdate =
4396 /* */
4397 Hydrating | Update;
4398 var Visibility =
4399 /* */
4400 8192;
4401 var StoreConsistency =
4402 /* */
4403 16384;
4404 var LifecycleEffectMask = Passive | Update | Callback | Ref | Snapshot | StoreConsistency; // Union of all commit flags (flags with the lifetime of a particular commit)
4405
4406 var HostEffectMask =
4407 /* */
4408 32767; // These are not really side effects, but we still reuse this field.
4409
4410 var Incomplete =
4411 /* */
4412 32768;
4413 var ShouldCapture =
4414 /* */
4415 65536;
4416 var ForceUpdateForLegacySuspense =
4417 /* */
4418 131072;
4419 var Forked =
4420 /* */
4421 1048576; // Static tags describe aspects of a fiber that are not specific to a render,
4422 // e.g. a fiber uses a passive effect (even if there are no updates on this particular render).
4423 // This enables us to defer more work in the unmount case,
4424 // since we can defer traversing the tree during layout to look for Passive effects,
4425 // and instead rely on the static flag as a signal that there may be cleanup work.
4426
4427 var RefStatic =
4428 /* */
4429 2097152;
4430 var LayoutStatic =
4431 /* */
4432 4194304;
4433 var PassiveStatic =
4434 /* */
4435 8388608; // These flags allow us to traverse to fibers that have effects on mount
4436 // without traversing the entire tree after every commit for
4437 // double invoking
4438
4439 var MountLayoutDev =
4440 /* */
4441 16777216;
4442 var MountPassiveDev =
4443 /* */
4444 33554432; // Groups of flags that are used in the commit phase to skip over trees that
4445 // don't contain effects, by checking subtreeFlags.
4446
4447 var BeforeMutationMask = // TODO: Remove Update flag from before mutation phase by re-landing Visibility
4448 // flag logic (see #20043)
4449 Update | Snapshot | ( 0);
4450 var MutationMask = Placement | Update | ChildDeletion | ContentReset | Ref | Hydrating | Visibility;
4451 var LayoutMask = Update | Callback | Ref | Visibility; // TODO: Split into PassiveMountMask and PassiveUnmountMask
4452
4453 var PassiveMask = Passive | ChildDeletion; // Union of tags that don't get reset on clones.
4454 // This allows certain concepts to persist without recalculating them,
4455 // e.g. whether a subtree contains passive effects or portals.
4456
4457 var StaticMask = LayoutStatic | PassiveStatic | RefStatic;
4458
4459 var ReactCurrentOwner = ReactSharedInternals.ReactCurrentOwner;
4460 function getNearestMountedFiber(fiber) {
4461 var node = fiber;
4462 var nearestMounted = fiber;
4463
4464 if (!fiber.alternate) {
4465 // If there is no alternate, this might be a new tree that isn't inserted
4466 // yet. If it is, then it will have a pending insertion effect on it.
4467 var nextNode = node;
4468
4469 do {
4470 node = nextNode;
4471
4472 if ((node.flags & (Placement | Hydrating)) !== NoFlags) {
4473 // This is an insertion or in-progress hydration. The nearest possible
4474 // mounted fiber is the parent but we need to continue to figure out
4475 // if that one is still mounted.
4476 nearestMounted = node.return;
4477 }
4478
4479 nextNode = node.return;
4480 } while (nextNode);
4481 } else {
4482 while (node.return) {
4483 node = node.return;
4484 }
4485 }
4486
4487 if (node.tag === HostRoot) {
4488 // TODO: Check if this was a nested HostRoot when used with
4489 // renderContainerIntoSubtree.
4490 return nearestMounted;
4491 } // If we didn't hit the root, that means that we're in an disconnected tree
4492 // that has been unmounted.
4493
4494
4495 return null;
4496 }
4497 function getSuspenseInstanceFromFiber(fiber) {
4498 if (fiber.tag === SuspenseComponent) {
4499 var suspenseState = fiber.memoizedState;
4500
4501 if (suspenseState === null) {
4502 var current = fiber.alternate;
4503
4504 if (current !== null) {
4505 suspenseState = current.memoizedState;
4506 }
4507 }
4508
4509 if (suspenseState !== null) {
4510 return suspenseState.dehydrated;
4511 }
4512 }
4513
4514 return null;
4515 }
4516 function getContainerFromFiber(fiber) {
4517 return fiber.tag === HostRoot ? fiber.stateNode.containerInfo : null;
4518 }
4519 function isFiberMounted(fiber) {
4520 return getNearestMountedFiber(fiber) === fiber;
4521 }
4522 function isMounted(component) {
4523 {
4524 var owner = ReactCurrentOwner.current;
4525
4526 if (owner !== null && owner.tag === ClassComponent) {
4527 var ownerFiber = owner;
4528 var instance = ownerFiber.stateNode;
4529
4530 if (!instance._warnedAboutRefsInRender) {
4531 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');
4532 }
4533
4534 instance._warnedAboutRefsInRender = true;
4535 }
4536 }
4537
4538 var fiber = get(component);
4539
4540 if (!fiber) {
4541 return false;
4542 }
4543
4544 return getNearestMountedFiber(fiber) === fiber;
4545 }
4546
4547 function assertIsMounted(fiber) {
4548 if (getNearestMountedFiber(fiber) !== fiber) {
4549 throw new Error('Unable to find node on an unmounted component.');
4550 }
4551 }
4552
4553 function findCurrentFiberUsingSlowPath(fiber) {
4554 var alternate = fiber.alternate;
4555
4556 if (!alternate) {
4557 // If there is no alternate, then we only need to check if it is mounted.
4558 var nearestMounted = getNearestMountedFiber(fiber);
4559
4560 if (nearestMounted === null) {
4561 throw new Error('Unable to find node on an unmounted component.');
4562 }
4563
4564 if (nearestMounted !== fiber) {
4565 return null;
4566 }
4567
4568 return fiber;
4569 } // If we have two possible branches, we'll walk backwards up to the root
4570 // to see what path the root points to. On the way we may hit one of the
4571 // special cases and we'll deal with them.
4572
4573
4574 var a = fiber;
4575 var b = alternate;
4576
4577 while (true) {
4578 var parentA = a.return;
4579
4580 if (parentA === null) {
4581 // We're at the root.
4582 break;
4583 }
4584
4585 var parentB = parentA.alternate;
4586
4587 if (parentB === null) {
4588 // There is no alternate. This is an unusual case. Currently, it only
4589 // happens when a Suspense component is hidden. An extra fragment fiber
4590 // is inserted in between the Suspense fiber and its children. Skip
4591 // over this extra fragment fiber and proceed to the next parent.
4592 var nextParent = parentA.return;
4593
4594 if (nextParent !== null) {
4595 a = b = nextParent;
4596 continue;
4597 } // If there's no parent, we're at the root.
4598
4599
4600 break;
4601 } // If both copies of the parent fiber point to the same child, we can
4602 // assume that the child is current. This happens when we bailout on low
4603 // priority: the bailed out fiber's child reuses the current child.
4604
4605
4606 if (parentA.child === parentB.child) {
4607 var child = parentA.child;
4608
4609 while (child) {
4610 if (child === a) {
4611 // We've determined that A is the current branch.
4612 assertIsMounted(parentA);
4613 return fiber;
4614 }
4615
4616 if (child === b) {
4617 // We've determined that B is the current branch.
4618 assertIsMounted(parentA);
4619 return alternate;
4620 }
4621
4622 child = child.sibling;
4623 } // We should never have an alternate for any mounting node. So the only
4624 // way this could possibly happen is if this was unmounted, if at all.
4625
4626
4627 throw new Error('Unable to find node on an unmounted component.');
4628 }
4629
4630 if (a.return !== b.return) {
4631 // The return pointer of A and the return pointer of B point to different
4632 // fibers. We assume that return pointers never criss-cross, so A must
4633 // belong to the child set of A.return, and B must belong to the child
4634 // set of B.return.
4635 a = parentA;
4636 b = parentB;
4637 } else {
4638 // The return pointers point to the same fiber. We'll have to use the
4639 // default, slow path: scan the child sets of each parent alternate to see
4640 // which child belongs to which set.
4641 //
4642 // Search parent A's child set
4643 var didFindChild = false;
4644 var _child = parentA.child;
4645
4646 while (_child) {
4647 if (_child === a) {
4648 didFindChild = true;
4649 a = parentA;
4650 b = parentB;
4651 break;
4652 }
4653
4654 if (_child === b) {
4655 didFindChild = true;
4656 b = parentA;
4657 a = parentB;
4658 break;
4659 }
4660
4661 _child = _child.sibling;
4662 }
4663
4664 if (!didFindChild) {
4665 // Search parent B's child set
4666 _child = parentB.child;
4667
4668 while (_child) {
4669 if (_child === a) {
4670 didFindChild = true;
4671 a = parentB;
4672 b = parentA;
4673 break;
4674 }
4675
4676 if (_child === b) {
4677 didFindChild = true;
4678 b = parentB;
4679 a = parentA;
4680 break;
4681 }
4682
4683 _child = _child.sibling;
4684 }
4685
4686 if (!didFindChild) {
4687 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.');
4688 }
4689 }
4690 }
4691
4692 if (a.alternate !== b) {
4693 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.');
4694 }
4695 } // If the root is not a host container, we're in a disconnected tree. I.e.
4696 // unmounted.
4697
4698
4699 if (a.tag !== HostRoot) {
4700 throw new Error('Unable to find node on an unmounted component.');
4701 }
4702
4703 if (a.stateNode.current === a) {
4704 // We've determined that A is the current branch.
4705 return fiber;
4706 } // Otherwise B has to be current branch.
4707
4708
4709 return alternate;
4710 }
4711 function findCurrentHostFiber(parent) {
4712 var currentParent = findCurrentFiberUsingSlowPath(parent);
4713 return currentParent !== null ? findCurrentHostFiberImpl(currentParent) : null;
4714 }
4715
4716 function findCurrentHostFiberImpl(node) {
4717 // Next we'll drill down this component to find the first HostComponent/Text.
4718 if (node.tag === HostComponent || node.tag === HostText) {
4719 return node;
4720 }
4721
4722 var child = node.child;
4723
4724 while (child !== null) {
4725 var match = findCurrentHostFiberImpl(child);
4726
4727 if (match !== null) {
4728 return match;
4729 }
4730
4731 child = child.sibling;
4732 }
4733
4734 return null;
4735 }
4736
4737 function findCurrentHostFiberWithNoPortals(parent) {
4738 var currentParent = findCurrentFiberUsingSlowPath(parent);
4739 return currentParent !== null ? findCurrentHostFiberWithNoPortalsImpl(currentParent) : null;
4740 }
4741
4742 function findCurrentHostFiberWithNoPortalsImpl(node) {
4743 // Next we'll drill down this component to find the first HostComponent/Text.
4744 if (node.tag === HostComponent || node.tag === HostText) {
4745 return node;
4746 }
4747
4748 var child = node.child;
4749
4750 while (child !== null) {
4751 if (child.tag !== HostPortal) {
4752 var match = findCurrentHostFiberWithNoPortalsImpl(child);
4753
4754 if (match !== null) {
4755 return match;
4756 }
4757 }
4758
4759 child = child.sibling;
4760 }
4761
4762 return null;
4763 }
4764
4765 // This module only exists as an ESM wrapper around the external CommonJS
4766 var scheduleCallback = unstable_scheduleCallback;
4767 var cancelCallback = unstable_cancelCallback;
4768 var shouldYield = unstable_shouldYield;
4769 var requestPaint = unstable_requestPaint;
4770 var now = unstable_now;
4771 var getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
4772 var ImmediatePriority = unstable_ImmediatePriority;
4773 var UserBlockingPriority = unstable_UserBlockingPriority;
4774 var NormalPriority = unstable_NormalPriority;
4775 var LowPriority = unstable_LowPriority;
4776 var IdlePriority = unstable_IdlePriority;
4777 // this doesn't actually exist on the scheduler, but it *does*
4778 // on scheduler/unstable_mock, which we'll need for internal testing
4779 var unstable_yieldValue$1 = unstable_yieldValue;
4780 var unstable_setDisableYieldValue$1 = unstable_setDisableYieldValue;
4781
4782 var rendererID = null;
4783 var injectedHook = null;
4784 var injectedProfilingHooks = null;
4785 var hasLoggedError = false;
4786 var isDevToolsPresent = typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== 'undefined';
4787 function injectInternals(internals) {
4788 if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ === 'undefined') {
4789 // No DevTools
4790 return false;
4791 }
4792
4793 var hook = __REACT_DEVTOOLS_GLOBAL_HOOK__;
4794
4795 if (hook.isDisabled) {
4796 // This isn't a real property on the hook, but it can be set to opt out
4797 // of DevTools integration and associated warnings and logs.
4798 // https://github.com/facebook/react/issues/3877
4799 return true;
4800 }
4801
4802 if (!hook.supportsFiber) {
4803 {
4804 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');
4805 } // DevTools exists, even though it doesn't support Fiber.
4806
4807
4808 return true;
4809 }
4810
4811 try {
4812 if (enableSchedulingProfiler) {
4813 // Conditionally inject these hooks only if Timeline profiler is supported by this build.
4814 // This gives DevTools a way to feature detect that isn't tied to version number
4815 // (since profiling and timeline are controlled by different feature flags).
4816 internals = assign({}, internals, {
4817 getLaneLabelMap: getLaneLabelMap,
4818 injectProfilingHooks: injectProfilingHooks
4819 });
4820 }
4821
4822 rendererID = hook.inject(internals); // We have successfully injected, so now it is safe to set up hooks.
4823
4824 injectedHook = hook;
4825 } catch (err) {
4826 // Catch all errors because it is unsafe to throw during initialization.
4827 {
4828 error('React instrumentation encountered an error: %s.', err);
4829 }
4830 }
4831
4832 if (hook.checkDCE) {
4833 // This is the real DevTools.
4834 return true;
4835 } else {
4836 // This is likely a hook installed by Fast Refresh runtime.
4837 return false;
4838 }
4839 }
4840 function onScheduleRoot(root, children) {
4841 {
4842 if (injectedHook && typeof injectedHook.onScheduleFiberRoot === 'function') {
4843 try {
4844 injectedHook.onScheduleFiberRoot(rendererID, root, children);
4845 } catch (err) {
4846 if ( !hasLoggedError) {
4847 hasLoggedError = true;
4848
4849 error('React instrumentation encountered an error: %s', err);
4850 }
4851 }
4852 }
4853 }
4854 }
4855 function onCommitRoot(root, eventPriority) {
4856 if (injectedHook && typeof injectedHook.onCommitFiberRoot === 'function') {
4857 try {
4858 var didError = (root.current.flags & DidCapture) === DidCapture;
4859
4860 if (enableProfilerTimer) {
4861 var schedulerPriority;
4862
4863 switch (eventPriority) {
4864 case DiscreteEventPriority:
4865 schedulerPriority = ImmediatePriority;
4866 break;
4867
4868 case ContinuousEventPriority:
4869 schedulerPriority = UserBlockingPriority;
4870 break;
4871
4872 case DefaultEventPriority:
4873 schedulerPriority = NormalPriority;
4874 break;
4875
4876 case IdleEventPriority:
4877 schedulerPriority = IdlePriority;
4878 break;
4879
4880 default:
4881 schedulerPriority = NormalPriority;
4882 break;
4883 }
4884
4885 injectedHook.onCommitFiberRoot(rendererID, root, schedulerPriority, didError);
4886 } else {
4887 injectedHook.onCommitFiberRoot(rendererID, root, undefined, didError);
4888 }
4889 } catch (err) {
4890 {
4891 if (!hasLoggedError) {
4892 hasLoggedError = true;
4893
4894 error('React instrumentation encountered an error: %s', err);
4895 }
4896 }
4897 }
4898 }
4899 }
4900 function onPostCommitRoot(root) {
4901 if (injectedHook && typeof injectedHook.onPostCommitFiberRoot === 'function') {
4902 try {
4903 injectedHook.onPostCommitFiberRoot(rendererID, root);
4904 } catch (err) {
4905 {
4906 if (!hasLoggedError) {
4907 hasLoggedError = true;
4908
4909 error('React instrumentation encountered an error: %s', err);
4910 }
4911 }
4912 }
4913 }
4914 }
4915 function onCommitUnmount(fiber) {
4916 if (injectedHook && typeof injectedHook.onCommitFiberUnmount === 'function') {
4917 try {
4918 injectedHook.onCommitFiberUnmount(rendererID, fiber);
4919 } catch (err) {
4920 {
4921 if (!hasLoggedError) {
4922 hasLoggedError = true;
4923
4924 error('React instrumentation encountered an error: %s', err);
4925 }
4926 }
4927 }
4928 }
4929 }
4930 function setIsStrictModeForDevtools(newIsStrictMode) {
4931 {
4932 if (typeof unstable_yieldValue$1 === 'function') {
4933 // We're in a test because Scheduler.unstable_yieldValue only exists
4934 // in SchedulerMock. To reduce the noise in strict mode tests,
4935 // suppress warnings and disable scheduler yielding during the double render
4936 unstable_setDisableYieldValue$1(newIsStrictMode);
4937 setSuppressWarning(newIsStrictMode);
4938 }
4939
4940 if (injectedHook && typeof injectedHook.setStrictMode === 'function') {
4941 try {
4942 injectedHook.setStrictMode(rendererID, newIsStrictMode);
4943 } catch (err) {
4944 {
4945 if (!hasLoggedError) {
4946 hasLoggedError = true;
4947
4948 error('React instrumentation encountered an error: %s', err);
4949 }
4950 }
4951 }
4952 }
4953 }
4954 } // Profiler API hooks
4955
4956 function injectProfilingHooks(profilingHooks) {
4957 injectedProfilingHooks = profilingHooks;
4958 }
4959
4960 function getLaneLabelMap() {
4961 {
4962 var map = new Map();
4963 var lane = 1;
4964
4965 for (var index = 0; index < TotalLanes; index++) {
4966 var label = getLabelForLane(lane);
4967 map.set(lane, label);
4968 lane *= 2;
4969 }
4970
4971 return map;
4972 }
4973 }
4974
4975 function markCommitStarted(lanes) {
4976 {
4977 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStarted === 'function') {
4978 injectedProfilingHooks.markCommitStarted(lanes);
4979 }
4980 }
4981 }
4982 function markCommitStopped() {
4983 {
4984 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markCommitStopped === 'function') {
4985 injectedProfilingHooks.markCommitStopped();
4986 }
4987 }
4988 }
4989 function markComponentRenderStarted(fiber) {
4990 {
4991 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStarted === 'function') {
4992 injectedProfilingHooks.markComponentRenderStarted(fiber);
4993 }
4994 }
4995 }
4996 function markComponentRenderStopped() {
4997 {
4998 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentRenderStopped === 'function') {
4999 injectedProfilingHooks.markComponentRenderStopped();
5000 }
5001 }
5002 }
5003 function markComponentPassiveEffectMountStarted(fiber) {
5004 {
5005 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStarted === 'function') {
5006 injectedProfilingHooks.markComponentPassiveEffectMountStarted(fiber);
5007 }
5008 }
5009 }
5010 function markComponentPassiveEffectMountStopped() {
5011 {
5012 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectMountStopped === 'function') {
5013 injectedProfilingHooks.markComponentPassiveEffectMountStopped();
5014 }
5015 }
5016 }
5017 function markComponentPassiveEffectUnmountStarted(fiber) {
5018 {
5019 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStarted === 'function') {
5020 injectedProfilingHooks.markComponentPassiveEffectUnmountStarted(fiber);
5021 }
5022 }
5023 }
5024 function markComponentPassiveEffectUnmountStopped() {
5025 {
5026 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentPassiveEffectUnmountStopped === 'function') {
5027 injectedProfilingHooks.markComponentPassiveEffectUnmountStopped();
5028 }
5029 }
5030 }
5031 function markComponentLayoutEffectMountStarted(fiber) {
5032 {
5033 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStarted === 'function') {
5034 injectedProfilingHooks.markComponentLayoutEffectMountStarted(fiber);
5035 }
5036 }
5037 }
5038 function markComponentLayoutEffectMountStopped() {
5039 {
5040 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectMountStopped === 'function') {
5041 injectedProfilingHooks.markComponentLayoutEffectMountStopped();
5042 }
5043 }
5044 }
5045 function markComponentLayoutEffectUnmountStarted(fiber) {
5046 {
5047 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStarted === 'function') {
5048 injectedProfilingHooks.markComponentLayoutEffectUnmountStarted(fiber);
5049 }
5050 }
5051 }
5052 function markComponentLayoutEffectUnmountStopped() {
5053 {
5054 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentLayoutEffectUnmountStopped === 'function') {
5055 injectedProfilingHooks.markComponentLayoutEffectUnmountStopped();
5056 }
5057 }
5058 }
5059 function markComponentErrored(fiber, thrownValue, lanes) {
5060 {
5061 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentErrored === 'function') {
5062 injectedProfilingHooks.markComponentErrored(fiber, thrownValue, lanes);
5063 }
5064 }
5065 }
5066 function markComponentSuspended(fiber, wakeable, lanes) {
5067 {
5068 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markComponentSuspended === 'function') {
5069 injectedProfilingHooks.markComponentSuspended(fiber, wakeable, lanes);
5070 }
5071 }
5072 }
5073 function markLayoutEffectsStarted(lanes) {
5074 {
5075 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStarted === 'function') {
5076 injectedProfilingHooks.markLayoutEffectsStarted(lanes);
5077 }
5078 }
5079 }
5080 function markLayoutEffectsStopped() {
5081 {
5082 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markLayoutEffectsStopped === 'function') {
5083 injectedProfilingHooks.markLayoutEffectsStopped();
5084 }
5085 }
5086 }
5087 function markPassiveEffectsStarted(lanes) {
5088 {
5089 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStarted === 'function') {
5090 injectedProfilingHooks.markPassiveEffectsStarted(lanes);
5091 }
5092 }
5093 }
5094 function markPassiveEffectsStopped() {
5095 {
5096 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markPassiveEffectsStopped === 'function') {
5097 injectedProfilingHooks.markPassiveEffectsStopped();
5098 }
5099 }
5100 }
5101 function markRenderStarted(lanes) {
5102 {
5103 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStarted === 'function') {
5104 injectedProfilingHooks.markRenderStarted(lanes);
5105 }
5106 }
5107 }
5108 function markRenderYielded() {
5109 {
5110 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderYielded === 'function') {
5111 injectedProfilingHooks.markRenderYielded();
5112 }
5113 }
5114 }
5115 function markRenderStopped() {
5116 {
5117 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderStopped === 'function') {
5118 injectedProfilingHooks.markRenderStopped();
5119 }
5120 }
5121 }
5122 function markRenderScheduled(lane) {
5123 {
5124 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markRenderScheduled === 'function') {
5125 injectedProfilingHooks.markRenderScheduled(lane);
5126 }
5127 }
5128 }
5129 function markForceUpdateScheduled(fiber, lane) {
5130 {
5131 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markForceUpdateScheduled === 'function') {
5132 injectedProfilingHooks.markForceUpdateScheduled(fiber, lane);
5133 }
5134 }
5135 }
5136 function markStateUpdateScheduled(fiber, lane) {
5137 {
5138 if (injectedProfilingHooks !== null && typeof injectedProfilingHooks.markStateUpdateScheduled === 'function') {
5139 injectedProfilingHooks.markStateUpdateScheduled(fiber, lane);
5140 }
5141 }
5142 }
5143
5144 var NoMode =
5145 /* */
5146 0; // TODO: Remove ConcurrentMode by reading from the root tag instead
5147
5148 var ConcurrentMode =
5149 /* */
5150 1;
5151 var ProfileMode =
5152 /* */
5153 2;
5154 var StrictLegacyMode =
5155 /* */
5156 8;
5157 var StrictEffectsMode =
5158 /* */
5159 16;
5160
5161 // TODO: This is pretty well supported by browsers. Maybe we can drop it.
5162 var clz32 = Math.clz32 ? Math.clz32 : clz32Fallback; // Count leading zeros.
5163 // Based on:
5164 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/clz32
5165
5166 var log = Math.log;
5167 var LN2 = Math.LN2;
5168
5169 function clz32Fallback(x) {
5170 var asUint = x >>> 0;
5171
5172 if (asUint === 0) {
5173 return 32;
5174 }
5175
5176 return 31 - (log(asUint) / LN2 | 0) | 0;
5177 }
5178
5179 // If those values are changed that package should be rebuilt and redeployed.
5180
5181 var TotalLanes = 31;
5182 var NoLanes =
5183 /* */
5184 0;
5185 var NoLane =
5186 /* */
5187 0;
5188 var SyncLane =
5189 /* */
5190 1;
5191 var InputContinuousHydrationLane =
5192 /* */
5193 2;
5194 var InputContinuousLane =
5195 /* */
5196 4;
5197 var DefaultHydrationLane =
5198 /* */
5199 8;
5200 var DefaultLane =
5201 /* */
5202 16;
5203 var TransitionHydrationLane =
5204 /* */
5205 32;
5206 var TransitionLanes =
5207 /* */
5208 4194240;
5209 var TransitionLane1 =
5210 /* */
5211 64;
5212 var TransitionLane2 =
5213 /* */
5214 128;
5215 var TransitionLane3 =
5216 /* */
5217 256;
5218 var TransitionLane4 =
5219 /* */
5220 512;
5221 var TransitionLane5 =
5222 /* */
5223 1024;
5224 var TransitionLane6 =
5225 /* */
5226 2048;
5227 var TransitionLane7 =
5228 /* */
5229 4096;
5230 var TransitionLane8 =
5231 /* */
5232 8192;
5233 var TransitionLane9 =
5234 /* */
5235 16384;
5236 var TransitionLane10 =
5237 /* */
5238 32768;
5239 var TransitionLane11 =
5240 /* */
5241 65536;
5242 var TransitionLane12 =
5243 /* */
5244 131072;
5245 var TransitionLane13 =
5246 /* */
5247 262144;
5248 var TransitionLane14 =
5249 /* */
5250 524288;
5251 var TransitionLane15 =
5252 /* */
5253 1048576;
5254 var TransitionLane16 =
5255 /* */
5256 2097152;
5257 var RetryLanes =
5258 /* */
5259 130023424;
5260 var RetryLane1 =
5261 /* */
5262 4194304;
5263 var RetryLane2 =
5264 /* */
5265 8388608;
5266 var RetryLane3 =
5267 /* */
5268 16777216;
5269 var RetryLane4 =
5270 /* */
5271 33554432;
5272 var RetryLane5 =
5273 /* */
5274 67108864;
5275 var SomeRetryLane = RetryLane1;
5276 var SelectiveHydrationLane =
5277 /* */
5278 134217728;
5279 var NonIdleLanes =
5280 /* */
5281 268435455;
5282 var IdleHydrationLane =
5283 /* */
5284 268435456;
5285 var IdleLane =
5286 /* */
5287 536870912;
5288 var OffscreenLane =
5289 /* */
5290 1073741824; // This function is used for the experimental timeline (react-devtools-timeline)
5291 // It should be kept in sync with the Lanes values above.
5292
5293 function getLabelForLane(lane) {
5294 {
5295 if (lane & SyncLane) {
5296 return 'Sync';
5297 }
5298
5299 if (lane & InputContinuousHydrationLane) {
5300 return 'InputContinuousHydration';
5301 }
5302
5303 if (lane & InputContinuousLane) {
5304 return 'InputContinuous';
5305 }
5306
5307 if (lane & DefaultHydrationLane) {
5308 return 'DefaultHydration';
5309 }
5310
5311 if (lane & DefaultLane) {
5312 return 'Default';
5313 }
5314
5315 if (lane & TransitionHydrationLane) {
5316 return 'TransitionHydration';
5317 }
5318
5319 if (lane & TransitionLanes) {
5320 return 'Transition';
5321 }
5322
5323 if (lane & RetryLanes) {
5324 return 'Retry';
5325 }
5326
5327 if (lane & SelectiveHydrationLane) {
5328 return 'SelectiveHydration';
5329 }
5330
5331 if (lane & IdleHydrationLane) {
5332 return 'IdleHydration';
5333 }
5334
5335 if (lane & IdleLane) {
5336 return 'Idle';
5337 }
5338
5339 if (lane & OffscreenLane) {
5340 return 'Offscreen';
5341 }
5342 }
5343 }
5344 var NoTimestamp = -1;
5345 var nextTransitionLane = TransitionLane1;
5346 var nextRetryLane = RetryLane1;
5347
5348 function getHighestPriorityLanes(lanes) {
5349 switch (getHighestPriorityLane(lanes)) {
5350 case SyncLane:
5351 return SyncLane;
5352
5353 case InputContinuousHydrationLane:
5354 return InputContinuousHydrationLane;
5355
5356 case InputContinuousLane:
5357 return InputContinuousLane;
5358
5359 case DefaultHydrationLane:
5360 return DefaultHydrationLane;
5361
5362 case DefaultLane:
5363 return DefaultLane;
5364
5365 case TransitionHydrationLane:
5366 return TransitionHydrationLane;
5367
5368 case TransitionLane1:
5369 case TransitionLane2:
5370 case TransitionLane3:
5371 case TransitionLane4:
5372 case TransitionLane5:
5373 case TransitionLane6:
5374 case TransitionLane7:
5375 case TransitionLane8:
5376 case TransitionLane9:
5377 case TransitionLane10:
5378 case TransitionLane11:
5379 case TransitionLane12:
5380 case TransitionLane13:
5381 case TransitionLane14:
5382 case TransitionLane15:
5383 case TransitionLane16:
5384 return lanes & TransitionLanes;
5385
5386 case RetryLane1:
5387 case RetryLane2:
5388 case RetryLane3:
5389 case RetryLane4:
5390 case RetryLane5:
5391 return lanes & RetryLanes;
5392
5393 case SelectiveHydrationLane:
5394 return SelectiveHydrationLane;
5395
5396 case IdleHydrationLane:
5397 return IdleHydrationLane;
5398
5399 case IdleLane:
5400 return IdleLane;
5401
5402 case OffscreenLane:
5403 return OffscreenLane;
5404
5405 default:
5406 {
5407 error('Should have found matching lanes. This is a bug in React.');
5408 } // This shouldn't be reachable, but as a fallback, return the entire bitmask.
5409
5410
5411 return lanes;
5412 }
5413 }
5414
5415 function getNextLanes(root, wipLanes) {
5416 // Early bailout if there's no pending work left.
5417 var pendingLanes = root.pendingLanes;
5418
5419 if (pendingLanes === NoLanes) {
5420 return NoLanes;
5421 }
5422
5423 var nextLanes = NoLanes;
5424 var suspendedLanes = root.suspendedLanes;
5425 var pingedLanes = root.pingedLanes; // Do not work on any idle work until all the non-idle work has finished,
5426 // even if the work is suspended.
5427
5428 var nonIdlePendingLanes = pendingLanes & NonIdleLanes;
5429
5430 if (nonIdlePendingLanes !== NoLanes) {
5431 var nonIdleUnblockedLanes = nonIdlePendingLanes & ~suspendedLanes;
5432
5433 if (nonIdleUnblockedLanes !== NoLanes) {
5434 nextLanes = getHighestPriorityLanes(nonIdleUnblockedLanes);
5435 } else {
5436 var nonIdlePingedLanes = nonIdlePendingLanes & pingedLanes;
5437
5438 if (nonIdlePingedLanes !== NoLanes) {
5439 nextLanes = getHighestPriorityLanes(nonIdlePingedLanes);
5440 }
5441 }
5442 } else {
5443 // The only remaining work is Idle.
5444 var unblockedLanes = pendingLanes & ~suspendedLanes;
5445
5446 if (unblockedLanes !== NoLanes) {
5447 nextLanes = getHighestPriorityLanes(unblockedLanes);
5448 } else {
5449 if (pingedLanes !== NoLanes) {
5450 nextLanes = getHighestPriorityLanes(pingedLanes);
5451 }
5452 }
5453 }
5454
5455 if (nextLanes === NoLanes) {
5456 // This should only be reachable if we're suspended
5457 // TODO: Consider warning in this path if a fallback timer is not scheduled.
5458 return NoLanes;
5459 } // If we're already in the middle of a render, switching lanes will interrupt
5460 // it and we'll lose our progress. We should only do this if the new lanes are
5461 // higher priority.
5462
5463
5464 if (wipLanes !== NoLanes && wipLanes !== nextLanes && // If we already suspended with a delay, then interrupting is fine. Don't
5465 // bother waiting until the root is complete.
5466 (wipLanes & suspendedLanes) === NoLanes) {
5467 var nextLane = getHighestPriorityLane(nextLanes);
5468 var wipLane = getHighestPriorityLane(wipLanes);
5469
5470 if ( // Tests whether the next lane is equal or lower priority than the wip
5471 // one. This works because the bits decrease in priority as you go left.
5472 nextLane >= wipLane || // Default priority updates should not interrupt transition updates. The
5473 // only difference between default updates and transition updates is that
5474 // default updates do not support refresh transitions.
5475 nextLane === DefaultLane && (wipLane & TransitionLanes) !== NoLanes) {
5476 // Keep working on the existing in-progress tree. Do not interrupt.
5477 return wipLanes;
5478 }
5479 }
5480
5481 if ((nextLanes & InputContinuousLane) !== NoLanes) {
5482 // When updates are sync by default, we entangle continuous priority updates
5483 // and default updates, so they render in the same batch. The only reason
5484 // they use separate lanes is because continuous updates should interrupt
5485 // transitions, but default updates should not.
5486 nextLanes |= pendingLanes & DefaultLane;
5487 } // Check for entangled lanes and add them to the batch.
5488 //
5489 // A lane is said to be entangled with another when it's not allowed to render
5490 // in a batch that does not also include the other lane. Typically we do this
5491 // when multiple updates have the same source, and we only want to respond to
5492 // the most recent event from that source.
5493 //
5494 // Note that we apply entanglements *after* checking for partial work above.
5495 // This means that if a lane is entangled during an interleaved event while
5496 // it's already rendering, we won't interrupt it. This is intentional, since
5497 // entanglement is usually "best effort": we'll try our best to render the
5498 // lanes in the same batch, but it's not worth throwing out partially
5499 // completed work in order to do it.
5500 // TODO: Reconsider this. The counter-argument is that the partial work
5501 // represents an intermediate state, which we don't want to show to the user.
5502 // And by spending extra time finishing it, we're increasing the amount of
5503 // time it takes to show the final state, which is what they are actually
5504 // waiting for.
5505 //
5506 // For those exceptions where entanglement is semantically important, like
5507 // useMutableSource, we should ensure that there is no partial work at the
5508 // time we apply the entanglement.
5509
5510
5511 var entangledLanes = root.entangledLanes;
5512
5513 if (entangledLanes !== NoLanes) {
5514 var entanglements = root.entanglements;
5515 var lanes = nextLanes & entangledLanes;
5516
5517 while (lanes > 0) {
5518 var index = pickArbitraryLaneIndex(lanes);
5519 var lane = 1 << index;
5520 nextLanes |= entanglements[index];
5521 lanes &= ~lane;
5522 }
5523 }
5524
5525 return nextLanes;
5526 }
5527 function getMostRecentEventTime(root, lanes) {
5528 var eventTimes = root.eventTimes;
5529 var mostRecentEventTime = NoTimestamp;
5530
5531 while (lanes > 0) {
5532 var index = pickArbitraryLaneIndex(lanes);
5533 var lane = 1 << index;
5534 var eventTime = eventTimes[index];
5535
5536 if (eventTime > mostRecentEventTime) {
5537 mostRecentEventTime = eventTime;
5538 }
5539
5540 lanes &= ~lane;
5541 }
5542
5543 return mostRecentEventTime;
5544 }
5545
5546 function computeExpirationTime(lane, currentTime) {
5547 switch (lane) {
5548 case SyncLane:
5549 case InputContinuousHydrationLane:
5550 case InputContinuousLane:
5551 // User interactions should expire slightly more quickly.
5552 //
5553 // NOTE: This is set to the corresponding constant as in Scheduler.js.
5554 // When we made it larger, a product metric in www regressed, suggesting
5555 // there's a user interaction that's being starved by a series of
5556 // synchronous updates. If that theory is correct, the proper solution is
5557 // to fix the starvation. However, this scenario supports the idea that
5558 // expiration times are an important safeguard when starvation
5559 // does happen.
5560 return currentTime + 250;
5561
5562 case DefaultHydrationLane:
5563 case DefaultLane:
5564 case TransitionHydrationLane:
5565 case TransitionLane1:
5566 case TransitionLane2:
5567 case TransitionLane3:
5568 case TransitionLane4:
5569 case TransitionLane5:
5570 case TransitionLane6:
5571 case TransitionLane7:
5572 case TransitionLane8:
5573 case TransitionLane9:
5574 case TransitionLane10:
5575 case TransitionLane11:
5576 case TransitionLane12:
5577 case TransitionLane13:
5578 case TransitionLane14:
5579 case TransitionLane15:
5580 case TransitionLane16:
5581 return currentTime + 5000;
5582
5583 case RetryLane1:
5584 case RetryLane2:
5585 case RetryLane3:
5586 case RetryLane4:
5587 case RetryLane5:
5588 // TODO: Retries should be allowed to expire if they are CPU bound for
5589 // too long, but when I made this change it caused a spike in browser
5590 // crashes. There must be some other underlying bug; not super urgent but
5591 // ideally should figure out why and fix it. Unfortunately we don't have
5592 // a repro for the crashes, only detected via production metrics.
5593 return NoTimestamp;
5594
5595 case SelectiveHydrationLane:
5596 case IdleHydrationLane:
5597 case IdleLane:
5598 case OffscreenLane:
5599 // Anything idle priority or lower should never expire.
5600 return NoTimestamp;
5601
5602 default:
5603 {
5604 error('Should have found matching lanes. This is a bug in React.');
5605 }
5606
5607 return NoTimestamp;
5608 }
5609 }
5610
5611 function markStarvedLanesAsExpired(root, currentTime) {
5612 // TODO: This gets called every time we yield. We can optimize by storing
5613 // the earliest expiration time on the root. Then use that to quickly bail out
5614 // of this function.
5615 var pendingLanes = root.pendingLanes;
5616 var suspendedLanes = root.suspendedLanes;
5617 var pingedLanes = root.pingedLanes;
5618 var expirationTimes = root.expirationTimes; // Iterate through the pending lanes and check if we've reached their
5619 // expiration time. If so, we'll assume the update is being starved and mark
5620 // it as expired to force it to finish.
5621
5622 var lanes = pendingLanes;
5623
5624 while (lanes > 0) {
5625 var index = pickArbitraryLaneIndex(lanes);
5626 var lane = 1 << index;
5627 var expirationTime = expirationTimes[index];
5628
5629 if (expirationTime === NoTimestamp) {
5630 // Found a pending lane with no expiration time. If it's not suspended, or
5631 // if it's pinged, assume it's CPU-bound. Compute a new expiration time
5632 // using the current time.
5633 if ((lane & suspendedLanes) === NoLanes || (lane & pingedLanes) !== NoLanes) {
5634 // Assumes timestamps are monotonically increasing.
5635 expirationTimes[index] = computeExpirationTime(lane, currentTime);
5636 }
5637 } else if (expirationTime <= currentTime) {
5638 // This lane expired
5639 root.expiredLanes |= lane;
5640 }
5641
5642 lanes &= ~lane;
5643 }
5644 } // This returns the highest priority pending lanes regardless of whether they
5645 // are suspended.
5646
5647 function getHighestPriorityPendingLanes(root) {
5648 return getHighestPriorityLanes(root.pendingLanes);
5649 }
5650 function getLanesToRetrySynchronouslyOnError(root) {
5651 var everythingButOffscreen = root.pendingLanes & ~OffscreenLane;
5652
5653 if (everythingButOffscreen !== NoLanes) {
5654 return everythingButOffscreen;
5655 }
5656
5657 if (everythingButOffscreen & OffscreenLane) {
5658 return OffscreenLane;
5659 }
5660
5661 return NoLanes;
5662 }
5663 function includesSyncLane(lanes) {
5664 return (lanes & SyncLane) !== NoLanes;
5665 }
5666 function includesNonIdleWork(lanes) {
5667 return (lanes & NonIdleLanes) !== NoLanes;
5668 }
5669 function includesOnlyRetries(lanes) {
5670 return (lanes & RetryLanes) === lanes;
5671 }
5672 function includesOnlyTransitions(lanes) {
5673 return (lanes & TransitionLanes) === lanes;
5674 }
5675 function includesBlockingLane(root, lanes) {
5676
5677 var SyncDefaultLanes = InputContinuousHydrationLane | InputContinuousLane | DefaultHydrationLane | DefaultLane;
5678 return (lanes & SyncDefaultLanes) !== NoLanes;
5679 }
5680 function includesExpiredLane(root, lanes) {
5681 // This is a separate check from includesBlockingLane because a lane can
5682 // expire after a render has already started.
5683 return (lanes & root.expiredLanes) !== NoLanes;
5684 }
5685 function isTransitionLane(lane) {
5686 return (lane & TransitionLanes) !== 0;
5687 }
5688 function claimNextTransitionLane() {
5689 // Cycle through the lanes, assigning each new transition to the next lane.
5690 // In most cases, this means every transition gets its own lane, until we
5691 // run out of lanes and cycle back to the beginning.
5692 var lane = nextTransitionLane;
5693 nextTransitionLane <<= 1;
5694
5695 if ((nextTransitionLane & TransitionLanes) === 0) {
5696 nextTransitionLane = TransitionLane1;
5697 }
5698
5699 return lane;
5700 }
5701 function claimNextRetryLane() {
5702 var lane = nextRetryLane;
5703 nextRetryLane <<= 1;
5704
5705 if ((nextRetryLane & RetryLanes) === 0) {
5706 nextRetryLane = RetryLane1;
5707 }
5708
5709 return lane;
5710 }
5711 function getHighestPriorityLane(lanes) {
5712 return lanes & -lanes;
5713 }
5714 function pickArbitraryLane(lanes) {
5715 // This wrapper function gets inlined. Only exists so to communicate that it
5716 // doesn't matter which bit is selected; you can pick any bit without
5717 // affecting the algorithms where its used. Here I'm using
5718 // getHighestPriorityLane because it requires the fewest operations.
5719 return getHighestPriorityLane(lanes);
5720 }
5721
5722 function pickArbitraryLaneIndex(lanes) {
5723 return 31 - clz32(lanes);
5724 }
5725
5726 function laneToIndex(lane) {
5727 return pickArbitraryLaneIndex(lane);
5728 }
5729
5730 function includesSomeLane(a, b) {
5731 return (a & b) !== NoLanes;
5732 }
5733 function isSubsetOfLanes(set, subset) {
5734 return (set & subset) === subset;
5735 }
5736 function mergeLanes(a, b) {
5737 return a | b;
5738 }
5739 function removeLanes(set, subset) {
5740 return set & ~subset;
5741 }
5742 function intersectLanes(a, b) {
5743 return a & b;
5744 } // Seems redundant, but it changes the type from a single lane (used for
5745 // updates) to a group of lanes (used for flushing work).
5746
5747 function laneToLanes(lane) {
5748 return lane;
5749 }
5750 function higherPriorityLane(a, b) {
5751 // This works because the bit ranges decrease in priority as you go left.
5752 return a !== NoLane && a < b ? a : b;
5753 }
5754 function createLaneMap(initial) {
5755 // Intentionally pushing one by one.
5756 // https://v8.dev/blog/elements-kinds#avoid-creating-holes
5757 var laneMap = [];
5758
5759 for (var i = 0; i < TotalLanes; i++) {
5760 laneMap.push(initial);
5761 }
5762
5763 return laneMap;
5764 }
5765 function markRootUpdated(root, updateLane, eventTime) {
5766 root.pendingLanes |= updateLane; // If there are any suspended transitions, it's possible this new update
5767 // could unblock them. Clear the suspended lanes so that we can try rendering
5768 // them again.
5769 //
5770 // TODO: We really only need to unsuspend only lanes that are in the
5771 // `subtreeLanes` of the updated fiber, or the update lanes of the return
5772 // path. This would exclude suspended updates in an unrelated sibling tree,
5773 // since there's no way for this update to unblock it.
5774 //
5775 // We don't do this if the incoming update is idle, because we never process
5776 // idle updates until after all the regular updates have finished; there's no
5777 // way it could unblock a transition.
5778
5779 if (updateLane !== IdleLane) {
5780 root.suspendedLanes = NoLanes;
5781 root.pingedLanes = NoLanes;
5782 }
5783
5784 var eventTimes = root.eventTimes;
5785 var index = laneToIndex(updateLane); // We can always overwrite an existing timestamp because we prefer the most
5786 // recent event, and we assume time is monotonically increasing.
5787
5788 eventTimes[index] = eventTime;
5789 }
5790 function markRootSuspended(root, suspendedLanes) {
5791 root.suspendedLanes |= suspendedLanes;
5792 root.pingedLanes &= ~suspendedLanes; // The suspended lanes are no longer CPU-bound. Clear their expiration times.
5793
5794 var expirationTimes = root.expirationTimes;
5795 var lanes = suspendedLanes;
5796
5797 while (lanes > 0) {
5798 var index = pickArbitraryLaneIndex(lanes);
5799 var lane = 1 << index;
5800 expirationTimes[index] = NoTimestamp;
5801 lanes &= ~lane;
5802 }
5803 }
5804 function markRootPinged(root, pingedLanes, eventTime) {
5805 root.pingedLanes |= root.suspendedLanes & pingedLanes;
5806 }
5807 function markRootFinished(root, remainingLanes) {
5808 var noLongerPendingLanes = root.pendingLanes & ~remainingLanes;
5809 root.pendingLanes = remainingLanes; // Let's try everything again
5810
5811 root.suspendedLanes = 0;
5812 root.pingedLanes = 0;
5813 root.expiredLanes &= remainingLanes;
5814 root.mutableReadLanes &= remainingLanes;
5815 root.entangledLanes &= remainingLanes;
5816 var entanglements = root.entanglements;
5817 var eventTimes = root.eventTimes;
5818 var expirationTimes = root.expirationTimes; // Clear the lanes that no longer have pending work
5819
5820 var lanes = noLongerPendingLanes;
5821
5822 while (lanes > 0) {
5823 var index = pickArbitraryLaneIndex(lanes);
5824 var lane = 1 << index;
5825 entanglements[index] = NoLanes;
5826 eventTimes[index] = NoTimestamp;
5827 expirationTimes[index] = NoTimestamp;
5828 lanes &= ~lane;
5829 }
5830 }
5831 function markRootEntangled(root, entangledLanes) {
5832 // In addition to entangling each of the given lanes with each other, we also
5833 // have to consider _transitive_ entanglements. For each lane that is already
5834 // entangled with *any* of the given lanes, that lane is now transitively
5835 // entangled with *all* the given lanes.
5836 //
5837 // Translated: If C is entangled with A, then entangling A with B also
5838 // entangles C with B.
5839 //
5840 // If this is hard to grasp, it might help to intentionally break this
5841 // function and look at the tests that fail in ReactTransition-test.js. Try
5842 // commenting out one of the conditions below.
5843 var rootEntangledLanes = root.entangledLanes |= entangledLanes;
5844 var entanglements = root.entanglements;
5845 var lanes = rootEntangledLanes;
5846
5847 while (lanes) {
5848 var index = pickArbitraryLaneIndex(lanes);
5849 var lane = 1 << index;
5850
5851 if ( // Is this one of the newly entangled lanes?
5852 lane & entangledLanes | // Is this lane transitively entangled with the newly entangled lanes?
5853 entanglements[index] & entangledLanes) {
5854 entanglements[index] |= entangledLanes;
5855 }
5856
5857 lanes &= ~lane;
5858 }
5859 }
5860 function getBumpedLaneForHydration(root, renderLanes) {
5861 var renderLane = getHighestPriorityLane(renderLanes);
5862 var lane;
5863
5864 switch (renderLane) {
5865 case InputContinuousLane:
5866 lane = InputContinuousHydrationLane;
5867 break;
5868
5869 case DefaultLane:
5870 lane = DefaultHydrationLane;
5871 break;
5872
5873 case TransitionLane1:
5874 case TransitionLane2:
5875 case TransitionLane3:
5876 case TransitionLane4:
5877 case TransitionLane5:
5878 case TransitionLane6:
5879 case TransitionLane7:
5880 case TransitionLane8:
5881 case TransitionLane9:
5882 case TransitionLane10:
5883 case TransitionLane11:
5884 case TransitionLane12:
5885 case TransitionLane13:
5886 case TransitionLane14:
5887 case TransitionLane15:
5888 case TransitionLane16:
5889 case RetryLane1:
5890 case RetryLane2:
5891 case RetryLane3:
5892 case RetryLane4:
5893 case RetryLane5:
5894 lane = TransitionHydrationLane;
5895 break;
5896
5897 case IdleLane:
5898 lane = IdleHydrationLane;
5899 break;
5900
5901 default:
5902 // Everything else is already either a hydration lane, or shouldn't
5903 // be retried at a hydration lane.
5904 lane = NoLane;
5905 break;
5906 } // Check if the lane we chose is suspended. If so, that indicates that we
5907 // already attempted and failed to hydrate at that level. Also check if we're
5908 // already rendering that lane, which is rare but could happen.
5909
5910
5911 if ((lane & (root.suspendedLanes | renderLanes)) !== NoLane) {
5912 // Give up trying to hydrate and fall back to client render.
5913 return NoLane;
5914 }
5915
5916 return lane;
5917 }
5918 function addFiberToLanesMap(root, fiber, lanes) {
5919
5920 if (!isDevToolsPresent) {
5921 return;
5922 }
5923
5924 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap;
5925
5926 while (lanes > 0) {
5927 var index = laneToIndex(lanes);
5928 var lane = 1 << index;
5929 var updaters = pendingUpdatersLaneMap[index];
5930 updaters.add(fiber);
5931 lanes &= ~lane;
5932 }
5933 }
5934 function movePendingFibersToMemoized(root, lanes) {
5935
5936 if (!isDevToolsPresent) {
5937 return;
5938 }
5939
5940 var pendingUpdatersLaneMap = root.pendingUpdatersLaneMap;
5941 var memoizedUpdaters = root.memoizedUpdaters;
5942
5943 while (lanes > 0) {
5944 var index = laneToIndex(lanes);
5945 var lane = 1 << index;
5946 var updaters = pendingUpdatersLaneMap[index];
5947
5948 if (updaters.size > 0) {
5949 updaters.forEach(function (fiber) {
5950 var alternate = fiber.alternate;
5951
5952 if (alternate === null || !memoizedUpdaters.has(alternate)) {
5953 memoizedUpdaters.add(fiber);
5954 }
5955 });
5956 updaters.clear();
5957 }
5958
5959 lanes &= ~lane;
5960 }
5961 }
5962
5963 var DiscreteEventPriority = SyncLane;
5964 var ContinuousEventPriority = InputContinuousLane;
5965 var DefaultEventPriority = DefaultLane;
5966 var IdleEventPriority = IdleLane;
5967 var currentUpdatePriority = NoLane;
5968 function getCurrentUpdatePriority() {
5969 return currentUpdatePriority;
5970 }
5971 function setCurrentUpdatePriority(newPriority) {
5972 currentUpdatePriority = newPriority;
5973 }
5974 function runWithPriority(priority, fn) {
5975 var previousPriority = currentUpdatePriority;
5976
5977 try {
5978 currentUpdatePriority = priority;
5979 return fn();
5980 } finally {
5981 currentUpdatePriority = previousPriority;
5982 }
5983 }
5984 function higherEventPriority(a, b) {
5985 return a !== 0 && a < b ? a : b;
5986 }
5987 function lowerEventPriority(a, b) {
5988 return a === 0 || a > b ? a : b;
5989 }
5990 function isHigherEventPriority(a, b) {
5991 return a !== 0 && a < b;
5992 }
5993 function 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.
6014 function isRootDehydrated(root) {
6015 var currentState = root.current.memoizedState;
6016 return currentState.isDehydrated;
6017 }
6018
6019 var _attemptSynchronousHydration;
6020
6021 function setAttemptSynchronousHydration(fn) {
6022 _attemptSynchronousHydration = fn;
6023 }
6024 function attemptSynchronousHydration(fiber) {
6025 _attemptSynchronousHydration(fiber);
6026 }
6027 var attemptContinuousHydration;
6028 function setAttemptContinuousHydration(fn) {
6029 attemptContinuousHydration = fn;
6030 }
6031 var attemptHydrationAtCurrentPriority;
6032 function setAttemptHydrationAtCurrentPriority(fn) {
6033 attemptHydrationAtCurrentPriority = fn;
6034 }
6035 var getCurrentUpdatePriority$1;
6036 function setGetCurrentUpdatePriority(fn) {
6037 getCurrentUpdatePriority$1 = fn;
6038 }
6039 var attemptHydrationAtPriority;
6040 function 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
6045 var hasScheduledReplayAttempt = false; // The queue of discrete events to be replayed.
6046
6047 var queuedDiscreteEvents = []; // Indicates if any continuous event targets are non-null for early bailout.
6048 // if the last target was dehydrated.
6049
6050 var queuedFocus = null;
6051 var queuedDrag = null;
6052 var queuedMouse = null; // For pointer events there can be one latest event per pointerId.
6053
6054 var queuedPointers = new Map();
6055 var queuedPointerCaptures = new Map(); // We could consider replaying selectionchange and touchmoves too.
6056
6057 var queuedExplicitHydrationTargets = [];
6058 var synchronouslyHydratedEvents = ['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'];
6060 function isDiscreteEventThatRequiresHydration(eventType) {
6061 return synchronouslyHydratedEvents.indexOf(eventType) > -1;
6062 }
6063
6064 function 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 } // Resets the replaying for this type of continuous event to no event.
6073
6074
6075 function clearIfContinuousEvent(domEventName, nativeEvent) {
6076 switch (domEventName) {
6077 case 'focusin':
6078 case 'focusout':
6079 queuedFocus = null;
6080 break;
6081
6082 case 'dragenter':
6083 case 'dragleave':
6084 queuedDrag = null;
6085 break;
6086
6087 case 'mouseover':
6088 case 'mouseout':
6089 queuedMouse = null;
6090 break;
6091
6092 case 'pointerover':
6093 case 'pointerout':
6094 {
6095 var pointerId = nativeEvent.pointerId;
6096 queuedPointers.delete(pointerId);
6097 break;
6098 }
6099
6100 case 'gotpointercapture':
6101 case 'lostpointercapture':
6102 {
6103 var _pointerId = nativeEvent.pointerId;
6104 queuedPointerCaptures.delete(_pointerId);
6105 break;
6106 }
6107 }
6108 }
6109
6110 function accumulateOrCreateContinuousQueuedReplayableEvent(existingQueuedEvent, blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6111 if (existingQueuedEvent === null || existingQueuedEvent.nativeEvent !== nativeEvent) {
6112 var queuedEvent = createQueuedReplayableEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);
6113
6114 if (blockedOn !== null) {
6115 var _fiber = getInstanceFromNode(blockedOn);
6116
6117 if (_fiber !== null) {
6118 // Attempt to increase the priority of this target.
6119 attemptContinuousHydration(_fiber);
6120 }
6121 }
6122
6123 return queuedEvent;
6124 } // If we have already queued this exact event, then it's because
6125 // the different event systems have different DOM event listeners.
6126 // We can accumulate the flags, and the targetContainers, and
6127 // store a single event to be replayed.
6128
6129
6130 existingQueuedEvent.eventSystemFlags |= eventSystemFlags;
6131 var targetContainers = existingQueuedEvent.targetContainers;
6132
6133 if (targetContainer !== null && targetContainers.indexOf(targetContainer) === -1) {
6134 targetContainers.push(targetContainer);
6135 }
6136
6137 return existingQueuedEvent;
6138 }
6139
6140 function queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6141 // These set relatedTarget to null because the replayed event will be treated as if we
6142 // moved from outside the window (no target) onto the target once it hydrates.
6143 // Instead of mutating we could clone the event.
6144 switch (domEventName) {
6145 case 'focusin':
6146 {
6147 var focusEvent = nativeEvent;
6148 queuedFocus = accumulateOrCreateContinuousQueuedReplayableEvent(queuedFocus, blockedOn, domEventName, eventSystemFlags, targetContainer, focusEvent);
6149 return true;
6150 }
6151
6152 case 'dragenter':
6153 {
6154 var dragEvent = nativeEvent;
6155 queuedDrag = accumulateOrCreateContinuousQueuedReplayableEvent(queuedDrag, blockedOn, domEventName, eventSystemFlags, targetContainer, dragEvent);
6156 return true;
6157 }
6158
6159 case 'mouseover':
6160 {
6161 var mouseEvent = nativeEvent;
6162 queuedMouse = accumulateOrCreateContinuousQueuedReplayableEvent(queuedMouse, blockedOn, domEventName, eventSystemFlags, targetContainer, mouseEvent);
6163 return true;
6164 }
6165
6166 case 'pointerover':
6167 {
6168 var pointerEvent = nativeEvent;
6169 var pointerId = pointerEvent.pointerId;
6170 queuedPointers.set(pointerId, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointers.get(pointerId) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, pointerEvent));
6171 return true;
6172 }
6173
6174 case 'gotpointercapture':
6175 {
6176 var _pointerEvent = nativeEvent;
6177 var _pointerId2 = _pointerEvent.pointerId;
6178 queuedPointerCaptures.set(_pointerId2, accumulateOrCreateContinuousQueuedReplayableEvent(queuedPointerCaptures.get(_pointerId2) || null, blockedOn, domEventName, eventSystemFlags, targetContainer, _pointerEvent));
6179 return true;
6180 }
6181 }
6182
6183 return false;
6184 } // Check if this target is unblocked. Returns true if it's unblocked.
6185
6186 function attemptExplicitHydrationTarget(queuedTarget) {
6187 // TODO: This function shares a lot of logic with findInstanceBlockingEvent.
6188 // Try to unify them. It's a bit tricky since it would require two return
6189 // values.
6190 var targetInst = getClosestInstanceFromNode(queuedTarget.target);
6191
6192 if (targetInst !== null) {
6193 var nearestMounted = getNearestMountedFiber(targetInst);
6194
6195 if (nearestMounted !== null) {
6196 var tag = nearestMounted.tag;
6197
6198 if (tag === SuspenseComponent) {
6199 var instance = getSuspenseInstanceFromFiber(nearestMounted);
6200
6201 if (instance !== null) {
6202 // We're blocked on hydrating this boundary.
6203 // Increase its priority.
6204 queuedTarget.blockedOn = instance;
6205 attemptHydrationAtPriority(queuedTarget.priority, function () {
6206 attemptHydrationAtCurrentPriority(nearestMounted);
6207 });
6208 return;
6209 }
6210 } else if (tag === HostRoot) {
6211 var root = nearestMounted.stateNode;
6212
6213 if (isRootDehydrated(root)) {
6214 queuedTarget.blockedOn = getContainerFromFiber(nearestMounted); // We don't currently have a way to increase the priority of
6215 // a root other than sync.
6216
6217 return;
6218 }
6219 }
6220 }
6221 }
6222
6223 queuedTarget.blockedOn = null;
6224 }
6225
6226 function queueExplicitHydrationTarget(target) {
6227 {
6228 // TODO: This will read the priority if it's dispatched by the React
6229 // event system but not native events. Should read window.event.type, like
6230 // we do for updates (getCurrentEventPriority).
6231 var updatePriority = getCurrentUpdatePriority$1();
6232 var queuedTarget = {
6233 blockedOn: null,
6234 target: target,
6235 priority: updatePriority
6236 };
6237 var i = 0;
6238
6239 for (; i < queuedExplicitHydrationTargets.length; i++) {
6240 // Stop once we hit the first target with lower priority than
6241 if (!isHigherEventPriority(updatePriority, queuedExplicitHydrationTargets[i].priority)) {
6242 break;
6243 }
6244 }
6245
6246 queuedExplicitHydrationTargets.splice(i, 0, queuedTarget);
6247
6248 if (i === 0) {
6249 attemptExplicitHydrationTarget(queuedTarget);
6250 }
6251 }
6252 }
6253
6254 function attemptReplayContinuousQueuedEvent(queuedEvent) {
6255 if (queuedEvent.blockedOn !== null) {
6256 return false;
6257 }
6258
6259 var targetContainers = queuedEvent.targetContainers;
6260
6261 while (targetContainers.length > 0) {
6262 var targetContainer = targetContainers[0];
6263 var nextBlockedOn = findInstanceBlockingEvent(queuedEvent.domEventName, queuedEvent.eventSystemFlags, targetContainer, queuedEvent.nativeEvent);
6264
6265 if (nextBlockedOn === null) {
6266 var nativeEvent = queuedEvent.nativeEvent;
6267 var nativeEventClone = new nativeEvent.constructor(nativeEvent.type, nativeEvent);
6268 setReplayingEvent(nativeEventClone);
6269 nativeEvent.target.dispatchEvent(nativeEventClone);
6270 resetReplayingEvent();
6271 } else {
6272 // We're still blocked. Try again later.
6273 var _fiber2 = getInstanceFromNode(nextBlockedOn);
6274
6275 if (_fiber2 !== null) {
6276 attemptContinuousHydration(_fiber2);
6277 }
6278
6279 queuedEvent.blockedOn = nextBlockedOn;
6280 return false;
6281 } // This target container was successfully dispatched. Try the next.
6282
6283
6284 targetContainers.shift();
6285 }
6286
6287 return true;
6288 }
6289
6290 function attemptReplayContinuousQueuedEventInMap(queuedEvent, key, map) {
6291 if (attemptReplayContinuousQueuedEvent(queuedEvent)) {
6292 map.delete(key);
6293 }
6294 }
6295
6296 function replayUnblockedEvents() {
6297 hasScheduledReplayAttempt = false; // Next replay any continuous events.
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
6315 function 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 unstable_scheduleCallback(unstable_NormalPriority, replayUnblockedEvents);
6325 }
6326 }
6327 }
6328
6329 function 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
6390 var ReactCurrentBatchConfig = ReactSharedInternals.ReactCurrentBatchConfig; // TODO: can we stop exporting these?
6391 function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) {
6392 var eventPriority = getEventPriority(domEventName);
6393 var listenerWrapper;
6394
6395 switch (eventPriority) {
6396 case DiscreteEventPriority:
6397 listenerWrapper = dispatchDiscreteEvent;
6398 break;
6399
6400 case ContinuousEventPriority:
6401 listenerWrapper = dispatchContinuousEvent;
6402 break;
6403
6404 case DefaultEventPriority:
6405 default:
6406 listenerWrapper = dispatchEvent;
6407 break;
6408 }
6409
6410 return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
6411 }
6412
6413 function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) {
6414 var previousPriority = getCurrentUpdatePriority();
6415 var prevTransition = ReactCurrentBatchConfig.transition;
6416 ReactCurrentBatchConfig.transition = null;
6417
6418 try {
6419 setCurrentUpdatePriority(DiscreteEventPriority);
6420 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
6421 } finally {
6422 setCurrentUpdatePriority(previousPriority);
6423 ReactCurrentBatchConfig.transition = prevTransition;
6424 }
6425 }
6426
6427 function dispatchContinuousEvent(domEventName, eventSystemFlags, container, nativeEvent) {
6428 var previousPriority = getCurrentUpdatePriority();
6429 var prevTransition = ReactCurrentBatchConfig.transition;
6430 ReactCurrentBatchConfig.transition = null;
6431
6432 try {
6433 setCurrentUpdatePriority(ContinuousEventPriority);
6434 dispatchEvent(domEventName, eventSystemFlags, container, nativeEvent);
6435 } finally {
6436 setCurrentUpdatePriority(previousPriority);
6437 ReactCurrentBatchConfig.transition = prevTransition;
6438 }
6439 }
6440
6441 function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6442 var blockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
6443
6444 if (blockedOn === null) {
6445 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
6446 clearIfContinuousEvent(domEventName, nativeEvent);
6447 return;
6448 }
6449
6450 if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) {
6451 nativeEvent.stopPropagation();
6452 return;
6453 } // We need to clear only if we didn't queue because
6454 // queueing is accumulative.
6455
6456
6457 clearIfContinuousEvent(domEventName, nativeEvent);
6458
6459 if (eventSystemFlags & IS_CAPTURE_PHASE && isDiscreteEventThatRequiresHydration(domEventName)) {
6460 while (blockedOn !== null) {
6461 var fiber = getInstanceFromNode(blockedOn);
6462
6463 if (fiber !== null) {
6464 attemptSynchronousHydration(fiber);
6465 }
6466
6467 var nextBlockedOn = findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);
6468
6469 if (nextBlockedOn === null) {
6470 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, return_targetInst, targetContainer);
6471 }
6472
6473 if (nextBlockedOn === blockedOn) {
6474 break;
6475 }
6476
6477 blockedOn = nextBlockedOn;
6478 }
6479
6480 if (blockedOn !== null) {
6481 nativeEvent.stopPropagation();
6482 }
6483
6484 return;
6485 } // This is not replayable so we'll invoke it but without a target,
6486 // in case the event system needs to trace it.
6487
6488
6489 dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer);
6490 }
6491
6492 var return_targetInst = null; // Returns a SuspenseInstance or Container if it's blocked.
6493 // The return_targetInst field above is conceptually part of the return value.
6494
6495 function findInstanceBlockingEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {
6496 // TODO: Warn if _enabled is false.
6497 return_targetInst = null;
6498 var nativeEventTarget = getEventTarget(nativeEvent);
6499 var targetInst = getClosestInstanceFromNode(nativeEventTarget);
6500
6501 if (targetInst !== null) {
6502 var nearestMounted = getNearestMountedFiber(targetInst);
6503
6504 if (nearestMounted === null) {
6505 // This tree has been unmounted already. Dispatch without a target.
6506 targetInst = null;
6507 } else {
6508 var tag = nearestMounted.tag;
6509
6510 if (tag === SuspenseComponent) {
6511 var instance = getSuspenseInstanceFromFiber(nearestMounted);
6512
6513 if (instance !== null) {
6514 // Queue the event to be replayed later. Abort dispatching since we
6515 // don't want this event dispatched twice through the event system.
6516 // TODO: If this is the first discrete event in the queue. Schedule an increased
6517 // priority for this boundary.
6518 return instance;
6519 } // This shouldn't happen, something went wrong but to avoid blocking
6520 // the whole system, dispatch the event without a target.
6521 // TODO: Warn.
6522
6523
6524 targetInst = null;
6525 } else if (tag === HostRoot) {
6526 var root = nearestMounted.stateNode;
6527
6528 if (isRootDehydrated(root)) {
6529 // If this happens during a replay something went wrong and it might block
6530 // the whole system.
6531 return getContainerFromFiber(nearestMounted);
6532 }
6533
6534 targetInst = null;
6535 } else if (nearestMounted !== targetInst) {
6536 // If we get an event (ex: img onload) before committing that
6537 // component's mount, ignore it for now (that is, treat it as if it was an
6538 // event on a non-React tree). We might also consider queueing events and
6539 // dispatching them after the mount.
6540 targetInst = null;
6541 }
6542 }
6543 }
6544
6545 return_targetInst = targetInst; // We're not blocked on anything.
6546
6547 return null;
6548 }
6549 function getEventPriority(domEventName) {
6550 switch (domEventName) {
6551 // Used by SimpleEventPlugin:
6552 case 'cancel':
6553 case 'click':
6554 case 'close':
6555 case 'contextmenu':
6556 case 'copy':
6557 case 'cut':
6558 case 'auxclick':
6559 case 'dblclick':
6560 case 'dragend':
6561 case 'dragstart':
6562 case 'drop':
6563 case 'focusin':
6564 case 'focusout':
6565 case 'input':
6566 case 'invalid':
6567 case 'keydown':
6568 case 'keypress':
6569 case 'keyup':
6570 case 'mousedown':
6571 case 'mouseup':
6572 case 'paste':
6573 case 'pause':
6574 case 'play':
6575 case 'pointercancel':
6576 case 'pointerdown':
6577 case 'pointerup':
6578 case 'ratechange':
6579 case 'reset':
6580 case 'resize':
6581 case 'seeked':
6582 case 'submit':
6583 case 'touchcancel':
6584 case 'touchend':
6585 case 'touchstart':
6586 case 'volumechange': // Used by polyfills:
6587 // eslint-disable-next-line no-fallthrough
6588
6589 case 'change':
6590 case 'selectionchange':
6591 case 'textInput':
6592 case 'compositionstart':
6593 case 'compositionend':
6594 case 'compositionupdate': // Only enableCreateEventHandleAPI:
6595 // eslint-disable-next-line no-fallthrough
6596
6597 case 'beforeblur':
6598 case 'afterblur': // Not used by React but could be by user code:
6599 // eslint-disable-next-line no-fallthrough
6600
6601 case 'beforeinput':
6602 case 'blur':
6603 case 'fullscreenchange':
6604 case 'focus':
6605 case 'hashchange':
6606 case 'popstate':
6607 case 'select':
6608 case 'selectstart':
6609 return DiscreteEventPriority;
6610
6611 case 'drag':
6612 case 'dragenter':
6613 case 'dragexit':
6614 case 'dragleave':
6615 case 'dragover':
6616 case 'mousemove':
6617 case 'mouseout':
6618 case 'mouseover':
6619 case 'pointermove':
6620 case 'pointerout':
6621 case 'pointerover':
6622 case 'scroll':
6623 case 'toggle':
6624 case 'touchmove':
6625 case 'wheel': // Not used by React but could be by user code:
6626 // eslint-disable-next-line no-fallthrough
6627
6628 case 'mouseenter':
6629 case 'mouseleave':
6630 case 'pointerenter':
6631 case 'pointerleave':
6632 return ContinuousEventPriority;
6633
6634 case 'message':
6635 {
6636 // We might be in the Scheduler callback.
6637 // Eventually this mechanism will be replaced by a check
6638 // of the current priority on the native scheduler.
6639 var schedulerPriority = getCurrentPriorityLevel();
6640
6641 switch (schedulerPriority) {
6642 case ImmediatePriority:
6643 return DiscreteEventPriority;
6644
6645 case UserBlockingPriority:
6646 return ContinuousEventPriority;
6647
6648 case NormalPriority:
6649 case LowPriority:
6650 // TODO: Handle LowSchedulerPriority, somehow. Maybe the same lane as hydration.
6651 return DefaultEventPriority;
6652
6653 case IdlePriority:
6654 return IdleEventPriority;
6655
6656 default:
6657 return DefaultEventPriority;
6658 }
6659 }
6660
6661 default:
6662 return DefaultEventPriority;
6663 }
6664 }
6665
6666 function addEventBubbleListener(target, eventType, listener) {
6667 target.addEventListener(eventType, listener, false);
6668 return listener;
6669 }
6670 function addEventCaptureListener(target, eventType, listener) {
6671 target.addEventListener(eventType, listener, true);
6672 return listener;
6673 }
6674 function addEventCaptureListenerWithPassiveFlag(target, eventType, listener, passive) {
6675 target.addEventListener(eventType, listener, {
6676 capture: true,
6677 passive: passive
6678 });
6679 return listener;
6680 }
6681 function addEventBubbleListenerWithPassiveFlag(target, eventType, listener, passive) {
6682 target.addEventListener(eventType, listener, {
6683 passive: passive
6684 });
6685 return listener;
6686 }
6687
6688 /**
6689 * These variables store information about text content of a target node,
6690 * allowing comparison of content before and after a given event.
6691 *
6692 * Identify the node where selection currently begins, then observe
6693 * both its text content and its current position in the DOM. Since the
6694 * browser may natively replace the target node during composition, we can
6695 * use its position to find its replacement.
6696 *
6697 *
6698 */
6699 var root = null;
6700 var startText = null;
6701 var fallbackText = null;
6702 function initialize(nativeEventTarget) {
6703 root = nativeEventTarget;
6704 startText = getText();
6705 return true;
6706 }
6707 function reset() {
6708 root = null;
6709 startText = null;
6710 fallbackText = null;
6711 }
6712 function getData() {
6713 if (fallbackText) {
6714 return fallbackText;
6715 }
6716
6717 var start;
6718 var startValue = startText;
6719 var startLength = startValue.length;
6720 var end;
6721 var endValue = getText();
6722 var endLength = endValue.length;
6723
6724 for (start = 0; start < startLength; start++) {
6725 if (startValue[start] !== endValue[start]) {
6726 break;
6727 }
6728 }
6729
6730 var minEnd = startLength - start;
6731
6732 for (end = 1; end <= minEnd; end++) {
6733 if (startValue[startLength - end] !== endValue[endLength - end]) {
6734 break;
6735 }
6736 }
6737
6738 var sliceTail = end > 1 ? 1 - end : undefined;
6739 fallbackText = endValue.slice(start, sliceTail);
6740 return fallbackText;
6741 }
6742 function getText() {
6743 if ('value' in root) {
6744 return root.value;
6745 }
6746
6747 return root.textContent;
6748 }
6749
6750 /**
6751 * `charCode` represents the actual "character code" and is safe to use with
6752 * `String.fromCharCode`. As such, only keys that correspond to printable
6753 * characters produce a valid `charCode`, the only exception to this is Enter.
6754 * The Tab-key is considered non-printable and does not have a `charCode`,
6755 * presumably because it does not produce a tab-character in browsers.
6756 *
6757 * @param {object} nativeEvent Native browser event.
6758 * @return {number} Normalized `charCode` property.
6759 */
6760 function getEventCharCode(nativeEvent) {
6761 var charCode;
6762 var keyCode = nativeEvent.keyCode;
6763
6764 if ('charCode' in nativeEvent) {
6765 charCode = nativeEvent.charCode; // FF does not set `charCode` for the Enter-key, check against `keyCode`.
6766
6767 if (charCode === 0 && keyCode === 13) {
6768 charCode = 13;
6769 }
6770 } else {
6771 // IE8 does not implement `charCode`, but `keyCode` has the correct value.
6772 charCode = keyCode;
6773 } // IE and Edge (on Windows) and Chrome / Safari (on Windows and Linux)
6774 // report Enter as charCode 10 when ctrl is pressed.
6775
6776
6777 if (charCode === 10) {
6778 charCode = 13;
6779 } // Some non-printable keys are reported in `charCode`/`keyCode`, discard them.
6780 // Must not discard the (non-)printable Enter-key.
6781
6782
6783 if (charCode >= 32 || charCode === 13) {
6784 return charCode;
6785 }
6786
6787 return 0;
6788 }
6789
6790 function functionThatReturnsTrue() {
6791 return true;
6792 }
6793
6794 function functionThatReturnsFalse() {
6795 return false;
6796 } // This is intentionally a factory so that we have different returned constructors.
6797 // If we had a single constructor, it would be megamorphic and engines would deopt.
6798
6799
6800 function createSyntheticEvent(Interface) {
6801 /**
6802 * Synthetic events are dispatched by event plugins, typically in response to a
6803 * top-level event delegation handler.
6804 *
6805 * These systems should generally use pooling to reduce the frequency of garbage
6806 * collection. The system should check `isPersistent` to determine whether the
6807 * event should be released into the pool after being dispatched. Users that
6808 * need a persisted event should invoke `persist`.
6809 *
6810 * Synthetic events (and subclasses) implement the DOM Level 3 Events API by
6811 * normalizing browser quirks. Subclasses do not necessarily have to implement a
6812 * DOM interface; custom application-specific events can also subclass this.
6813 */
6814 function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {
6815 this._reactName = reactName;
6816 this._targetInst = targetInst;
6817 this.type = reactEventType;
6818 this.nativeEvent = nativeEvent;
6819 this.target = nativeEventTarget;
6820 this.currentTarget = null;
6821
6822 for (var _propName in Interface) {
6823 if (!Interface.hasOwnProperty(_propName)) {
6824 continue;
6825 }
6826
6827 var normalize = Interface[_propName];
6828
6829 if (normalize) {
6830 this[_propName] = normalize(nativeEvent);
6831 } else {
6832 this[_propName] = nativeEvent[_propName];
6833 }
6834 }
6835
6836 var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;
6837
6838 if (defaultPrevented) {
6839 this.isDefaultPrevented = functionThatReturnsTrue;
6840 } else {
6841 this.isDefaultPrevented = functionThatReturnsFalse;
6842 }
6843
6844 this.isPropagationStopped = functionThatReturnsFalse;
6845 return this;
6846 }
6847
6848 assign(SyntheticBaseEvent.prototype, {
6849 preventDefault: function () {
6850 this.defaultPrevented = true;
6851 var event = this.nativeEvent;
6852
6853 if (!event) {
6854 return;
6855 }
6856
6857 if (event.preventDefault) {
6858 event.preventDefault(); // $FlowFixMe - flow is not aware of `unknown` in IE
6859 } else if (typeof event.returnValue !== 'unknown') {
6860 event.returnValue = false;
6861 }
6862
6863 this.isDefaultPrevented = functionThatReturnsTrue;
6864 },
6865 stopPropagation: function () {
6866 var event = this.nativeEvent;
6867
6868 if (!event) {
6869 return;
6870 }
6871
6872 if (event.stopPropagation) {
6873 event.stopPropagation(); // $FlowFixMe - flow is not aware of `unknown` in IE
6874 } else if (typeof event.cancelBubble !== 'unknown') {
6875 // The ChangeEventPlugin registers a "propertychange" event for
6876 // IE. This event does not support bubbling or cancelling, and
6877 // any references to cancelBubble throw "Member not found". A
6878 // typeof check of "unknown" circumvents this issue (and is also
6879 // IE specific).
6880 event.cancelBubble = true;
6881 }
6882
6883 this.isPropagationStopped = functionThatReturnsTrue;
6884 },
6885
6886 /**
6887 * We release all dispatched `SyntheticEvent`s after each event loop, adding
6888 * them back into the pool. This allows a way to hold onto a reference that
6889 * won't be added back into the pool.
6890 */
6891 persist: function () {// Modern event system doesn't use pooling.
6892 },
6893
6894 /**
6895 * Checks if this event should be released back into the pool.
6896 *
6897 * @return {boolean} True if this should not be released, false otherwise.
6898 */
6899 isPersistent: functionThatReturnsTrue
6900 });
6901 return SyntheticBaseEvent;
6902 }
6903 /**
6904 * @interface Event
6905 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6906 */
6907
6908
6909 var EventInterface = {
6910 eventPhase: 0,
6911 bubbles: 0,
6912 cancelable: 0,
6913 timeStamp: function (event) {
6914 return event.timeStamp || Date.now();
6915 },
6916 defaultPrevented: 0,
6917 isTrusted: 0
6918 };
6919 var SyntheticEvent = createSyntheticEvent(EventInterface);
6920
6921 var UIEventInterface = assign({}, EventInterface, {
6922 view: 0,
6923 detail: 0
6924 });
6925
6926 var SyntheticUIEvent = createSyntheticEvent(UIEventInterface);
6927 var lastMovementX;
6928 var lastMovementY;
6929 var lastMouseEvent;
6930
6931 function updateMouseMovementPolyfillState(event) {
6932 if (event !== lastMouseEvent) {
6933 if (lastMouseEvent && event.type === 'mousemove') {
6934 lastMovementX = event.screenX - lastMouseEvent.screenX;
6935 lastMovementY = event.screenY - lastMouseEvent.screenY;
6936 } else {
6937 lastMovementX = 0;
6938 lastMovementY = 0;
6939 }
6940
6941 lastMouseEvent = event;
6942 }
6943 }
6944 /**
6945 * @interface MouseEvent
6946 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6947 */
6948
6949
6950 var MouseEventInterface = assign({}, UIEventInterface, {
6951 screenX: 0,
6952 screenY: 0,
6953 clientX: 0,
6954 clientY: 0,
6955 pageX: 0,
6956 pageY: 0,
6957 ctrlKey: 0,
6958 shiftKey: 0,
6959 altKey: 0,
6960 metaKey: 0,
6961 getModifierState: getEventModifierState,
6962 button: 0,
6963 buttons: 0,
6964 relatedTarget: function (event) {
6965 if (event.relatedTarget === undefined) return event.fromElement === event.srcElement ? event.toElement : event.fromElement;
6966 return event.relatedTarget;
6967 },
6968 movementX: function (event) {
6969 if ('movementX' in event) {
6970 return event.movementX;
6971 }
6972
6973 updateMouseMovementPolyfillState(event);
6974 return lastMovementX;
6975 },
6976 movementY: function (event) {
6977 if ('movementY' in event) {
6978 return event.movementY;
6979 } // Don't need to call updateMouseMovementPolyfillState() here
6980 // because it's guaranteed to have already run when movementX
6981 // was copied.
6982
6983
6984 return lastMovementY;
6985 }
6986 });
6987
6988 var SyntheticMouseEvent = createSyntheticEvent(MouseEventInterface);
6989 /**
6990 * @interface DragEvent
6991 * @see http://www.w3.org/TR/DOM-Level-3-Events/
6992 */
6993
6994 var DragEventInterface = assign({}, MouseEventInterface, {
6995 dataTransfer: 0
6996 });
6997
6998 var SyntheticDragEvent = createSyntheticEvent(DragEventInterface);
6999 /**
7000 * @interface FocusEvent
7001 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7002 */
7003
7004 var FocusEventInterface = assign({}, UIEventInterface, {
7005 relatedTarget: 0
7006 });
7007
7008 var SyntheticFocusEvent = createSyntheticEvent(FocusEventInterface);
7009 /**
7010 * @interface Event
7011 * @see http://www.w3.org/TR/css3-animations/#AnimationEvent-interface
7012 * @see https://developer.mozilla.org/en-US/docs/Web/API/AnimationEvent
7013 */
7014
7015 var AnimationEventInterface = assign({}, EventInterface, {
7016 animationName: 0,
7017 elapsedTime: 0,
7018 pseudoElement: 0
7019 });
7020
7021 var SyntheticAnimationEvent = createSyntheticEvent(AnimationEventInterface);
7022 /**
7023 * @interface Event
7024 * @see http://www.w3.org/TR/clipboard-apis/
7025 */
7026
7027 var ClipboardEventInterface = assign({}, EventInterface, {
7028 clipboardData: function (event) {
7029 return 'clipboardData' in event ? event.clipboardData : window.clipboardData;
7030 }
7031 });
7032
7033 var SyntheticClipboardEvent = createSyntheticEvent(ClipboardEventInterface);
7034 /**
7035 * @interface Event
7036 * @see http://www.w3.org/TR/DOM-Level-3-Events/#events-compositionevents
7037 */
7038
7039 var CompositionEventInterface = assign({}, EventInterface, {
7040 data: 0
7041 });
7042
7043 var SyntheticCompositionEvent = createSyntheticEvent(CompositionEventInterface);
7044 /**
7045 * @interface Event
7046 * @see http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105
7047 * /#events-inputevents
7048 */
7049 // Happens to share the same list for now.
7050
7051 var SyntheticInputEvent = SyntheticCompositionEvent;
7052 /**
7053 * Normalization of deprecated HTML5 `key` values
7054 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
7055 */
7056
7057 var normalizeKey = {
7058 Esc: 'Escape',
7059 Spacebar: ' ',
7060 Left: 'ArrowLeft',
7061 Up: 'ArrowUp',
7062 Right: 'ArrowRight',
7063 Down: 'ArrowDown',
7064 Del: 'Delete',
7065 Win: 'OS',
7066 Menu: 'ContextMenu',
7067 Apps: 'ContextMenu',
7068 Scroll: 'ScrollLock',
7069 MozPrintableKey: 'Unidentified'
7070 };
7071 /**
7072 * Translation from legacy `keyCode` to HTML5 `key`
7073 * Only special keys supported, all others depend on keyboard layout or browser
7074 * @see https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names
7075 */
7076
7077 var translateToKey = {
7078 '8': 'Backspace',
7079 '9': 'Tab',
7080 '12': 'Clear',
7081 '13': 'Enter',
7082 '16': 'Shift',
7083 '17': 'Control',
7084 '18': 'Alt',
7085 '19': 'Pause',
7086 '20': 'CapsLock',
7087 '27': 'Escape',
7088 '32': ' ',
7089 '33': 'PageUp',
7090 '34': 'PageDown',
7091 '35': 'End',
7092 '36': 'Home',
7093 '37': 'ArrowLeft',
7094 '38': 'ArrowUp',
7095 '39': 'ArrowRight',
7096 '40': 'ArrowDown',
7097 '45': 'Insert',
7098 '46': 'Delete',
7099 '112': 'F1',
7100 '113': 'F2',
7101 '114': 'F3',
7102 '115': 'F4',
7103 '116': 'F5',
7104 '117': 'F6',
7105 '118': 'F7',
7106 '119': 'F8',
7107 '120': 'F9',
7108 '121': 'F10',
7109 '122': 'F11',
7110 '123': 'F12',
7111 '144': 'NumLock',
7112 '145': 'ScrollLock',
7113 '224': 'Meta'
7114 };
7115 /**
7116 * @param {object} nativeEvent Native browser event.
7117 * @return {string} Normalized `key` property.
7118 */
7119
7120 function getEventKey(nativeEvent) {
7121 if (nativeEvent.key) {
7122 // Normalize inconsistent values reported by browsers due to
7123 // implementations of a working draft specification.
7124 // FireFox implements `key` but returns `MozPrintableKey` for all
7125 // printable characters (normalized to `Unidentified`), ignore it.
7126 var key = normalizeKey[nativeEvent.key] || nativeEvent.key;
7127
7128 if (key !== 'Unidentified') {
7129 return key;
7130 }
7131 } // Browser does not implement `key`, polyfill as much of it as we can.
7132
7133
7134 if (nativeEvent.type === 'keypress') {
7135 var charCode = getEventCharCode(nativeEvent); // The enter-key is technically both printable and non-printable and can
7136 // thus be captured by `keypress`, no other non-printable key should.
7137
7138 return charCode === 13 ? 'Enter' : String.fromCharCode(charCode);
7139 }
7140
7141 if (nativeEvent.type === 'keydown' || nativeEvent.type === 'keyup') {
7142 // While user keyboard layout determines the actual meaning of each
7143 // `keyCode` value, almost all function keys have a universal value.
7144 return translateToKey[nativeEvent.keyCode] || 'Unidentified';
7145 }
7146
7147 return '';
7148 }
7149 /**
7150 * Translation from modifier key to the associated property in the event.
7151 * @see http://www.w3.org/TR/DOM-Level-3-Events/#keys-Modifiers
7152 */
7153
7154
7155 var modifierKeyToProp = {
7156 Alt: 'altKey',
7157 Control: 'ctrlKey',
7158 Meta: 'metaKey',
7159 Shift: 'shiftKey'
7160 }; // Older browsers (Safari <= 10, iOS Safari <= 10.2) do not support
7161 // getModifierState. If getModifierState is not supported, we map it to a set of
7162 // modifier keys exposed by the event. In this case, Lock-keys are not supported.
7163
7164 function modifierStateGetter(keyArg) {
7165 var syntheticEvent = this;
7166 var nativeEvent = syntheticEvent.nativeEvent;
7167
7168 if (nativeEvent.getModifierState) {
7169 return nativeEvent.getModifierState(keyArg);
7170 }
7171
7172 var keyProp = modifierKeyToProp[keyArg];
7173 return keyProp ? !!nativeEvent[keyProp] : false;
7174 }
7175
7176 function getEventModifierState(nativeEvent) {
7177 return modifierStateGetter;
7178 }
7179 /**
7180 * @interface KeyboardEvent
7181 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7182 */
7183
7184
7185 var KeyboardEventInterface = assign({}, UIEventInterface, {
7186 key: getEventKey,
7187 code: 0,
7188 location: 0,
7189 ctrlKey: 0,
7190 shiftKey: 0,
7191 altKey: 0,
7192 metaKey: 0,
7193 repeat: 0,
7194 locale: 0,
7195 getModifierState: getEventModifierState,
7196 // Legacy Interface
7197 charCode: function (event) {
7198 // `charCode` is the result of a KeyPress event and represents the value of
7199 // the actual printable character.
7200 // KeyPress is deprecated, but its replacement is not yet final and not
7201 // implemented in any major browser. Only KeyPress has charCode.
7202 if (event.type === 'keypress') {
7203 return getEventCharCode(event);
7204 }
7205
7206 return 0;
7207 },
7208 keyCode: function (event) {
7209 // `keyCode` is the result of a KeyDown/Up event and represents the value of
7210 // physical keyboard key.
7211 // The actual meaning of the value depends on the users' keyboard layout
7212 // which cannot be detected. Assuming that it is a US keyboard layout
7213 // provides a surprisingly accurate mapping for US and European users.
7214 // Due to this, it is left to the user to implement at this time.
7215 if (event.type === 'keydown' || event.type === 'keyup') {
7216 return event.keyCode;
7217 }
7218
7219 return 0;
7220 },
7221 which: function (event) {
7222 // `which` is an alias for either `keyCode` or `charCode` depending on the
7223 // type of the event.
7224 if (event.type === 'keypress') {
7225 return getEventCharCode(event);
7226 }
7227
7228 if (event.type === 'keydown' || event.type === 'keyup') {
7229 return event.keyCode;
7230 }
7231
7232 return 0;
7233 }
7234 });
7235
7236 var SyntheticKeyboardEvent = createSyntheticEvent(KeyboardEventInterface);
7237 /**
7238 * @interface PointerEvent
7239 * @see http://www.w3.org/TR/pointerevents/
7240 */
7241
7242 var PointerEventInterface = assign({}, MouseEventInterface, {
7243 pointerId: 0,
7244 width: 0,
7245 height: 0,
7246 pressure: 0,
7247 tangentialPressure: 0,
7248 tiltX: 0,
7249 tiltY: 0,
7250 twist: 0,
7251 pointerType: 0,
7252 isPrimary: 0
7253 });
7254
7255 var SyntheticPointerEvent = createSyntheticEvent(PointerEventInterface);
7256 /**
7257 * @interface TouchEvent
7258 * @see http://www.w3.org/TR/touch-events/
7259 */
7260
7261 var TouchEventInterface = assign({}, UIEventInterface, {
7262 touches: 0,
7263 targetTouches: 0,
7264 changedTouches: 0,
7265 altKey: 0,
7266 metaKey: 0,
7267 ctrlKey: 0,
7268 shiftKey: 0,
7269 getModifierState: getEventModifierState
7270 });
7271
7272 var SyntheticTouchEvent = createSyntheticEvent(TouchEventInterface);
7273 /**
7274 * @interface Event
7275 * @see http://www.w3.org/TR/2009/WD-css3-transitions-20090320/#transition-events-
7276 * @see https://developer.mozilla.org/en-US/docs/Web/API/TransitionEvent
7277 */
7278
7279 var TransitionEventInterface = assign({}, EventInterface, {
7280 propertyName: 0,
7281 elapsedTime: 0,
7282 pseudoElement: 0
7283 });
7284
7285 var SyntheticTransitionEvent = createSyntheticEvent(TransitionEventInterface);
7286 /**
7287 * @interface WheelEvent
7288 * @see http://www.w3.org/TR/DOM-Level-3-Events/
7289 */
7290
7291 var WheelEventInterface = assign({}, MouseEventInterface, {
7292 deltaX: function (event) {
7293 return 'deltaX' in event ? event.deltaX : // Fallback to `wheelDeltaX` for Webkit and normalize (right is positive).
7294 'wheelDeltaX' in event ? -event.wheelDeltaX : 0;
7295 },
7296 deltaY: function (event) {
7297 return 'deltaY' in event ? event.deltaY : // Fallback to `wheelDeltaY` for Webkit and normalize (down is positive).
7298 'wheelDeltaY' in event ? -event.wheelDeltaY : // Fallback to `wheelDelta` for IE<9 and normalize (down is positive).
7299 'wheelDelta' in event ? -event.wheelDelta : 0;
7300 },
7301 deltaZ: 0,
7302 // Browsers without "deltaMode" is reporting in raw wheel delta where one
7303 // notch on the scroll is always +/- 120, roughly equivalent to pixels.
7304 // A good approximation of DOM_DELTA_LINE (1) is 5% of viewport size or
7305 // ~40 pixels, for DOM_DELTA_SCREEN (2) it is 87.5% of viewport size.
7306 deltaMode: 0
7307 });
7308
7309 var SyntheticWheelEvent = createSyntheticEvent(WheelEventInterface);
7310
7311 var END_KEYCODES = [9, 13, 27, 32]; // Tab, Return, Esc, Space
7312
7313 var START_KEYCODE = 229;
7314 var canUseCompositionEvent = canUseDOM && 'CompositionEvent' in window;
7315 var documentMode = null;
7316
7317 if (canUseDOM && 'documentMode' in document) {
7318 documentMode = document.documentMode;
7319 } // Webkit offers a very useful `textInput` event that can be used to
7320 // directly represent `beforeInput`. The IE `textinput` event is not as
7321 // useful, so we don't use it.
7322
7323
7324 var canUseTextInputEvent = canUseDOM && 'TextEvent' in window && !documentMode; // In IE9+, we have access to composition events, but the data supplied
7325 // by the native compositionend event may be incorrect. Japanese ideographic
7326 // spaces, for instance (\u3000) are not recorded correctly.
7327
7328 var useFallbackCompositionData = canUseDOM && (!canUseCompositionEvent || documentMode && documentMode > 8 && documentMode <= 11);
7329 var SPACEBAR_CODE = 32;
7330 var SPACEBAR_CHAR = String.fromCharCode(SPACEBAR_CODE);
7331
7332 function registerEvents() {
7333 registerTwoPhaseEvent('onBeforeInput', ['compositionend', 'keypress', 'textInput', 'paste']);
7334 registerTwoPhaseEvent('onCompositionEnd', ['compositionend', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7335 registerTwoPhaseEvent('onCompositionStart', ['compositionstart', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7336 registerTwoPhaseEvent('onCompositionUpdate', ['compositionupdate', 'focusout', 'keydown', 'keypress', 'keyup', 'mousedown']);
7337 } // Track whether we've ever handled a keypress on the space key.
7338
7339
7340 var hasSpaceKeypress = false;
7341 /**
7342 * Return whether a native keypress event is assumed to be a command.
7343 * This is required because Firefox fires `keypress` events for key commands
7344 * (cut, copy, select-all, etc.) even though no character is inserted.
7345 */
7346
7347 function isKeypressCommand(nativeEvent) {
7348 return (nativeEvent.ctrlKey || nativeEvent.altKey || nativeEvent.metaKey) && // ctrlKey && altKey is equivalent to AltGr, and is not a command.
7349 !(nativeEvent.ctrlKey && nativeEvent.altKey);
7350 }
7351 /**
7352 * Translate native top level events into event types.
7353 */
7354
7355
7356 function getCompositionEventType(domEventName) {
7357 switch (domEventName) {
7358 case 'compositionstart':
7359 return 'onCompositionStart';
7360
7361 case 'compositionend':
7362 return 'onCompositionEnd';
7363
7364 case 'compositionupdate':
7365 return 'onCompositionUpdate';
7366 }
7367 }
7368 /**
7369 * Does our fallback best-guess model think this event signifies that
7370 * composition has begun?
7371 */
7372
7373
7374 function isFallbackCompositionStart(domEventName, nativeEvent) {
7375 return domEventName === 'keydown' && nativeEvent.keyCode === START_KEYCODE;
7376 }
7377 /**
7378 * Does our fallback mode think that this event is the end of composition?
7379 */
7380
7381
7382 function isFallbackCompositionEnd(domEventName, nativeEvent) {
7383 switch (domEventName) {
7384 case 'keyup':
7385 // Command keys insert or clear IME input.
7386 return END_KEYCODES.indexOf(nativeEvent.keyCode) !== -1;
7387
7388 case 'keydown':
7389 // Expect IME keyCode on each keydown. If we get any other
7390 // code we must have exited earlier.
7391 return nativeEvent.keyCode !== START_KEYCODE;
7392
7393 case 'keypress':
7394 case 'mousedown':
7395 case 'focusout':
7396 // Events are not possible without cancelling IME.
7397 return true;
7398
7399 default:
7400 return false;
7401 }
7402 }
7403 /**
7404 * Google Input Tools provides composition data via a CustomEvent,
7405 * with the `data` property populated in the `detail` object. If this
7406 * is available on the event object, use it. If not, this is a plain
7407 * composition event and we have nothing special to extract.
7408 *
7409 * @param {object} nativeEvent
7410 * @return {?string}
7411 */
7412
7413
7414 function getDataFromCustomEvent(nativeEvent) {
7415 var detail = nativeEvent.detail;
7416
7417 if (typeof detail === 'object' && 'data' in detail) {
7418 return detail.data;
7419 }
7420
7421 return null;
7422 }
7423 /**
7424 * Check if a composition event was triggered by Korean IME.
7425 * Our fallback mode does not work well with IE's Korean IME,
7426 * so just use native composition events when Korean IME is used.
7427 * Although CompositionEvent.locale property is deprecated,
7428 * it is available in IE, where our fallback mode is enabled.
7429 *
7430 * @param {object} nativeEvent
7431 * @return {boolean}
7432 */
7433
7434
7435 function isUsingKoreanIME(nativeEvent) {
7436 return nativeEvent.locale === 'ko';
7437 } // Track the current IME composition status, if any.
7438
7439
7440 var isComposing = false;
7441 /**
7442 * @return {?object} A SyntheticCompositionEvent.
7443 */
7444
7445 function extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
7446 var eventType;
7447 var fallbackData;
7448
7449 if (canUseCompositionEvent) {
7450 eventType = getCompositionEventType(domEventName);
7451 } else if (!isComposing) {
7452 if (isFallbackCompositionStart(domEventName, nativeEvent)) {
7453 eventType = 'onCompositionStart';
7454 }
7455 } else if (isFallbackCompositionEnd(domEventName, nativeEvent)) {
7456 eventType = 'onCompositionEnd';
7457 }
7458
7459 if (!eventType) {
7460 return null;
7461 }
7462
7463 if (useFallbackCompositionData && !isUsingKoreanIME(nativeEvent)) {
7464 // The current composition is stored statically and must not be
7465 // overwritten while composition continues.
7466 if (!isComposing && eventType === 'onCompositionStart') {
7467 isComposing = initialize(nativeEventTarget);
7468 } else if (eventType === 'onCompositionEnd') {
7469 if (isComposing) {
7470 fallbackData = getData();
7471 }
7472 }
7473 }
7474
7475 var listeners = accumulateTwoPhaseListeners(targetInst, eventType);
7476
7477 if (listeners.length > 0) {
7478 var event = new SyntheticCompositionEvent(eventType, domEventName, null, nativeEvent, nativeEventTarget);
7479 dispatchQueue.push({
7480 event: event,
7481 listeners: listeners
7482 });
7483
7484 if (fallbackData) {
7485 // Inject data generated from fallback path into the synthetic event.
7486 // This matches the property of native CompositionEventInterface.
7487 event.data = fallbackData;
7488 } else {
7489 var customData = getDataFromCustomEvent(nativeEvent);
7490
7491 if (customData !== null) {
7492 event.data = customData;
7493 }
7494 }
7495 }
7496 }
7497
7498 function getNativeBeforeInputChars(domEventName, nativeEvent) {
7499 switch (domEventName) {
7500 case 'compositionend':
7501 return getDataFromCustomEvent(nativeEvent);
7502
7503 case 'keypress':
7504 /**
7505 * If native `textInput` events are available, our goal is to make
7506 * use of them. However, there is a special case: the spacebar key.
7507 * In Webkit, preventing default on a spacebar `textInput` event
7508 * cancels character insertion, but it *also* causes the browser
7509 * to fall back to its default spacebar behavior of scrolling the
7510 * page.
7511 *
7512 * Tracking at:
7513 * https://code.google.com/p/chromium/issues/detail?id=355103
7514 *
7515 * To avoid this issue, use the keypress event as if no `textInput`
7516 * event is available.
7517 */
7518 var which = nativeEvent.which;
7519
7520 if (which !== SPACEBAR_CODE) {
7521 return null;
7522 }
7523
7524 hasSpaceKeypress = true;
7525 return SPACEBAR_CHAR;
7526
7527 case 'textInput':
7528 // Record the characters to be added to the DOM.
7529 var chars = nativeEvent.data; // If it's a spacebar character, assume that we have already handled
7530 // it at the keypress level and bail immediately. Android Chrome
7531 // doesn't give us keycodes, so we need to ignore it.
7532
7533 if (chars === SPACEBAR_CHAR && hasSpaceKeypress) {
7534 return null;
7535 }
7536
7537 return chars;
7538
7539 default:
7540 // For other native event types, do nothing.
7541 return null;
7542 }
7543 }
7544 /**
7545 * For browsers that do not provide the `textInput` event, extract the
7546 * appropriate string to use for SyntheticInputEvent.
7547 */
7548
7549
7550 function getFallbackBeforeInputChars(domEventName, nativeEvent) {
7551 // If we are currently composing (IME) and using a fallback to do so,
7552 // try to extract the composed characters from the fallback object.
7553 // If composition event is available, we extract a string only at
7554 // compositionevent, otherwise extract it at fallback events.
7555 if (isComposing) {
7556 if (domEventName === 'compositionend' || !canUseCompositionEvent && isFallbackCompositionEnd(domEventName, nativeEvent)) {
7557 var chars = getData();
7558 reset();
7559 isComposing = false;
7560 return chars;
7561 }
7562
7563 return null;
7564 }
7565
7566 switch (domEventName) {
7567 case 'paste':
7568 // If a paste event occurs after a keypress, throw out the input
7569 // chars. Paste events should not lead to BeforeInput events.
7570 return null;
7571
7572 case 'keypress':
7573 /**
7574 * As of v27, Firefox may fire keypress events even when no character
7575 * will be inserted. A few possibilities:
7576 *
7577 * - `which` is `0`. Arrow keys, Esc key, etc.
7578 *
7579 * - `which` is the pressed key code, but no char is available.
7580 * Ex: 'AltGr + d` in Polish. There is no modified character for
7581 * this key combination and no character is inserted into the
7582 * document, but FF fires the keypress for char code `100` anyway.
7583 * No `input` event will occur.
7584 *
7585 * - `which` is the pressed key code, but a command combination is
7586 * being used. Ex: `Cmd+C`. No character is inserted, and no
7587 * `input` event will occur.
7588 */
7589 if (!isKeypressCommand(nativeEvent)) {
7590 // IE fires the `keypress` event when a user types an emoji via
7591 // Touch keyboard of Windows. In such a case, the `char` property
7592 // holds an emoji character like `\uD83D\uDE0A`. Because its length
7593 // is 2, the property `which` does not represent an emoji correctly.
7594 // In such a case, we directly return the `char` property instead of
7595 // using `which`.
7596 if (nativeEvent.char && nativeEvent.char.length > 1) {
7597 return nativeEvent.char;
7598 } else if (nativeEvent.which) {
7599 return String.fromCharCode(nativeEvent.which);
7600 }
7601 }
7602
7603 return null;
7604
7605 case 'compositionend':
7606 return useFallbackCompositionData && !isUsingKoreanIME(nativeEvent) ? null : nativeEvent.data;
7607
7608 default:
7609 return null;
7610 }
7611 }
7612 /**
7613 * Extract a SyntheticInputEvent for `beforeInput`, based on either native
7614 * `textInput` or fallback behavior.
7615 *
7616 * @return {?object} A SyntheticInputEvent.
7617 */
7618
7619
7620 function extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget) {
7621 var chars;
7622
7623 if (canUseTextInputEvent) {
7624 chars = getNativeBeforeInputChars(domEventName, nativeEvent);
7625 } else {
7626 chars = getFallbackBeforeInputChars(domEventName, nativeEvent);
7627 } // If no characters are being inserted, no BeforeInput event should
7628 // be fired.
7629
7630
7631 if (!chars) {
7632 return null;
7633 }
7634
7635 var listeners = accumulateTwoPhaseListeners(targetInst, 'onBeforeInput');
7636
7637 if (listeners.length > 0) {
7638 var event = new SyntheticInputEvent('onBeforeInput', 'beforeinput', null, nativeEvent, nativeEventTarget);
7639 dispatchQueue.push({
7640 event: event,
7641 listeners: listeners
7642 });
7643 event.data = chars;
7644 }
7645 }
7646 /**
7647 * Create an `onBeforeInput` event to match
7648 * http://www.w3.org/TR/2013/WD-DOM-Level-3-Events-20131105/#events-inputevents.
7649 *
7650 * This event plugin is based on the native `textInput` event
7651 * available in Chrome, Safari, Opera, and IE. This event fires after
7652 * `onKeyPress` and `onCompositionEnd`, but before `onInput`.
7653 *
7654 * `beforeInput` is spec'd but not implemented in any browsers, and
7655 * the `input` event does not provide any useful information about what has
7656 * actually been added, contrary to the spec. Thus, `textInput` is the best
7657 * available event to identify the characters that have actually been inserted
7658 * into the target node.
7659 *
7660 * This plugin is also responsible for emitting `composition` events, thus
7661 * allowing us to share composition fallback code for both `beforeInput` and
7662 * `composition` event types.
7663 */
7664
7665
7666 function extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7667 extractCompositionEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7668 extractBeforeInputEvent(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
7669 }
7670
7671 /**
7672 * @see http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
7673 */
7674 var supportedInputTypes = {
7675 color: true,
7676 date: true,
7677 datetime: true,
7678 'datetime-local': true,
7679 email: true,
7680 month: true,
7681 number: true,
7682 password: true,
7683 range: true,
7684 search: true,
7685 tel: true,
7686 text: true,
7687 time: true,
7688 url: true,
7689 week: true
7690 };
7691
7692 function isTextInputElement(elem) {
7693 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
7694
7695 if (nodeName === 'input') {
7696 return !!supportedInputTypes[elem.type];
7697 }
7698
7699 if (nodeName === 'textarea') {
7700 return true;
7701 }
7702
7703 return false;
7704 }
7705
7706 /**
7707 * Checks if an event is supported in the current execution environment.
7708 *
7709 * NOTE: This will not work correctly for non-generic events such as `change`,
7710 * `reset`, `load`, `error`, and `select`.
7711 *
7712 * Borrows from Modernizr.
7713 *
7714 * @param {string} eventNameSuffix Event name, e.g. "click".
7715 * @return {boolean} True if the event is supported.
7716 * @internal
7717 * @license Modernizr 3.0.0pre (Custom Build) | MIT
7718 */
7719
7720 function isEventSupported(eventNameSuffix) {
7721 if (!canUseDOM) {
7722 return false;
7723 }
7724
7725 var eventName = 'on' + eventNameSuffix;
7726 var isSupported = (eventName in document);
7727
7728 if (!isSupported) {
7729 var element = document.createElement('div');
7730 element.setAttribute(eventName, 'return;');
7731 isSupported = typeof element[eventName] === 'function';
7732 }
7733
7734 return isSupported;
7735 }
7736
7737 function registerEvents$1() {
7738 registerTwoPhaseEvent('onChange', ['change', 'click', 'focusin', 'focusout', 'input', 'keydown', 'keyup', 'selectionchange']);
7739 }
7740
7741 function createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, target) {
7742 // Flag this event loop as needing state restore.
7743 enqueueStateRestore(target);
7744 var listeners = accumulateTwoPhaseListeners(inst, 'onChange');
7745
7746 if (listeners.length > 0) {
7747 var event = new SyntheticEvent('onChange', 'change', null, nativeEvent, target);
7748 dispatchQueue.push({
7749 event: event,
7750 listeners: listeners
7751 });
7752 }
7753 }
7754 /**
7755 * For IE shims
7756 */
7757
7758
7759 var activeElement = null;
7760 var activeElementInst = null;
7761 /**
7762 * SECTION: handle `change` event
7763 */
7764
7765 function shouldUseChangeEvent(elem) {
7766 var nodeName = elem.nodeName && elem.nodeName.toLowerCase();
7767 return nodeName === 'select' || nodeName === 'input' && elem.type === 'file';
7768 }
7769
7770 function manualDispatchChangeEvent(nativeEvent) {
7771 var dispatchQueue = [];
7772 createAndAccumulateChangeEvent(dispatchQueue, activeElementInst, nativeEvent, getEventTarget(nativeEvent)); // If change and propertychange bubbled, we'd just bind to it like all the
7773 // other events and have it go through ReactBrowserEventEmitter. Since it
7774 // doesn't, we manually listen for the events and so we have to enqueue and
7775 // process the abstract event manually.
7776 //
7777 // Batching is necessary here in order to ensure that all event handlers run
7778 // before the next rerender (including event handlers attached to ancestor
7779 // elements instead of directly on the input). Without this, controlled
7780 // components don't work properly in conjunction with event bubbling because
7781 // the component is rerendered and the value reverted before all the event
7782 // handlers can run. See https://github.com/facebook/react/issues/708.
7783
7784 batchedUpdates(runEventInBatch, dispatchQueue);
7785 }
7786
7787 function runEventInBatch(dispatchQueue) {
7788 processDispatchQueue(dispatchQueue, 0);
7789 }
7790
7791 function getInstIfValueChanged(targetInst) {
7792 var targetNode = getNodeFromInstance(targetInst);
7793
7794 if (updateValueIfChanged(targetNode)) {
7795 return targetInst;
7796 }
7797 }
7798
7799 function getTargetInstForChangeEvent(domEventName, targetInst) {
7800 if (domEventName === 'change') {
7801 return targetInst;
7802 }
7803 }
7804 /**
7805 * SECTION: handle `input` event
7806 */
7807
7808
7809 var isInputEventSupported = false;
7810
7811 if (canUseDOM) {
7812 // IE9 claims to support the input event but fails to trigger it when
7813 // deleting text, so we ignore its input events.
7814 isInputEventSupported = isEventSupported('input') && (!document.documentMode || document.documentMode > 9);
7815 }
7816 /**
7817 * (For IE <=9) Starts tracking propertychange events on the passed-in element
7818 * and override the value property so that we can distinguish user events from
7819 * value changes in JS.
7820 */
7821
7822
7823 function startWatchingForValueChange(target, targetInst) {
7824 activeElement = target;
7825 activeElementInst = targetInst;
7826 activeElement.attachEvent('onpropertychange', handlePropertyChange);
7827 }
7828 /**
7829 * (For IE <=9) Removes the event listeners from the currently-tracked element,
7830 * if any exists.
7831 */
7832
7833
7834 function stopWatchingForValueChange() {
7835 if (!activeElement) {
7836 return;
7837 }
7838
7839 activeElement.detachEvent('onpropertychange', handlePropertyChange);
7840 activeElement = null;
7841 activeElementInst = null;
7842 }
7843 /**
7844 * (For IE <=9) Handles a propertychange event, sending a `change` event if
7845 * the value of the active element has changed.
7846 */
7847
7848
7849 function handlePropertyChange(nativeEvent) {
7850 if (nativeEvent.propertyName !== 'value') {
7851 return;
7852 }
7853
7854 if (getInstIfValueChanged(activeElementInst)) {
7855 manualDispatchChangeEvent(nativeEvent);
7856 }
7857 }
7858
7859 function handleEventsForInputEventPolyfill(domEventName, target, targetInst) {
7860 if (domEventName === 'focusin') {
7861 // In IE9, propertychange fires for most input events but is buggy and
7862 // doesn't fire when text is deleted, but conveniently, selectionchange
7863 // appears to fire in all of the remaining cases so we catch those and
7864 // forward the event if the value has changed
7865 // In either case, we don't want to call the event handler if the value
7866 // is changed from JS so we redefine a setter for `.value` that updates
7867 // our activeElementValue variable, allowing us to ignore those changes
7868 //
7869 // stopWatching() should be a noop here but we call it just in case we
7870 // missed a blur event somehow.
7871 stopWatchingForValueChange();
7872 startWatchingForValueChange(target, targetInst);
7873 } else if (domEventName === 'focusout') {
7874 stopWatchingForValueChange();
7875 }
7876 } // For IE8 and IE9.
7877
7878
7879 function getTargetInstForInputEventPolyfill(domEventName, targetInst) {
7880 if (domEventName === 'selectionchange' || domEventName === 'keyup' || domEventName === 'keydown') {
7881 // On the selectionchange event, the target is just document which isn't
7882 // helpful for us so just check activeElement instead.
7883 //
7884 // 99% of the time, keydown and keyup aren't necessary. IE8 fails to fire
7885 // propertychange on the first input event after setting `value` from a
7886 // script and fires only keydown, keypress, keyup. Catching keyup usually
7887 // gets it and catching keydown lets us fire an event for the first
7888 // keystroke if user does a key repeat (it'll be a little delayed: right
7889 // before the second keystroke). Other input methods (e.g., paste) seem to
7890 // fire selectionchange normally.
7891 return getInstIfValueChanged(activeElementInst);
7892 }
7893 }
7894 /**
7895 * SECTION: handle `click` event
7896 */
7897
7898
7899 function shouldUseClickEvent(elem) {
7900 // Use the `click` event to detect changes to checkbox and radio inputs.
7901 // This approach works across all browsers, whereas `change` does not fire
7902 // until `blur` in IE8.
7903 var nodeName = elem.nodeName;
7904 return nodeName && nodeName.toLowerCase() === 'input' && (elem.type === 'checkbox' || elem.type === 'radio');
7905 }
7906
7907 function getTargetInstForClickEvent(domEventName, targetInst) {
7908 if (domEventName === 'click') {
7909 return getInstIfValueChanged(targetInst);
7910 }
7911 }
7912
7913 function getTargetInstForInputOrChangeEvent(domEventName, targetInst) {
7914 if (domEventName === 'input' || domEventName === 'change') {
7915 return getInstIfValueChanged(targetInst);
7916 }
7917 }
7918
7919 function handleControlledInputBlur(node) {
7920 var state = node._wrapperState;
7921
7922 if (!state || !state.controlled || node.type !== 'number') {
7923 return;
7924 }
7925
7926 {
7927 // If controlled, assign the value attribute to the current value on blur
7928 setDefaultValue(node, 'number', node.value);
7929 }
7930 }
7931 /**
7932 * This plugin creates an `onChange` event that normalizes change events
7933 * across form elements. This event fires at a time when it's possible to
7934 * change the element's value without seeing a flicker.
7935 *
7936 * Supported elements are:
7937 * - input (see `isTextInputElement`)
7938 * - textarea
7939 * - select
7940 */
7941
7942
7943 function extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7944 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
7945 var getTargetInstFunc, handleEventFunc;
7946
7947 if (shouldUseChangeEvent(targetNode)) {
7948 getTargetInstFunc = getTargetInstForChangeEvent;
7949 } else if (isTextInputElement(targetNode)) {
7950 if (isInputEventSupported) {
7951 getTargetInstFunc = getTargetInstForInputOrChangeEvent;
7952 } else {
7953 getTargetInstFunc = getTargetInstForInputEventPolyfill;
7954 handleEventFunc = handleEventsForInputEventPolyfill;
7955 }
7956 } else if (shouldUseClickEvent(targetNode)) {
7957 getTargetInstFunc = getTargetInstForClickEvent;
7958 }
7959
7960 if (getTargetInstFunc) {
7961 var inst = getTargetInstFunc(domEventName, targetInst);
7962
7963 if (inst) {
7964 createAndAccumulateChangeEvent(dispatchQueue, inst, nativeEvent, nativeEventTarget);
7965 return;
7966 }
7967 }
7968
7969 if (handleEventFunc) {
7970 handleEventFunc(domEventName, targetNode, targetInst);
7971 } // When blurring, set the value attribute for number inputs
7972
7973
7974 if (domEventName === 'focusout') {
7975 handleControlledInputBlur(targetNode);
7976 }
7977 }
7978
7979 function registerEvents$2() {
7980 registerDirectEvent('onMouseEnter', ['mouseout', 'mouseover']);
7981 registerDirectEvent('onMouseLeave', ['mouseout', 'mouseover']);
7982 registerDirectEvent('onPointerEnter', ['pointerout', 'pointerover']);
7983 registerDirectEvent('onPointerLeave', ['pointerout', 'pointerover']);
7984 }
7985 /**
7986 * For almost every interaction we care about, there will be both a top-level
7987 * `mouseover` and `mouseout` event that occurs. Only use `mouseout` so that
7988 * we do not extract duplicate events. However, moving the mouse into the
7989 * browser from outside will not fire a `mouseout` event. In this case, we use
7990 * the `mouseover` top-level event.
7991 */
7992
7993
7994 function extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
7995 var isOverEvent = domEventName === 'mouseover' || domEventName === 'pointerover';
7996 var isOutEvent = domEventName === 'mouseout' || domEventName === 'pointerout';
7997
7998 if (isOverEvent && !isReplayingEvent(nativeEvent)) {
7999 // If this is an over event with a target, we might have already dispatched
8000 // the event in the out event of the other target. If this is replayed,
8001 // then it's because we couldn't dispatch against this target previously
8002 // so we have to do it now instead.
8003 var related = nativeEvent.relatedTarget || nativeEvent.fromElement;
8004
8005 if (related) {
8006 // If the related node is managed by React, we can assume that we have
8007 // already dispatched the corresponding events during its mouseout.
8008 if (getClosestInstanceFromNode(related) || isContainerMarkedAsRoot(related)) {
8009 return;
8010 }
8011 }
8012 }
8013
8014 if (!isOutEvent && !isOverEvent) {
8015 // Must not be a mouse or pointer in or out - ignoring.
8016 return;
8017 }
8018
8019 var win; // TODO: why is this nullable in the types but we read from it?
8020
8021 if (nativeEventTarget.window === nativeEventTarget) {
8022 // `nativeEventTarget` is probably a window object.
8023 win = nativeEventTarget;
8024 } else {
8025 // TODO: Figure out why `ownerDocument` is sometimes undefined in IE8.
8026 var doc = nativeEventTarget.ownerDocument;
8027
8028 if (doc) {
8029 win = doc.defaultView || doc.parentWindow;
8030 } else {
8031 win = window;
8032 }
8033 }
8034
8035 var from;
8036 var to;
8037
8038 if (isOutEvent) {
8039 var _related = nativeEvent.relatedTarget || nativeEvent.toElement;
8040
8041 from = targetInst;
8042 to = _related ? getClosestInstanceFromNode(_related) : null;
8043
8044 if (to !== null) {
8045 var nearestMounted = getNearestMountedFiber(to);
8046
8047 if (to !== nearestMounted || to.tag !== HostComponent && to.tag !== HostText) {
8048 to = null;
8049 }
8050 }
8051 } else {
8052 // Moving to a node from outside the window.
8053 from = null;
8054 to = targetInst;
8055 }
8056
8057 if (from === to) {
8058 // Nothing pertains to our managed components.
8059 return;
8060 }
8061
8062 var SyntheticEventCtor = SyntheticMouseEvent;
8063 var leaveEventType = 'onMouseLeave';
8064 var enterEventType = 'onMouseEnter';
8065 var eventTypePrefix = 'mouse';
8066
8067 if (domEventName === 'pointerout' || domEventName === 'pointerover') {
8068 SyntheticEventCtor = SyntheticPointerEvent;
8069 leaveEventType = 'onPointerLeave';
8070 enterEventType = 'onPointerEnter';
8071 eventTypePrefix = 'pointer';
8072 }
8073
8074 var fromNode = from == null ? win : getNodeFromInstance(from);
8075 var toNode = to == null ? win : getNodeFromInstance(to);
8076 var leave = new SyntheticEventCtor(leaveEventType, eventTypePrefix + 'leave', from, nativeEvent, nativeEventTarget);
8077 leave.target = fromNode;
8078 leave.relatedTarget = toNode;
8079 var enter = null; // We should only process this nativeEvent if we are processing
8080 // the first ancestor. Next time, we will ignore the event.
8081
8082 var nativeTargetInst = getClosestInstanceFromNode(nativeEventTarget);
8083
8084 if (nativeTargetInst === targetInst) {
8085 var enterEvent = new SyntheticEventCtor(enterEventType, eventTypePrefix + 'enter', to, nativeEvent, nativeEventTarget);
8086 enterEvent.target = toNode;
8087 enterEvent.relatedTarget = fromNode;
8088 enter = enterEvent;
8089 }
8090
8091 accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leave, enter, from, to);
8092 }
8093
8094 /**
8095 * inlined Object.is polyfill to avoid requiring consumers ship their own
8096 * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is
8097 */
8098 function is(x, y) {
8099 return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y // eslint-disable-line no-self-compare
8100 ;
8101 }
8102
8103 var objectIs = typeof Object.is === 'function' ? Object.is : is;
8104
8105 /**
8106 * Performs equality by iterating through keys on an object and returning false
8107 * when any key has values which are not strictly equal between the arguments.
8108 * Returns true when the values of all keys are strictly equal.
8109 */
8110
8111 function shallowEqual(objA, objB) {
8112 if (objectIs(objA, objB)) {
8113 return true;
8114 }
8115
8116 if (typeof objA !== 'object' || objA === null || typeof objB !== 'object' || objB === null) {
8117 return false;
8118 }
8119
8120 var keysA = Object.keys(objA);
8121 var keysB = Object.keys(objB);
8122
8123 if (keysA.length !== keysB.length) {
8124 return false;
8125 } // Test for A's keys different from B.
8126
8127
8128 for (var i = 0; i < keysA.length; i++) {
8129 var currentKey = keysA[i];
8130
8131 if (!hasOwnProperty.call(objB, currentKey) || !objectIs(objA[currentKey], objB[currentKey])) {
8132 return false;
8133 }
8134 }
8135
8136 return true;
8137 }
8138
8139 /**
8140 * Given any node return the first leaf node without children.
8141 *
8142 * @param {DOMElement|DOMTextNode} node
8143 * @return {DOMElement|DOMTextNode}
8144 */
8145
8146 function getLeafNode(node) {
8147 while (node && node.firstChild) {
8148 node = node.firstChild;
8149 }
8150
8151 return node;
8152 }
8153 /**
8154 * Get the next sibling within a container. This will walk up the
8155 * DOM if a node's siblings have been exhausted.
8156 *
8157 * @param {DOMElement|DOMTextNode} node
8158 * @return {?DOMElement|DOMTextNode}
8159 */
8160
8161
8162 function getSiblingNode(node) {
8163 while (node) {
8164 if (node.nextSibling) {
8165 return node.nextSibling;
8166 }
8167
8168 node = node.parentNode;
8169 }
8170 }
8171 /**
8172 * Get object describing the nodes which contain characters at offset.
8173 *
8174 * @param {DOMElement|DOMTextNode} root
8175 * @param {number} offset
8176 * @return {?object}
8177 */
8178
8179
8180 function getNodeForCharacterOffset(root, offset) {
8181 var node = getLeafNode(root);
8182 var nodeStart = 0;
8183 var nodeEnd = 0;
8184
8185 while (node) {
8186 if (node.nodeType === TEXT_NODE) {
8187 nodeEnd = nodeStart + node.textContent.length;
8188
8189 if (nodeStart <= offset && nodeEnd >= offset) {
8190 return {
8191 node: node,
8192 offset: offset - nodeStart
8193 };
8194 }
8195
8196 nodeStart = nodeEnd;
8197 }
8198
8199 node = getLeafNode(getSiblingNode(node));
8200 }
8201 }
8202
8203 /**
8204 * @param {DOMElement} outerNode
8205 * @return {?object}
8206 */
8207
8208 function getOffsets(outerNode) {
8209 var ownerDocument = outerNode.ownerDocument;
8210 var win = ownerDocument && ownerDocument.defaultView || window;
8211 var selection = win.getSelection && win.getSelection();
8212
8213 if (!selection || selection.rangeCount === 0) {
8214 return null;
8215 }
8216
8217 var anchorNode = selection.anchorNode,
8218 anchorOffset = selection.anchorOffset,
8219 focusNode = selection.focusNode,
8220 focusOffset = selection.focusOffset; // In Firefox, anchorNode and focusNode can be "anonymous divs", e.g. the
8221 // up/down buttons on an <input type="number">. Anonymous divs do not seem to
8222 // expose properties, triggering a "Permission denied error" if any of its
8223 // properties are accessed. The only seemingly possible way to avoid erroring
8224 // is to access a property that typically works for non-anonymous divs and
8225 // catch any error that may otherwise arise. See
8226 // https://bugzilla.mozilla.org/show_bug.cgi?id=208427
8227
8228 try {
8229 /* eslint-disable no-unused-expressions */
8230 anchorNode.nodeType;
8231 focusNode.nodeType;
8232 /* eslint-enable no-unused-expressions */
8233 } catch (e) {
8234 return null;
8235 }
8236
8237 return getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset);
8238 }
8239 /**
8240 * Returns {start, end} where `start` is the character/codepoint index of
8241 * (anchorNode, anchorOffset) within the textContent of `outerNode`, and
8242 * `end` is the index of (focusNode, focusOffset).
8243 *
8244 * Returns null if you pass in garbage input but we should probably just crash.
8245 *
8246 * Exported only for testing.
8247 */
8248
8249 function getModernOffsetsFromPoints(outerNode, anchorNode, anchorOffset, focusNode, focusOffset) {
8250 var length = 0;
8251 var start = -1;
8252 var end = -1;
8253 var indexWithinAnchor = 0;
8254 var indexWithinFocus = 0;
8255 var node = outerNode;
8256 var parentNode = null;
8257
8258 outer: while (true) {
8259 var next = null;
8260
8261 while (true) {
8262 if (node === anchorNode && (anchorOffset === 0 || node.nodeType === TEXT_NODE)) {
8263 start = length + anchorOffset;
8264 }
8265
8266 if (node === focusNode && (focusOffset === 0 || node.nodeType === TEXT_NODE)) {
8267 end = length + focusOffset;
8268 }
8269
8270 if (node.nodeType === TEXT_NODE) {
8271 length += node.nodeValue.length;
8272 }
8273
8274 if ((next = node.firstChild) === null) {
8275 break;
8276 } // Moving from `node` to its first child `next`.
8277
8278
8279 parentNode = node;
8280 node = next;
8281 }
8282
8283 while (true) {
8284 if (node === outerNode) {
8285 // If `outerNode` has children, this is always the second time visiting
8286 // it. If it has no children, this is still the first loop, and the only
8287 // valid selection is anchorNode and focusNode both equal to this node
8288 // and both offsets 0, in which case we will have handled above.
8289 break outer;
8290 }
8291
8292 if (parentNode === anchorNode && ++indexWithinAnchor === anchorOffset) {
8293 start = length;
8294 }
8295
8296 if (parentNode === focusNode && ++indexWithinFocus === focusOffset) {
8297 end = length;
8298 }
8299
8300 if ((next = node.nextSibling) !== null) {
8301 break;
8302 }
8303
8304 node = parentNode;
8305 parentNode = node.parentNode;
8306 } // Moving from `node` to its next sibling `next`.
8307
8308
8309 node = next;
8310 }
8311
8312 if (start === -1 || end === -1) {
8313 // This should never happen. (Would happen if the anchor/focus nodes aren't
8314 // actually inside the passed-in node.)
8315 return null;
8316 }
8317
8318 return {
8319 start: start,
8320 end: end
8321 };
8322 }
8323 /**
8324 * In modern non-IE browsers, we can support both forward and backward
8325 * selections.
8326 *
8327 * Note: IE10+ supports the Selection object, but it does not support
8328 * the `extend` method, which means that even in modern IE, it's not possible
8329 * to programmatically create a backward selection. Thus, for all IE
8330 * versions, we use the old IE API to create our selections.
8331 *
8332 * @param {DOMElement|DOMTextNode} node
8333 * @param {object} offsets
8334 */
8335
8336 function setOffsets(node, offsets) {
8337 var doc = node.ownerDocument || document;
8338 var win = doc && doc.defaultView || window; // Edge fails with "Object expected" in some scenarios.
8339 // (For instance: TinyMCE editor used in a list component that supports pasting to add more,
8340 // fails when pasting 100+ items)
8341
8342 if (!win.getSelection) {
8343 return;
8344 }
8345
8346 var selection = win.getSelection();
8347 var length = node.textContent.length;
8348 var start = Math.min(offsets.start, length);
8349 var end = offsets.end === undefined ? start : Math.min(offsets.end, length); // IE 11 uses modern selection, but doesn't support the extend method.
8350 // Flip backward selections, so we can set with a single range.
8351
8352 if (!selection.extend && start > end) {
8353 var temp = end;
8354 end = start;
8355 start = temp;
8356 }
8357
8358 var startMarker = getNodeForCharacterOffset(node, start);
8359 var endMarker = getNodeForCharacterOffset(node, end);
8360
8361 if (startMarker && endMarker) {
8362 if (selection.rangeCount === 1 && selection.anchorNode === startMarker.node && selection.anchorOffset === startMarker.offset && selection.focusNode === endMarker.node && selection.focusOffset === endMarker.offset) {
8363 return;
8364 }
8365
8366 var range = doc.createRange();
8367 range.setStart(startMarker.node, startMarker.offset);
8368 selection.removeAllRanges();
8369
8370 if (start > end) {
8371 selection.addRange(range);
8372 selection.extend(endMarker.node, endMarker.offset);
8373 } else {
8374 range.setEnd(endMarker.node, endMarker.offset);
8375 selection.addRange(range);
8376 }
8377 }
8378 }
8379
8380 function isTextNode(node) {
8381 return node && node.nodeType === TEXT_NODE;
8382 }
8383
8384 function containsNode(outerNode, innerNode) {
8385 if (!outerNode || !innerNode) {
8386 return false;
8387 } else if (outerNode === innerNode) {
8388 return true;
8389 } else if (isTextNode(outerNode)) {
8390 return false;
8391 } else if (isTextNode(innerNode)) {
8392 return containsNode(outerNode, innerNode.parentNode);
8393 } else if ('contains' in outerNode) {
8394 return outerNode.contains(innerNode);
8395 } else if (outerNode.compareDocumentPosition) {
8396 return !!(outerNode.compareDocumentPosition(innerNode) & 16);
8397 } else {
8398 return false;
8399 }
8400 }
8401
8402 function isInDocument(node) {
8403 return node && node.ownerDocument && containsNode(node.ownerDocument.documentElement, node);
8404 }
8405
8406 function isSameOriginFrame(iframe) {
8407 try {
8408 // Accessing the contentDocument of a HTMLIframeElement can cause the browser
8409 // to throw, e.g. if it has a cross-origin src attribute.
8410 // Safari will show an error in the console when the access results in "Blocked a frame with origin". e.g:
8411 // iframe.contentDocument.defaultView;
8412 // A safety way is to access one of the cross origin properties: Window or Location
8413 // Which might result in "SecurityError" DOM Exception and it is compatible to Safari.
8414 // https://html.spec.whatwg.org/multipage/browsers.html#integration-with-idl
8415 return typeof iframe.contentWindow.location.href === 'string';
8416 } catch (err) {
8417 return false;
8418 }
8419 }
8420
8421 function getActiveElementDeep() {
8422 var win = window;
8423 var element = getActiveElement();
8424
8425 while (element instanceof win.HTMLIFrameElement) {
8426 if (isSameOriginFrame(element)) {
8427 win = element.contentWindow;
8428 } else {
8429 return element;
8430 }
8431
8432 element = getActiveElement(win.document);
8433 }
8434
8435 return element;
8436 }
8437 /**
8438 * @ReactInputSelection: React input selection module. Based on Selection.js,
8439 * but modified to be suitable for react and has a couple of bug fixes (doesn't
8440 * assume buttons have range selections allowed).
8441 * Input selection module for React.
8442 */
8443
8444 /**
8445 * @hasSelectionCapabilities: we get the element types that support selection
8446 * from https://html.spec.whatwg.org/#do-not-apply, looking at `selectionStart`
8447 * and `selectionEnd` rows.
8448 */
8449
8450
8451 function hasSelectionCapabilities(elem) {
8452 var nodeName = elem && elem.nodeName && elem.nodeName.toLowerCase();
8453 return nodeName && (nodeName === 'input' && (elem.type === 'text' || elem.type === 'search' || elem.type === 'tel' || elem.type === 'url' || elem.type === 'password') || nodeName === 'textarea' || elem.contentEditable === 'true');
8454 }
8455 function getSelectionInformation() {
8456 var focusedElem = getActiveElementDeep();
8457 return {
8458 focusedElem: focusedElem,
8459 selectionRange: hasSelectionCapabilities(focusedElem) ? getSelection(focusedElem) : null
8460 };
8461 }
8462 /**
8463 * @restoreSelection: If any selection information was potentially lost,
8464 * restore it. This is useful when performing operations that could remove dom
8465 * nodes and place them back in, resulting in focus being lost.
8466 */
8467
8468 function restoreSelection(priorSelectionInformation) {
8469 var curFocusedElem = getActiveElementDeep();
8470 var priorFocusedElem = priorSelectionInformation.focusedElem;
8471 var priorSelectionRange = priorSelectionInformation.selectionRange;
8472
8473 if (curFocusedElem !== priorFocusedElem && isInDocument(priorFocusedElem)) {
8474 if (priorSelectionRange !== null && hasSelectionCapabilities(priorFocusedElem)) {
8475 setSelection(priorFocusedElem, priorSelectionRange);
8476 } // Focusing a node can change the scroll position, which is undesirable
8477
8478
8479 var ancestors = [];
8480 var ancestor = priorFocusedElem;
8481
8482 while (ancestor = ancestor.parentNode) {
8483 if (ancestor.nodeType === ELEMENT_NODE) {
8484 ancestors.push({
8485 element: ancestor,
8486 left: ancestor.scrollLeft,
8487 top: ancestor.scrollTop
8488 });
8489 }
8490 }
8491
8492 if (typeof priorFocusedElem.focus === 'function') {
8493 priorFocusedElem.focus();
8494 }
8495
8496 for (var i = 0; i < ancestors.length; i++) {
8497 var info = ancestors[i];
8498 info.element.scrollLeft = info.left;
8499 info.element.scrollTop = info.top;
8500 }
8501 }
8502 }
8503 /**
8504 * @getSelection: Gets the selection bounds of a focused textarea, input or
8505 * contentEditable node.
8506 * -@input: Look up selection bounds of this input
8507 * -@return {start: selectionStart, end: selectionEnd}
8508 */
8509
8510 function getSelection(input) {
8511 var selection;
8512
8513 if ('selectionStart' in input) {
8514 // Modern browser with input or textarea.
8515 selection = {
8516 start: input.selectionStart,
8517 end: input.selectionEnd
8518 };
8519 } else {
8520 // Content editable or old IE textarea.
8521 selection = getOffsets(input);
8522 }
8523
8524 return selection || {
8525 start: 0,
8526 end: 0
8527 };
8528 }
8529 /**
8530 * @setSelection: Sets the selection bounds of a textarea or input and focuses
8531 * the input.
8532 * -@input Set selection bounds of this input or textarea
8533 * -@offsets Object of same form that is returned from get*
8534 */
8535
8536 function setSelection(input, offsets) {
8537 var start = offsets.start;
8538 var end = offsets.end;
8539
8540 if (end === undefined) {
8541 end = start;
8542 }
8543
8544 if ('selectionStart' in input) {
8545 input.selectionStart = start;
8546 input.selectionEnd = Math.min(end, input.value.length);
8547 } else {
8548 setOffsets(input, offsets);
8549 }
8550 }
8551
8552 var skipSelectionChangeEvent = canUseDOM && 'documentMode' in document && document.documentMode <= 11;
8553
8554 function registerEvents$3() {
8555 registerTwoPhaseEvent('onSelect', ['focusout', 'contextmenu', 'dragend', 'focusin', 'keydown', 'keyup', 'mousedown', 'mouseup', 'selectionchange']);
8556 }
8557
8558 var activeElement$1 = null;
8559 var activeElementInst$1 = null;
8560 var lastSelection = null;
8561 var mouseDown = false;
8562 /**
8563 * Get an object which is a unique representation of the current selection.
8564 *
8565 * The return value will not be consistent across nodes or browsers, but
8566 * two identical selections on the same node will return identical objects.
8567 */
8568
8569 function getSelection$1(node) {
8570 if ('selectionStart' in node && hasSelectionCapabilities(node)) {
8571 return {
8572 start: node.selectionStart,
8573 end: node.selectionEnd
8574 };
8575 } else {
8576 var win = node.ownerDocument && node.ownerDocument.defaultView || window;
8577 var selection = win.getSelection();
8578 return {
8579 anchorNode: selection.anchorNode,
8580 anchorOffset: selection.anchorOffset,
8581 focusNode: selection.focusNode,
8582 focusOffset: selection.focusOffset
8583 };
8584 }
8585 }
8586 /**
8587 * Get document associated with the event target.
8588 */
8589
8590
8591 function getEventTargetDocument(eventTarget) {
8592 return eventTarget.window === eventTarget ? eventTarget.document : eventTarget.nodeType === DOCUMENT_NODE ? eventTarget : eventTarget.ownerDocument;
8593 }
8594 /**
8595 * Poll selection to see whether it's changed.
8596 *
8597 * @param {object} nativeEvent
8598 * @param {object} nativeEventTarget
8599 * @return {?SyntheticEvent}
8600 */
8601
8602
8603 function constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget) {
8604 // Ensure we have the right element, and that the user is not dragging a
8605 // selection (this matches native `select` event behavior). In HTML5, select
8606 // fires only on input and textarea thus if there's no focused element we
8607 // won't dispatch.
8608 var doc = getEventTargetDocument(nativeEventTarget);
8609
8610 if (mouseDown || activeElement$1 == null || activeElement$1 !== getActiveElement(doc)) {
8611 return;
8612 } // Only fire when selection has actually changed.
8613
8614
8615 var currentSelection = getSelection$1(activeElement$1);
8616
8617 if (!lastSelection || !shallowEqual(lastSelection, currentSelection)) {
8618 lastSelection = currentSelection;
8619 var listeners = accumulateTwoPhaseListeners(activeElementInst$1, 'onSelect');
8620
8621 if (listeners.length > 0) {
8622 var event = new SyntheticEvent('onSelect', 'select', null, nativeEvent, nativeEventTarget);
8623 dispatchQueue.push({
8624 event: event,
8625 listeners: listeners
8626 });
8627 event.target = activeElement$1;
8628 }
8629 }
8630 }
8631 /**
8632 * This plugin creates an `onSelect` event that normalizes select events
8633 * across form elements.
8634 *
8635 * Supported elements are:
8636 * - input (see `isTextInputElement`)
8637 * - textarea
8638 * - contentEditable
8639 *
8640 * This differs from native browser implementations in the following ways:
8641 * - Fires on contentEditable fields as well as inputs.
8642 * - Fires for collapsed selection.
8643 * - Fires after user input.
8644 */
8645
8646
8647 function extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8648 var targetNode = targetInst ? getNodeFromInstance(targetInst) : window;
8649
8650 switch (domEventName) {
8651 // Track the input node that has focus.
8652 case 'focusin':
8653 if (isTextInputElement(targetNode) || targetNode.contentEditable === 'true') {
8654 activeElement$1 = targetNode;
8655 activeElementInst$1 = targetInst;
8656 lastSelection = null;
8657 }
8658
8659 break;
8660
8661 case 'focusout':
8662 activeElement$1 = null;
8663 activeElementInst$1 = null;
8664 lastSelection = null;
8665 break;
8666 // Don't fire the event while the user is dragging. This matches the
8667 // semantics of the native select event.
8668
8669 case 'mousedown':
8670 mouseDown = true;
8671 break;
8672
8673 case 'contextmenu':
8674 case 'mouseup':
8675 case 'dragend':
8676 mouseDown = false;
8677 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8678 break;
8679 // Chrome and IE fire non-standard event when selection is changed (and
8680 // sometimes when it hasn't). IE's event fires out of order with respect
8681 // to key and input events on deletion, so we discard it.
8682 //
8683 // Firefox doesn't support selectionchange, so check selection status
8684 // after each key entry. The selection changes after keydown and before
8685 // keyup, but we check on keydown as well in the case of holding down a
8686 // key, when multiple keydown events are fired but only one keyup is.
8687 // This is also our approach for IE handling, for the reason above.
8688
8689 case 'selectionchange':
8690 if (skipSelectionChangeEvent) {
8691 break;
8692 }
8693
8694 // falls through
8695
8696 case 'keydown':
8697 case 'keyup':
8698 constructSelectEvent(dispatchQueue, nativeEvent, nativeEventTarget);
8699 }
8700 }
8701
8702 /**
8703 * Generate a mapping of standard vendor prefixes using the defined style property and event name.
8704 *
8705 * @param {string} styleProp
8706 * @param {string} eventName
8707 * @returns {object}
8708 */
8709
8710 function makePrefixMap(styleProp, eventName) {
8711 var prefixes = {};
8712 prefixes[styleProp.toLowerCase()] = eventName.toLowerCase();
8713 prefixes['Webkit' + styleProp] = 'webkit' + eventName;
8714 prefixes['Moz' + styleProp] = 'moz' + eventName;
8715 return prefixes;
8716 }
8717 /**
8718 * A list of event names to a configurable list of vendor prefixes.
8719 */
8720
8721
8722 var vendorPrefixes = {
8723 animationend: makePrefixMap('Animation', 'AnimationEnd'),
8724 animationiteration: makePrefixMap('Animation', 'AnimationIteration'),
8725 animationstart: makePrefixMap('Animation', 'AnimationStart'),
8726 transitionend: makePrefixMap('Transition', 'TransitionEnd')
8727 };
8728 /**
8729 * Event names that have already been detected and prefixed (if applicable).
8730 */
8731
8732 var prefixedEventNames = {};
8733 /**
8734 * Element to check for prefixes on.
8735 */
8736
8737 var style = {};
8738 /**
8739 * Bootstrap if a DOM exists.
8740 */
8741
8742 if (canUseDOM) {
8743 style = document.createElement('div').style; // On some platforms, in particular some releases of Android 4.x,
8744 // the un-prefixed "animation" and "transition" properties are defined on the
8745 // style object but the events that fire will still be prefixed, so we need
8746 // to check if the un-prefixed events are usable, and if not remove them from the map.
8747
8748 if (!('AnimationEvent' in window)) {
8749 delete vendorPrefixes.animationend.animation;
8750 delete vendorPrefixes.animationiteration.animation;
8751 delete vendorPrefixes.animationstart.animation;
8752 } // Same as above
8753
8754
8755 if (!('TransitionEvent' in window)) {
8756 delete vendorPrefixes.transitionend.transition;
8757 }
8758 }
8759 /**
8760 * Attempts to determine the correct vendor prefixed event name.
8761 *
8762 * @param {string} eventName
8763 * @returns {string}
8764 */
8765
8766
8767 function getVendorPrefixedEventName(eventName) {
8768 if (prefixedEventNames[eventName]) {
8769 return prefixedEventNames[eventName];
8770 } else if (!vendorPrefixes[eventName]) {
8771 return eventName;
8772 }
8773
8774 var prefixMap = vendorPrefixes[eventName];
8775
8776 for (var styleProp in prefixMap) {
8777 if (prefixMap.hasOwnProperty(styleProp) && styleProp in style) {
8778 return prefixedEventNames[eventName] = prefixMap[styleProp];
8779 }
8780 }
8781
8782 return eventName;
8783 }
8784
8785 var ANIMATION_END = getVendorPrefixedEventName('animationend');
8786 var ANIMATION_ITERATION = getVendorPrefixedEventName('animationiteration');
8787 var ANIMATION_START = getVendorPrefixedEventName('animationstart');
8788 var TRANSITION_END = getVendorPrefixedEventName('transitionend');
8789
8790 var topLevelEventsToReactNames = new Map(); // NOTE: Capitalization is important in this list!
8791 //
8792 // E.g. it needs "pointerDown", not "pointerdown".
8793 // This is because we derive both React name ("onPointerDown")
8794 // and DOM name ("pointerdown") from the same list.
8795 //
8796 // Exceptions that don't match this convention are listed separately.
8797 //
8798 // prettier-ignore
8799
8800 var 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'];
8801
8802 function registerSimpleEvent(domEventName, reactName) {
8803 topLevelEventsToReactNames.set(domEventName, reactName);
8804 registerTwoPhaseEvent(reactName, [domEventName]);
8805 }
8806
8807 function registerSimpleEvents() {
8808 for (var i = 0; i < simpleEventPluginEvents.length; i++) {
8809 var eventName = simpleEventPluginEvents[i];
8810 var domEventName = eventName.toLowerCase();
8811 var capitalizedEvent = eventName[0].toUpperCase() + eventName.slice(1);
8812 registerSimpleEvent(domEventName, 'on' + capitalizedEvent);
8813 } // Special cases where event names don't match.
8814
8815
8816 registerSimpleEvent(ANIMATION_END, 'onAnimationEnd');
8817 registerSimpleEvent(ANIMATION_ITERATION, 'onAnimationIteration');
8818 registerSimpleEvent(ANIMATION_START, 'onAnimationStart');
8819 registerSimpleEvent('dblclick', 'onDoubleClick');
8820 registerSimpleEvent('focusin', 'onFocus');
8821 registerSimpleEvent('focusout', 'onBlur');
8822 registerSimpleEvent(TRANSITION_END, 'onTransitionEnd');
8823 }
8824
8825 function extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8826 var reactName = topLevelEventsToReactNames.get(domEventName);
8827
8828 if (reactName === undefined) {
8829 return;
8830 }
8831
8832 var SyntheticEventCtor = SyntheticEvent;
8833 var reactEventType = domEventName;
8834
8835 switch (domEventName) {
8836 case 'keypress':
8837 // Firefox creates a keypress event for function keys too. This removes
8838 // the unwanted keypress events. Enter is however both printable and
8839 // non-printable. One would expect Tab to be as well (but it isn't).
8840 if (getEventCharCode(nativeEvent) === 0) {
8841 return;
8842 }
8843
8844 /* falls through */
8845
8846 case 'keydown':
8847 case 'keyup':
8848 SyntheticEventCtor = SyntheticKeyboardEvent;
8849 break;
8850
8851 case 'focusin':
8852 reactEventType = 'focus';
8853 SyntheticEventCtor = SyntheticFocusEvent;
8854 break;
8855
8856 case 'focusout':
8857 reactEventType = 'blur';
8858 SyntheticEventCtor = SyntheticFocusEvent;
8859 break;
8860
8861 case 'beforeblur':
8862 case 'afterblur':
8863 SyntheticEventCtor = SyntheticFocusEvent;
8864 break;
8865
8866 case 'click':
8867 // Firefox creates a click event on right mouse clicks. This removes the
8868 // unwanted click events.
8869 if (nativeEvent.button === 2) {
8870 return;
8871 }
8872
8873 /* falls through */
8874
8875 case 'auxclick':
8876 case 'dblclick':
8877 case 'mousedown':
8878 case 'mousemove':
8879 case 'mouseup': // TODO: Disabled elements should not respond to mouse events
8880
8881 /* falls through */
8882
8883 case 'mouseout':
8884 case 'mouseover':
8885 case 'contextmenu':
8886 SyntheticEventCtor = SyntheticMouseEvent;
8887 break;
8888
8889 case 'drag':
8890 case 'dragend':
8891 case 'dragenter':
8892 case 'dragexit':
8893 case 'dragleave':
8894 case 'dragover':
8895 case 'dragstart':
8896 case 'drop':
8897 SyntheticEventCtor = SyntheticDragEvent;
8898 break;
8899
8900 case 'touchcancel':
8901 case 'touchend':
8902 case 'touchmove':
8903 case 'touchstart':
8904 SyntheticEventCtor = SyntheticTouchEvent;
8905 break;
8906
8907 case ANIMATION_END:
8908 case ANIMATION_ITERATION:
8909 case ANIMATION_START:
8910 SyntheticEventCtor = SyntheticAnimationEvent;
8911 break;
8912
8913 case TRANSITION_END:
8914 SyntheticEventCtor = SyntheticTransitionEvent;
8915 break;
8916
8917 case 'scroll':
8918 SyntheticEventCtor = SyntheticUIEvent;
8919 break;
8920
8921 case 'wheel':
8922 SyntheticEventCtor = SyntheticWheelEvent;
8923 break;
8924
8925 case 'copy':
8926 case 'cut':
8927 case 'paste':
8928 SyntheticEventCtor = SyntheticClipboardEvent;
8929 break;
8930
8931 case 'gotpointercapture':
8932 case 'lostpointercapture':
8933 case 'pointercancel':
8934 case 'pointerdown':
8935 case 'pointermove':
8936 case 'pointerout':
8937 case 'pointerover':
8938 case 'pointerup':
8939 SyntheticEventCtor = SyntheticPointerEvent;
8940 break;
8941 }
8942
8943 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
8944
8945 {
8946 // Some events don't bubble in the browser.
8947 // In the past, React has always bubbled them, but this can be surprising.
8948 // We're going to try aligning closer to the browser behavior by not bubbling
8949 // them in React either. We'll start by not bubbling onScroll, and then expand.
8950 var accumulateTargetOnly = !inCapturePhase && // TODO: ideally, we'd eventually add all events from
8951 // nonDelegatedEvents list in DOMPluginEventSystem.
8952 // Then we can remove this special list.
8953 // This is a breaking change that can wait until React 18.
8954 domEventName === 'scroll';
8955
8956 var _listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, inCapturePhase, accumulateTargetOnly);
8957
8958 if (_listeners.length > 0) {
8959 // Intentionally create event lazily.
8960 var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
8961
8962 dispatchQueue.push({
8963 event: _event,
8964 listeners: _listeners
8965 });
8966 }
8967 }
8968 }
8969
8970 // TODO: remove top-level side effect.
8971 registerSimpleEvents();
8972 registerEvents$2();
8973 registerEvents$1();
8974 registerEvents$3();
8975 registerEvents();
8976
8977 function extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags, targetContainer) {
8978 // TODO: we should remove the concept of a "SimpleEventPlugin".
8979 // This is the basic functionality of the event system. All
8980 // the other plugins are essentially polyfills. So the plugin
8981 // should probably be inlined somewhere and have its logic
8982 // be core the to event system. This would potentially allow
8983 // us to ship builds of React without the polyfilled plugins below.
8984 extractEvents$4(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
8985 var shouldProcessPolyfillPlugins = (eventSystemFlags & SHOULD_NOT_PROCESS_POLYFILL_EVENT_PLUGINS) === 0; // We don't process these events unless we are in the
8986 // event's native "bubble" phase, which means that we're
8987 // not in the capture phase. That's because we emulate
8988 // the capture phase here still. This is a trade-off,
8989 // because in an ideal world we would not emulate and use
8990 // the phases properly, like we do with the SimpleEvent
8991 // plugin. However, the plugins below either expect
8992 // emulation (EnterLeave) or use state localized to that
8993 // plugin (BeforeInput, Change, Select). The state in
8994 // these modules complicates things, as you'll essentially
8995 // get the case where the capture phase event might change
8996 // state, only for the following bubble event to come in
8997 // later and not trigger anything as the state now
8998 // invalidates the heuristics of the event plugin. We
8999 // could alter all these plugins to work in such ways, but
9000 // that might cause other unknown side-effects that we
9001 // can't foresee right now.
9002
9003 if (shouldProcessPolyfillPlugins) {
9004 extractEvents$2(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9005 extractEvents$1(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9006 extractEvents$3(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9007 extractEvents(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget);
9008 }
9009 } // List of events that need to be individually attached to media elements.
9010
9011
9012 var 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
9013 // set them on the actual target element itself. This is primarily
9014 // because these events do not consistently bubble in the DOM.
9015
9016 var nonDelegatedEvents = new Set(['cancel', 'close', 'invalid', 'load', 'scroll', 'toggle'].concat(mediaEventTypes));
9017
9018 function executeDispatch(event, listener, currentTarget) {
9019 var type = event.type || 'unknown-event';
9020 event.currentTarget = currentTarget;
9021 invokeGuardedCallbackAndCatchFirstError(type, listener, undefined, event);
9022 event.currentTarget = null;
9023 }
9024
9025 function processDispatchQueueItemsInOrder(event, dispatchListeners, inCapturePhase) {
9026 var previousInstance;
9027
9028 if (inCapturePhase) {
9029 for (var i = dispatchListeners.length - 1; i >= 0; i--) {
9030 var _dispatchListeners$i = dispatchListeners[i],
9031 instance = _dispatchListeners$i.instance,
9032 currentTarget = _dispatchListeners$i.currentTarget,
9033 listener = _dispatchListeners$i.listener;
9034
9035 if (instance !== previousInstance && event.isPropagationStopped()) {
9036 return;
9037 }
9038
9039 executeDispatch(event, listener, currentTarget);
9040 previousInstance = instance;
9041 }
9042 } else {
9043 for (var _i = 0; _i < dispatchListeners.length; _i++) {
9044 var _dispatchListeners$_i = dispatchListeners[_i],
9045 _instance = _dispatchListeners$_i.instance,
9046 _currentTarget = _dispatchListeners$_i.currentTarget,
9047 _listener = _dispatchListeners$_i.listener;
9048
9049 if (_instance !== previousInstance && event.isPropagationStopped()) {
9050 return;
9051 }
9052
9053 executeDispatch(event, _listener, _currentTarget);
9054 previousInstance = _instance;
9055 }
9056 }
9057 }
9058
9059 function processDispatchQueue(dispatchQueue, eventSystemFlags) {
9060 var inCapturePhase = (eventSystemFlags & IS_CAPTURE_PHASE) !== 0;
9061
9062 for (var i = 0; i < dispatchQueue.length; i++) {
9063 var _dispatchQueue$i = dispatchQueue[i],
9064 event = _dispatchQueue$i.event,
9065 listeners = _dispatchQueue$i.listeners;
9066 processDispatchQueueItemsInOrder(event, listeners, inCapturePhase); // event system doesn't use pooling.
9067 } // This would be a good time to rethrow if any of the event handlers threw.
9068
9069
9070 rethrowCaughtError();
9071 }
9072
9073 function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
9074 var nativeEventTarget = getEventTarget(nativeEvent);
9075 var dispatchQueue = [];
9076 extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);
9077 processDispatchQueue(dispatchQueue, eventSystemFlags);
9078 }
9079
9080 function listenToNonDelegatedEvent(domEventName, targetElement) {
9081 {
9082 if (!nonDelegatedEvents.has(domEventName)) {
9083 error('Did not expect a listenToNonDelegatedEvent() call for "%s". ' + 'This is a bug in React. Please file an issue.', domEventName);
9084 }
9085 }
9086
9087 var isCapturePhaseListener = false;
9088 var listenerSet = getEventListenerSet(targetElement);
9089 var listenerSetKey = getListenerSetKey(domEventName, isCapturePhaseListener);
9090
9091 if (!listenerSet.has(listenerSetKey)) {
9092 addTrappedEventListener(targetElement, domEventName, IS_NON_DELEGATED, isCapturePhaseListener);
9093 listenerSet.add(listenerSetKey);
9094 }
9095 }
9096 function listenToNativeEvent(domEventName, isCapturePhaseListener, target) {
9097 {
9098 if (nonDelegatedEvents.has(domEventName) && !isCapturePhaseListener) {
9099 error('Did not expect a listenToNativeEvent() call for "%s" in the bubble phase. ' + 'This is a bug in React. Please file an issue.', domEventName);
9100 }
9101 }
9102
9103 var eventSystemFlags = 0;
9104
9105 if (isCapturePhaseListener) {
9106 eventSystemFlags |= IS_CAPTURE_PHASE;
9107 }
9108
9109 addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener);
9110 } // This is only used by createEventHandle when the
9111 var listeningMarker = '_reactListening' + Math.random().toString(36).slice(2);
9112 function listenToAllSupportedEvents(rootContainerElement) {
9113 if (!rootContainerElement[listeningMarker]) {
9114 rootContainerElement[listeningMarker] = true;
9115 allNativeEvents.forEach(function (domEventName) {
9116 // We handle selectionchange separately because it
9117 // doesn't bubble and needs to be on the document.
9118 if (domEventName !== 'selectionchange') {
9119 if (!nonDelegatedEvents.has(domEventName)) {
9120 listenToNativeEvent(domEventName, false, rootContainerElement);
9121 }
9122
9123 listenToNativeEvent(domEventName, true, rootContainerElement);
9124 }
9125 });
9126 var ownerDocument = rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
9127
9128 if (ownerDocument !== null) {
9129 // The selectionchange event also needs deduplication
9130 // but it is attached to the document.
9131 if (!ownerDocument[listeningMarker]) {
9132 ownerDocument[listeningMarker] = true;
9133 listenToNativeEvent('selectionchange', false, ownerDocument);
9134 }
9135 }
9136 }
9137 }
9138
9139 function addTrappedEventListener(targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener, isDeferredListenerForLegacyFBSupport) {
9140 var listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags); // If passive option is not supported, then the event will be
9141 // active and not passive.
9142
9143 var isPassiveListener = undefined;
9144
9145 if (passiveBrowserEventsSupported) {
9146 // Browsers introduced an intervention, making these events
9147 // passive by default on document. React doesn't bind them
9148 // to document anymore, but changing this now would undo
9149 // the performance wins from the change. So we emulate
9150 // the existing behavior manually on the roots now.
9151 // https://github.com/facebook/react/issues/19651
9152 if (domEventName === 'touchstart' || domEventName === 'touchmove' || domEventName === 'wheel') {
9153 isPassiveListener = true;
9154 }
9155 }
9156
9157 targetContainer = targetContainer;
9158 var unsubscribeListener; // When legacyFBSupport is enabled, it's for when we
9159
9160
9161 if (isCapturePhaseListener) {
9162 if (isPassiveListener !== undefined) {
9163 unsubscribeListener = addEventCaptureListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
9164 } else {
9165 unsubscribeListener = addEventCaptureListener(targetContainer, domEventName, listener);
9166 }
9167 } else {
9168 if (isPassiveListener !== undefined) {
9169 unsubscribeListener = addEventBubbleListenerWithPassiveFlag(targetContainer, domEventName, listener, isPassiveListener);
9170 } else {
9171 unsubscribeListener = addEventBubbleListener(targetContainer, domEventName, listener);
9172 }
9173 }
9174 }
9175
9176 function isMatchingRootContainer(grandContainer, targetContainer) {
9177 return grandContainer === targetContainer || grandContainer.nodeType === COMMENT_NODE && grandContainer.parentNode === targetContainer;
9178 }
9179
9180 function dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {
9181 var ancestorInst = targetInst;
9182
9183 if ((eventSystemFlags & IS_EVENT_HANDLE_NON_MANAGED_NODE) === 0 && (eventSystemFlags & IS_NON_DELEGATED) === 0) {
9184 var targetContainerNode = targetContainer; // If we are using the legacy FB support flag, we
9185
9186 if (targetInst !== null) {
9187 // The below logic attempts to work out if we need to change
9188 // the target fiber to a different ancestor. We had similar logic
9189 // in the legacy event system, except the big difference between
9190 // systems is that the modern event system now has an event listener
9191 // attached to each React Root and React Portal Root. Together,
9192 // the DOM nodes representing these roots are the "rootContainer".
9193 // To figure out which ancestor instance we should use, we traverse
9194 // up the fiber tree from the target instance and attempt to find
9195 // root boundaries that match that of our current "rootContainer".
9196 // If we find that "rootContainer", we find the parent fiber
9197 // sub-tree for that root and make that our ancestor instance.
9198 var node = targetInst;
9199
9200 mainLoop: while (true) {
9201 if (node === null) {
9202 return;
9203 }
9204
9205 var nodeTag = node.tag;
9206
9207 if (nodeTag === HostRoot || nodeTag === HostPortal) {
9208 var container = node.stateNode.containerInfo;
9209
9210 if (isMatchingRootContainer(container, targetContainerNode)) {
9211 break;
9212 }
9213
9214 if (nodeTag === HostPortal) {
9215 // The target is a portal, but it's not the rootContainer we're looking for.
9216 // Normally portals handle their own events all the way down to the root.
9217 // So we should be able to stop now. However, we don't know if this portal
9218 // was part of *our* root.
9219 var grandNode = node.return;
9220
9221 while (grandNode !== null) {
9222 var grandTag = grandNode.tag;
9223
9224 if (grandTag === HostRoot || grandTag === HostPortal) {
9225 var grandContainer = grandNode.stateNode.containerInfo;
9226
9227 if (isMatchingRootContainer(grandContainer, targetContainerNode)) {
9228 // This is the rootContainer we're looking for and we found it as
9229 // a parent of the Portal. That means we can ignore it because the
9230 // Portal will bubble through to us.
9231 return;
9232 }
9233 }
9234
9235 grandNode = grandNode.return;
9236 }
9237 } // Now we need to find it's corresponding host fiber in the other
9238 // tree. To do this we can use getClosestInstanceFromNode, but we
9239 // need to validate that the fiber is a host instance, otherwise
9240 // we need to traverse up through the DOM till we find the correct
9241 // node that is from the other tree.
9242
9243
9244 while (container !== null) {
9245 var parentNode = getClosestInstanceFromNode(container);
9246
9247 if (parentNode === null) {
9248 return;
9249 }
9250
9251 var parentTag = parentNode.tag;
9252
9253 if (parentTag === HostComponent || parentTag === HostText) {
9254 node = ancestorInst = parentNode;
9255 continue mainLoop;
9256 }
9257
9258 container = container.parentNode;
9259 }
9260 }
9261
9262 node = node.return;
9263 }
9264 }
9265 }
9266
9267 batchedUpdates(function () {
9268 return dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, ancestorInst);
9269 });
9270 }
9271
9272 function createDispatchListener(instance, listener, currentTarget) {
9273 return {
9274 instance: instance,
9275 listener: listener,
9276 currentTarget: currentTarget
9277 };
9278 }
9279
9280 function accumulateSinglePhaseListeners(targetFiber, reactName, nativeEventType, inCapturePhase, accumulateTargetOnly, nativeEvent) {
9281 var captureName = reactName !== null ? reactName + 'Capture' : null;
9282 var reactEventName = inCapturePhase ? captureName : reactName;
9283 var listeners = [];
9284 var instance = targetFiber;
9285 var lastHostComponent = null; // Accumulate all instances and listeners via the target -> root path.
9286
9287 while (instance !== null) {
9288 var _instance2 = instance,
9289 stateNode = _instance2.stateNode,
9290 tag = _instance2.tag; // Handle listeners that are on HostComponents (i.e. <div>)
9291
9292 if (tag === HostComponent && stateNode !== null) {
9293 lastHostComponent = stateNode; // createEventHandle listeners
9294
9295
9296 if (reactEventName !== null) {
9297 var listener = getListener(instance, reactEventName);
9298
9299 if (listener != null) {
9300 listeners.push(createDispatchListener(instance, listener, lastHostComponent));
9301 }
9302 }
9303 } // If we are only accumulating events for the target, then we don't
9304 // continue to propagate through the React fiber tree to find other
9305 // listeners.
9306
9307
9308 if (accumulateTargetOnly) {
9309 break;
9310 } // If we are processing the onBeforeBlur event, then we need to take
9311
9312 instance = instance.return;
9313 }
9314
9315 return listeners;
9316 } // We should only use this function for:
9317 // - BeforeInputEventPlugin
9318 // - ChangeEventPlugin
9319 // - SelectEventPlugin
9320 // This is because we only process these plugins
9321 // in the bubble phase, so we need to accumulate two
9322 // phase event listeners (via emulation).
9323
9324 function accumulateTwoPhaseListeners(targetFiber, reactName) {
9325 var captureName = reactName + 'Capture';
9326 var listeners = [];
9327 var instance = targetFiber; // Accumulate all instances and listeners via the target -> root path.
9328
9329 while (instance !== null) {
9330 var _instance3 = instance,
9331 stateNode = _instance3.stateNode,
9332 tag = _instance3.tag; // Handle listeners that are on HostComponents (i.e. <div>)
9333
9334 if (tag === HostComponent && stateNode !== null) {
9335 var currentTarget = stateNode;
9336 var captureListener = getListener(instance, captureName);
9337
9338 if (captureListener != null) {
9339 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
9340 }
9341
9342 var bubbleListener = getListener(instance, reactName);
9343
9344 if (bubbleListener != null) {
9345 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
9346 }
9347 }
9348
9349 instance = instance.return;
9350 }
9351
9352 return listeners;
9353 }
9354
9355 function getParent(inst) {
9356 if (inst === null) {
9357 return null;
9358 }
9359
9360 do {
9361 inst = inst.return; // TODO: If this is a HostRoot we might want to bail out.
9362 // That is depending on if we want nested subtrees (layers) to bubble
9363 // events to their parent. We could also go through parentNode on the
9364 // host node but that wouldn't work for React Native and doesn't let us
9365 // do the portal feature.
9366 } while (inst && inst.tag !== HostComponent);
9367
9368 if (inst) {
9369 return inst;
9370 }
9371
9372 return null;
9373 }
9374 /**
9375 * Return the lowest common ancestor of A and B, or null if they are in
9376 * different trees.
9377 */
9378
9379
9380 function getLowestCommonAncestor(instA, instB) {
9381 var nodeA = instA;
9382 var nodeB = instB;
9383 var depthA = 0;
9384
9385 for (var tempA = nodeA; tempA; tempA = getParent(tempA)) {
9386 depthA++;
9387 }
9388
9389 var depthB = 0;
9390
9391 for (var tempB = nodeB; tempB; tempB = getParent(tempB)) {
9392 depthB++;
9393 } // If A is deeper, crawl up.
9394
9395
9396 while (depthA - depthB > 0) {
9397 nodeA = getParent(nodeA);
9398 depthA--;
9399 } // If B is deeper, crawl up.
9400
9401
9402 while (depthB - depthA > 0) {
9403 nodeB = getParent(nodeB);
9404 depthB--;
9405 } // Walk in lockstep until we find a match.
9406
9407
9408 var depth = depthA;
9409
9410 while (depth--) {
9411 if (nodeA === nodeB || nodeB !== null && nodeA === nodeB.alternate) {
9412 return nodeA;
9413 }
9414
9415 nodeA = getParent(nodeA);
9416 nodeB = getParent(nodeB);
9417 }
9418
9419 return null;
9420 }
9421
9422 function accumulateEnterLeaveListenersForEvent(dispatchQueue, event, target, common, inCapturePhase) {
9423 var registrationName = event._reactName;
9424 var listeners = [];
9425 var instance = target;
9426
9427 while (instance !== null) {
9428 if (instance === common) {
9429 break;
9430 }
9431
9432 var _instance4 = instance,
9433 alternate = _instance4.alternate,
9434 stateNode = _instance4.stateNode,
9435 tag = _instance4.tag;
9436
9437 if (alternate !== null && alternate === common) {
9438 break;
9439 }
9440
9441 if (tag === HostComponent && stateNode !== null) {
9442 var currentTarget = stateNode;
9443
9444 if (inCapturePhase) {
9445 var captureListener = getListener(instance, registrationName);
9446
9447 if (captureListener != null) {
9448 listeners.unshift(createDispatchListener(instance, captureListener, currentTarget));
9449 }
9450 } else if (!inCapturePhase) {
9451 var bubbleListener = getListener(instance, registrationName);
9452
9453 if (bubbleListener != null) {
9454 listeners.push(createDispatchListener(instance, bubbleListener, currentTarget));
9455 }
9456 }
9457 }
9458
9459 instance = instance.return;
9460 }
9461
9462 if (listeners.length !== 0) {
9463 dispatchQueue.push({
9464 event: event,
9465 listeners: listeners
9466 });
9467 }
9468 } // We should only use this function for:
9469 // - EnterLeaveEventPlugin
9470 // This is because we only process this plugin
9471 // in the bubble phase, so we need to accumulate two
9472 // phase event listeners.
9473
9474
9475 function accumulateEnterLeaveTwoPhaseListeners(dispatchQueue, leaveEvent, enterEvent, from, to) {
9476 var common = from && to ? getLowestCommonAncestor(from, to) : null;
9477
9478 if (from !== null) {
9479 accumulateEnterLeaveListenersForEvent(dispatchQueue, leaveEvent, from, common, false);
9480 }
9481
9482 if (to !== null && enterEvent !== null) {
9483 accumulateEnterLeaveListenersForEvent(dispatchQueue, enterEvent, to, common, true);
9484 }
9485 }
9486 function getListenerSetKey(domEventName, capture) {
9487 return domEventName + "__" + (capture ? 'capture' : 'bubble');
9488 }
9489
9490 var didWarnInvalidHydration = false;
9491 var DANGEROUSLY_SET_INNER_HTML = 'dangerouslySetInnerHTML';
9492 var SUPPRESS_CONTENT_EDITABLE_WARNING = 'suppressContentEditableWarning';
9493 var SUPPRESS_HYDRATION_WARNING = 'suppressHydrationWarning';
9494 var AUTOFOCUS = 'autoFocus';
9495 var CHILDREN = 'children';
9496 var STYLE = 'style';
9497 var HTML$1 = '__html';
9498 var warnedUnknownTags;
9499 var suppressHydrationWarning;
9500 var validatePropertiesInDevelopment;
9501 var warnForPropDifference;
9502 var warnForExtraAttributes;
9503 var warnForInvalidEventListener;
9504 var canDiffStyleForHydrationWarning;
9505 var normalizeHTML;
9506
9507 {
9508 warnedUnknownTags = {
9509 // There are working polyfills for <dialog>. Let people use it.
9510 dialog: true,
9511 // Electron ships a custom <webview> tag to display external web content in
9512 // an isolated frame and process.
9513 // This tag is not present in non Electron environments such as JSDom which
9514 // is often used for testing purposes.
9515 // @see https://electronjs.org/docs/api/webview-tag
9516 webview: true
9517 };
9518
9519 validatePropertiesInDevelopment = function (type, props) {
9520 validateProperties(type, props);
9521 validateProperties$1(type, props);
9522 validateProperties$2(type, props, {
9523 registrationNameDependencies: registrationNameDependencies,
9524 possibleRegistrationNames: possibleRegistrationNames
9525 });
9526 }; // IE 11 parses & normalizes the style attribute as opposed to other
9527 // browsers. It adds spaces and sorts the properties in some
9528 // non-alphabetical order. Handling that would require sorting CSS
9529 // properties in the client & server versions or applying
9530 // `expectedStyle` to a temporary DOM node to read its `style` attribute
9531 // normalized. Since it only affects IE, we're skipping style warnings
9532 // in that browser completely in favor of doing all that work.
9533 // See https://github.com/facebook/react/issues/11807
9534
9535
9536 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
9537
9538 warnForPropDifference = function (propName, serverValue, clientValue) {
9539 if (didWarnInvalidHydration) {
9540 return;
9541 }
9542
9543 var normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
9544 var normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
9545
9546 if (normalizedServerValue === normalizedClientValue) {
9547 return;
9548 }
9549
9550 didWarnInvalidHydration = true;
9551
9552 error('Prop `%s` did not match. Server: %s Client: %s', propName, JSON.stringify(normalizedServerValue), JSON.stringify(normalizedClientValue));
9553 };
9554
9555 warnForExtraAttributes = function (attributeNames) {
9556 if (didWarnInvalidHydration) {
9557 return;
9558 }
9559
9560 didWarnInvalidHydration = true;
9561 var names = [];
9562 attributeNames.forEach(function (name) {
9563 names.push(name);
9564 });
9565
9566 error('Extra attributes from the server: %s', names);
9567 };
9568
9569 warnForInvalidEventListener = function (registrationName, listener) {
9570 if (listener === false) {
9571 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);
9572 } else {
9573 error('Expected `%s` listener to be a function, instead got a value of `%s` type.', registrationName, typeof listener);
9574 }
9575 }; // Parse the HTML and read it back to normalize the HTML string so that it
9576 // can be used for comparison.
9577
9578
9579 normalizeHTML = function (parent, html) {
9580 // We could have created a separate document here to avoid
9581 // re-initializing custom elements if they exist. But this breaks
9582 // how <noscript> is being handled. So we use the same document.
9583 // See the discussion in https://github.com/facebook/react/pull/11157.
9584 var testElement = parent.namespaceURI === HTML_NAMESPACE ? parent.ownerDocument.createElement(parent.tagName) : parent.ownerDocument.createElementNS(parent.namespaceURI, parent.tagName);
9585 testElement.innerHTML = html;
9586 return testElement.innerHTML;
9587 };
9588 } // HTML parsing normalizes CR and CRLF to LF.
9589 // It also can turn \u0000 into \uFFFD inside attributes.
9590 // https://www.w3.org/TR/html5/single-page.html#preprocessing-the-input-stream
9591 // If we have a mismatch, it might be caused by that.
9592 // We will still patch up in this case but not fire the warning.
9593
9594
9595 var NORMALIZE_NEWLINES_REGEX = /\r\n?/g;
9596 var NORMALIZE_NULL_AND_REPLACEMENT_REGEX = /\u0000|\uFFFD/g;
9597
9598 function normalizeMarkupForTextOrAttribute(markup) {
9599 {
9600 checkHtmlStringCoercion(markup);
9601 }
9602
9603 var markupString = typeof markup === 'string' ? markup : '' + markup;
9604 return markupString.replace(NORMALIZE_NEWLINES_REGEX, '\n').replace(NORMALIZE_NULL_AND_REPLACEMENT_REGEX, '');
9605 }
9606
9607 function checkForUnmatchedText(serverText, clientText, isConcurrentMode, shouldWarnDev) {
9608 var normalizedClientText = normalizeMarkupForTextOrAttribute(clientText);
9609 var normalizedServerText = normalizeMarkupForTextOrAttribute(serverText);
9610
9611 if (normalizedServerText === normalizedClientText) {
9612 return;
9613 }
9614
9615 if (shouldWarnDev) {
9616 {
9617 if (!didWarnInvalidHydration) {
9618 didWarnInvalidHydration = true;
9619
9620 error('Text content did not match. Server: "%s" Client: "%s"', normalizedServerText, normalizedClientText);
9621 }
9622 }
9623 }
9624
9625 if (isConcurrentMode && enableClientRenderFallbackOnTextMismatch) {
9626 // In concurrent roots, we throw when there's a text mismatch and revert to
9627 // client rendering, up to the nearest Suspense boundary.
9628 throw new Error('Text content does not match server-rendered HTML.');
9629 }
9630 }
9631
9632 function getOwnerDocumentFromRootContainer(rootContainerElement) {
9633 return rootContainerElement.nodeType === DOCUMENT_NODE ? rootContainerElement : rootContainerElement.ownerDocument;
9634 }
9635
9636 function noop() {}
9637
9638 function trapClickOnNonInteractiveElement(node) {
9639 // Mobile Safari does not fire properly bubble click events on
9640 // non-interactive elements, which means delegated click listeners do not
9641 // fire. The workaround for this bug involves attaching an empty click
9642 // listener on the target node.
9643 // https://www.quirksmode.org/blog/archives/2010/09/click_event_del.html
9644 // Just set it using the onclick property so that we don't have to manage any
9645 // bookkeeping for it. Not sure if we need to clear it when the listener is
9646 // removed.
9647 // TODO: Only do this for the relevant Safaris maybe?
9648 node.onclick = noop;
9649 }
9650
9651 function setInitialDOMProperties(tag, domElement, rootContainerElement, nextProps, isCustomComponentTag) {
9652 for (var propKey in nextProps) {
9653 if (!nextProps.hasOwnProperty(propKey)) {
9654 continue;
9655 }
9656
9657 var nextProp = nextProps[propKey];
9658
9659 if (propKey === STYLE) {
9660 {
9661 if (nextProp) {
9662 // Freeze the next style object so that we can assume it won't be
9663 // mutated. We have already warned for this in the past.
9664 Object.freeze(nextProp);
9665 }
9666 } // Relies on `updateStylesByID` not mutating `styleUpdates`.
9667
9668
9669 setValueForStyles(domElement, nextProp);
9670 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9671 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
9672
9673 if (nextHtml != null) {
9674 setInnerHTML(domElement, nextHtml);
9675 }
9676 } else if (propKey === CHILDREN) {
9677 if (typeof nextProp === 'string') {
9678 // Avoid setting initial textContent when the text is empty. In IE11 setting
9679 // textContent on a <textarea> will cause the placeholder to not
9680 // show within the <textarea> until it has been focused and blurred again.
9681 // https://github.com/facebook/react/issues/6731#issuecomment-254874553
9682 var canSetTextContent = tag !== 'textarea' || nextProp !== '';
9683
9684 if (canSetTextContent) {
9685 setTextContent(domElement, nextProp);
9686 }
9687 } else if (typeof nextProp === 'number') {
9688 setTextContent(domElement, '' + nextProp);
9689 }
9690 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (propKey === AUTOFOCUS) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
9691 if (nextProp != null) {
9692 if ( typeof nextProp !== 'function') {
9693 warnForInvalidEventListener(propKey, nextProp);
9694 }
9695
9696 if (propKey === 'onScroll') {
9697 listenToNonDelegatedEvent('scroll', domElement);
9698 }
9699 }
9700 } else if (nextProp != null) {
9701 setValueForProperty(domElement, propKey, nextProp, isCustomComponentTag);
9702 }
9703 }
9704 }
9705
9706 function updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag) {
9707 // TODO: Handle wasCustomComponentTag
9708 for (var i = 0; i < updatePayload.length; i += 2) {
9709 var propKey = updatePayload[i];
9710 var propValue = updatePayload[i + 1];
9711
9712 if (propKey === STYLE) {
9713 setValueForStyles(domElement, propValue);
9714 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
9715 setInnerHTML(domElement, propValue);
9716 } else if (propKey === CHILDREN) {
9717 setTextContent(domElement, propValue);
9718 } else {
9719 setValueForProperty(domElement, propKey, propValue, isCustomComponentTag);
9720 }
9721 }
9722 }
9723
9724 function createElement(type, props, rootContainerElement, parentNamespace) {
9725 var isCustomComponentTag; // We create tags in the namespace of their parent container, except HTML
9726 // tags get no namespace.
9727
9728 var ownerDocument = getOwnerDocumentFromRootContainer(rootContainerElement);
9729 var domElement;
9730 var namespaceURI = parentNamespace;
9731
9732 if (namespaceURI === HTML_NAMESPACE) {
9733 namespaceURI = getIntrinsicNamespace(type);
9734 }
9735
9736 if (namespaceURI === HTML_NAMESPACE) {
9737 {
9738 isCustomComponentTag = isCustomComponent(type, props); // Should this check be gated by parent namespace? Not sure we want to
9739 // allow <SVG> or <mATH>.
9740
9741 if (!isCustomComponentTag && type !== type.toLowerCase()) {
9742 error('<%s /> is using incorrect casing. ' + 'Use PascalCase for React components, ' + 'or lowercase for HTML elements.', type);
9743 }
9744 }
9745
9746 if (type === 'script') {
9747 // Create the script via .innerHTML so its "parser-inserted" flag is
9748 // set to true and it does not execute
9749 var div = ownerDocument.createElement('div');
9750
9751 div.innerHTML = '<script><' + '/script>'; // eslint-disable-line
9752 // This is guaranteed to yield a script element.
9753
9754 var firstChild = div.firstChild;
9755 domElement = div.removeChild(firstChild);
9756 } else if (typeof props.is === 'string') {
9757 // $FlowIssue `createElement` should be updated for Web Components
9758 domElement = ownerDocument.createElement(type, {
9759 is: props.is
9760 });
9761 } else {
9762 // Separate else branch instead of using `props.is || undefined` above because of a Firefox bug.
9763 // See discussion in https://github.com/facebook/react/pull/6896
9764 // and discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=1276240
9765 domElement = ownerDocument.createElement(type); // Normally attributes are assigned in `setInitialDOMProperties`, however the `multiple` and `size`
9766 // attributes on `select`s needs to be added before `option`s are inserted.
9767 // This prevents:
9768 // - a bug where the `select` does not scroll to the correct option because singular
9769 // `select` elements automatically pick the first item #13222
9770 // - a bug where the `select` set the first item as selected despite the `size` attribute #14239
9771 // See https://github.com/facebook/react/issues/13222
9772 // and https://github.com/facebook/react/issues/14239
9773
9774 if (type === 'select') {
9775 var node = domElement;
9776
9777 if (props.multiple) {
9778 node.multiple = true;
9779 } else if (props.size) {
9780 // Setting a size greater than 1 causes a select to behave like `multiple=true`, where
9781 // it is possible that no option is selected.
9782 //
9783 // This is only necessary when a select in "single selection mode".
9784 node.size = props.size;
9785 }
9786 }
9787 }
9788 } else {
9789 domElement = ownerDocument.createElementNS(namespaceURI, type);
9790 }
9791
9792 {
9793 if (namespaceURI === HTML_NAMESPACE) {
9794 if (!isCustomComponentTag && Object.prototype.toString.call(domElement) === '[object HTMLUnknownElement]' && !hasOwnProperty.call(warnedUnknownTags, type)) {
9795 warnedUnknownTags[type] = true;
9796
9797 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);
9798 }
9799 }
9800 }
9801
9802 return domElement;
9803 }
9804 function createTextNode(text, rootContainerElement) {
9805 return getOwnerDocumentFromRootContainer(rootContainerElement).createTextNode(text);
9806 }
9807 function setInitialProperties(domElement, tag, rawProps, rootContainerElement) {
9808 var isCustomComponentTag = isCustomComponent(tag, rawProps);
9809
9810 {
9811 validatePropertiesInDevelopment(tag, rawProps);
9812 } // TODO: Make sure that we check isMounted before firing any of these events.
9813
9814
9815 var props;
9816
9817 switch (tag) {
9818 case 'dialog':
9819 listenToNonDelegatedEvent('cancel', domElement);
9820 listenToNonDelegatedEvent('close', domElement);
9821 props = rawProps;
9822 break;
9823
9824 case 'iframe':
9825 case 'object':
9826 case 'embed':
9827 // We listen to this event in case to ensure emulated bubble
9828 // listeners still fire for the load event.
9829 listenToNonDelegatedEvent('load', domElement);
9830 props = rawProps;
9831 break;
9832
9833 case 'video':
9834 case 'audio':
9835 // We listen to these events in case to ensure emulated bubble
9836 // listeners still fire for all the media events.
9837 for (var i = 0; i < mediaEventTypes.length; i++) {
9838 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
9839 }
9840
9841 props = rawProps;
9842 break;
9843
9844 case 'source':
9845 // We listen to this event in case to ensure emulated bubble
9846 // listeners still fire for the error event.
9847 listenToNonDelegatedEvent('error', domElement);
9848 props = rawProps;
9849 break;
9850
9851 case 'img':
9852 case 'image':
9853 case 'link':
9854 // We listen to these events in case to ensure emulated bubble
9855 // listeners still fire for error and load events.
9856 listenToNonDelegatedEvent('error', domElement);
9857 listenToNonDelegatedEvent('load', domElement);
9858 props = rawProps;
9859 break;
9860
9861 case 'details':
9862 // We listen to this event in case to ensure emulated bubble
9863 // listeners still fire for the toggle event.
9864 listenToNonDelegatedEvent('toggle', domElement);
9865 props = rawProps;
9866 break;
9867
9868 case 'input':
9869 initWrapperState(domElement, rawProps);
9870 props = getHostProps(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9871 // listeners still fire for the invalid event.
9872
9873 listenToNonDelegatedEvent('invalid', domElement);
9874 break;
9875
9876 case 'option':
9877 validateProps(domElement, rawProps);
9878 props = rawProps;
9879 break;
9880
9881 case 'select':
9882 initWrapperState$1(domElement, rawProps);
9883 props = getHostProps$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9884 // listeners still fire for the invalid event.
9885
9886 listenToNonDelegatedEvent('invalid', domElement);
9887 break;
9888
9889 case 'textarea':
9890 initWrapperState$2(domElement, rawProps);
9891 props = getHostProps$2(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
9892 // listeners still fire for the invalid event.
9893
9894 listenToNonDelegatedEvent('invalid', domElement);
9895 break;
9896
9897 default:
9898 props = rawProps;
9899 }
9900
9901 assertValidProps(tag, props);
9902 setInitialDOMProperties(tag, domElement, rootContainerElement, props, isCustomComponentTag);
9903
9904 switch (tag) {
9905 case 'input':
9906 // TODO: Make sure we check if this is still unmounted or do any clean
9907 // up necessary since we never stop tracking anymore.
9908 track(domElement);
9909 postMountWrapper(domElement, rawProps, false);
9910 break;
9911
9912 case 'textarea':
9913 // TODO: Make sure we check if this is still unmounted or do any clean
9914 // up necessary since we never stop tracking anymore.
9915 track(domElement);
9916 postMountWrapper$3(domElement);
9917 break;
9918
9919 case 'option':
9920 postMountWrapper$1(domElement, rawProps);
9921 break;
9922
9923 case 'select':
9924 postMountWrapper$2(domElement, rawProps);
9925 break;
9926
9927 default:
9928 if (typeof props.onClick === 'function') {
9929 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9930 trapClickOnNonInteractiveElement(domElement);
9931 }
9932
9933 break;
9934 }
9935 } // Calculate the diff between the two objects.
9936
9937 function diffProperties(domElement, tag, lastRawProps, nextRawProps, rootContainerElement) {
9938 {
9939 validatePropertiesInDevelopment(tag, nextRawProps);
9940 }
9941
9942 var updatePayload = null;
9943 var lastProps;
9944 var nextProps;
9945
9946 switch (tag) {
9947 case 'input':
9948 lastProps = getHostProps(domElement, lastRawProps);
9949 nextProps = getHostProps(domElement, nextRawProps);
9950 updatePayload = [];
9951 break;
9952
9953 case 'select':
9954 lastProps = getHostProps$1(domElement, lastRawProps);
9955 nextProps = getHostProps$1(domElement, nextRawProps);
9956 updatePayload = [];
9957 break;
9958
9959 case 'textarea':
9960 lastProps = getHostProps$2(domElement, lastRawProps);
9961 nextProps = getHostProps$2(domElement, nextRawProps);
9962 updatePayload = [];
9963 break;
9964
9965 default:
9966 lastProps = lastRawProps;
9967 nextProps = nextRawProps;
9968
9969 if (typeof lastProps.onClick !== 'function' && typeof nextProps.onClick === 'function') {
9970 // TODO: This cast may not be sound for SVG, MathML or custom elements.
9971 trapClickOnNonInteractiveElement(domElement);
9972 }
9973
9974 break;
9975 }
9976
9977 assertValidProps(tag, nextProps);
9978 var propKey;
9979 var styleName;
9980 var styleUpdates = null;
9981
9982 for (propKey in lastProps) {
9983 if (nextProps.hasOwnProperty(propKey) || !lastProps.hasOwnProperty(propKey) || lastProps[propKey] == null) {
9984 continue;
9985 }
9986
9987 if (propKey === STYLE) {
9988 var lastStyle = lastProps[propKey];
9989
9990 for (styleName in lastStyle) {
9991 if (lastStyle.hasOwnProperty(styleName)) {
9992 if (!styleUpdates) {
9993 styleUpdates = {};
9994 }
9995
9996 styleUpdates[styleName] = '';
9997 }
9998 }
9999 } 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)) {
10000 // This is a special case. If any listener updates we need to ensure
10001 // that the "current" fiber pointer gets updated so we need a commit
10002 // to update this element.
10003 if (!updatePayload) {
10004 updatePayload = [];
10005 }
10006 } else {
10007 // For all other deleted properties we add it to the queue. We use
10008 // the allowed property list in the commit phase instead.
10009 (updatePayload = updatePayload || []).push(propKey, null);
10010 }
10011 }
10012
10013 for (propKey in nextProps) {
10014 var nextProp = nextProps[propKey];
10015 var lastProp = lastProps != null ? lastProps[propKey] : undefined;
10016
10017 if (!nextProps.hasOwnProperty(propKey) || nextProp === lastProp || nextProp == null && lastProp == null) {
10018 continue;
10019 }
10020
10021 if (propKey === STYLE) {
10022 {
10023 if (nextProp) {
10024 // Freeze the next style object so that we can assume it won't be
10025 // mutated. We have already warned for this in the past.
10026 Object.freeze(nextProp);
10027 }
10028 }
10029
10030 if (lastProp) {
10031 // Unset styles on `lastProp` but not on `nextProp`.
10032 for (styleName in lastProp) {
10033 if (lastProp.hasOwnProperty(styleName) && (!nextProp || !nextProp.hasOwnProperty(styleName))) {
10034 if (!styleUpdates) {
10035 styleUpdates = {};
10036 }
10037
10038 styleUpdates[styleName] = '';
10039 }
10040 } // Update styles that changed since `lastProp`.
10041
10042
10043 for (styleName in nextProp) {
10044 if (nextProp.hasOwnProperty(styleName) && lastProp[styleName] !== nextProp[styleName]) {
10045 if (!styleUpdates) {
10046 styleUpdates = {};
10047 }
10048
10049 styleUpdates[styleName] = nextProp[styleName];
10050 }
10051 }
10052 } else {
10053 // Relies on `updateStylesByID` not mutating `styleUpdates`.
10054 if (!styleUpdates) {
10055 if (!updatePayload) {
10056 updatePayload = [];
10057 }
10058
10059 updatePayload.push(propKey, styleUpdates);
10060 }
10061
10062 styleUpdates = nextProp;
10063 }
10064 } else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
10065 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
10066 var lastHtml = lastProp ? lastProp[HTML$1] : undefined;
10067
10068 if (nextHtml != null) {
10069 if (lastHtml !== nextHtml) {
10070 (updatePayload = updatePayload || []).push(propKey, nextHtml);
10071 }
10072 }
10073 } else if (propKey === CHILDREN) {
10074 if (typeof nextProp === 'string' || typeof nextProp === 'number') {
10075 (updatePayload = updatePayload || []).push(propKey, '' + nextProp);
10076 }
10077 } else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING) ; else if (registrationNameDependencies.hasOwnProperty(propKey)) {
10078 if (nextProp != null) {
10079 // We eagerly listen to this even though we haven't committed yet.
10080 if ( typeof nextProp !== 'function') {
10081 warnForInvalidEventListener(propKey, nextProp);
10082 }
10083
10084 if (propKey === 'onScroll') {
10085 listenToNonDelegatedEvent('scroll', domElement);
10086 }
10087 }
10088
10089 if (!updatePayload && lastProp !== nextProp) {
10090 // This is a special case. If any listener updates we need to ensure
10091 // that the "current" props pointer gets updated so we need a commit
10092 // to update this element.
10093 updatePayload = [];
10094 }
10095 } else {
10096 // For any other property we always add it to the queue and then we
10097 // filter it out using the allowed property list during the commit.
10098 (updatePayload = updatePayload || []).push(propKey, nextProp);
10099 }
10100 }
10101
10102 if (styleUpdates) {
10103 {
10104 validateShorthandPropertyCollisionInDev(styleUpdates, nextProps[STYLE]);
10105 }
10106
10107 (updatePayload = updatePayload || []).push(STYLE, styleUpdates);
10108 }
10109
10110 return updatePayload;
10111 } // Apply the diff.
10112
10113 function updateProperties(domElement, updatePayload, tag, lastRawProps, nextRawProps) {
10114 // Update checked *before* name.
10115 // In the middle of an update, it is possible to have multiple checked.
10116 // When a checked radio tries to change name, browser makes another radio's checked false.
10117 if (tag === 'input' && nextRawProps.type === 'radio' && nextRawProps.name != null) {
10118 updateChecked(domElement, nextRawProps);
10119 }
10120
10121 var wasCustomComponentTag = isCustomComponent(tag, lastRawProps);
10122 var isCustomComponentTag = isCustomComponent(tag, nextRawProps); // Apply the diff.
10123
10124 updateDOMProperties(domElement, updatePayload, wasCustomComponentTag, isCustomComponentTag); // TODO: Ensure that an update gets scheduled if any of the special props
10125 // changed.
10126
10127 switch (tag) {
10128 case 'input':
10129 // Update the wrapper around inputs *after* updating props. This has to
10130 // happen after `updateDOMProperties`. Otherwise HTML5 input validations
10131 // raise warnings and prevent the new value from being assigned.
10132 updateWrapper(domElement, nextRawProps);
10133 break;
10134
10135 case 'textarea':
10136 updateWrapper$1(domElement, nextRawProps);
10137 break;
10138
10139 case 'select':
10140 // <select> value update needs to occur after <option> children
10141 // reconciliation
10142 postUpdateWrapper(domElement, nextRawProps);
10143 break;
10144 }
10145 }
10146
10147 function getPossibleStandardName(propName) {
10148 {
10149 var lowerCasedName = propName.toLowerCase();
10150
10151 if (!possibleStandardNames.hasOwnProperty(lowerCasedName)) {
10152 return null;
10153 }
10154
10155 return possibleStandardNames[lowerCasedName] || null;
10156 }
10157 }
10158
10159 function diffHydratedProperties(domElement, tag, rawProps, parentNamespace, rootContainerElement, isConcurrentMode, shouldWarnDev) {
10160 var isCustomComponentTag;
10161 var extraAttributeNames;
10162
10163 {
10164 suppressHydrationWarning = rawProps[SUPPRESS_HYDRATION_WARNING] === true;
10165 isCustomComponentTag = isCustomComponent(tag, rawProps);
10166 validatePropertiesInDevelopment(tag, rawProps);
10167 } // TODO: Make sure that we check isMounted before firing any of these events.
10168
10169
10170 switch (tag) {
10171 case 'dialog':
10172 listenToNonDelegatedEvent('cancel', domElement);
10173 listenToNonDelegatedEvent('close', domElement);
10174 break;
10175
10176 case 'iframe':
10177 case 'object':
10178 case 'embed':
10179 // We listen to this event in case to ensure emulated bubble
10180 // listeners still fire for the load event.
10181 listenToNonDelegatedEvent('load', domElement);
10182 break;
10183
10184 case 'video':
10185 case 'audio':
10186 // We listen to these events in case to ensure emulated bubble
10187 // listeners still fire for all the media events.
10188 for (var i = 0; i < mediaEventTypes.length; i++) {
10189 listenToNonDelegatedEvent(mediaEventTypes[i], domElement);
10190 }
10191
10192 break;
10193
10194 case 'source':
10195 // We listen to this event in case to ensure emulated bubble
10196 // listeners still fire for the error event.
10197 listenToNonDelegatedEvent('error', domElement);
10198 break;
10199
10200 case 'img':
10201 case 'image':
10202 case 'link':
10203 // We listen to these events in case to ensure emulated bubble
10204 // listeners still fire for error and load events.
10205 listenToNonDelegatedEvent('error', domElement);
10206 listenToNonDelegatedEvent('load', domElement);
10207 break;
10208
10209 case 'details':
10210 // We listen to this event in case to ensure emulated bubble
10211 // listeners still fire for the toggle event.
10212 listenToNonDelegatedEvent('toggle', domElement);
10213 break;
10214
10215 case 'input':
10216 initWrapperState(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
10217 // listeners still fire for the invalid event.
10218
10219 listenToNonDelegatedEvent('invalid', domElement);
10220 break;
10221
10222 case 'option':
10223 validateProps(domElement, rawProps);
10224 break;
10225
10226 case 'select':
10227 initWrapperState$1(domElement, rawProps); // We listen to this event in case to ensure emulated bubble
10228 // listeners still fire for the invalid event.
10229
10230 listenToNonDelegatedEvent('invalid', domElement);
10231 break;
10232
10233 case 'textarea':
10234 initWrapperState$2(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
10241 assertValidProps(tag, rawProps);
10242
10243 {
10244 extraAttributeNames = new Set();
10245 var attributes = domElement.attributes;
10246
10247 for (var _i = 0; _i < attributes.length; _i++) {
10248 var name = attributes[_i].name.toLowerCase();
10249
10250 switch (name) {
10251 // Controlled attributes are not validated
10252 // TODO: Only ignore them on controlled tags.
10253 case 'value':
10254 break;
10255
10256 case 'checked':
10257 break;
10258
10259 case 'selected':
10260 break;
10261
10262 default:
10263 // Intentionally use the original name.
10264 // See discussion in https://github.com/facebook/react/pull/10676.
10265 extraAttributeNames.add(attributes[_i].name);
10266 }
10267 }
10268 }
10269
10270 var updatePayload = null;
10271
10272 for (var propKey in rawProps) {
10273 if (!rawProps.hasOwnProperty(propKey)) {
10274 continue;
10275 }
10276
10277 var nextProp = rawProps[propKey];
10278
10279 if (propKey === CHILDREN) {
10280 // For text content children we compare against textContent. This
10281 // might match additional HTML that is hidden when we read it using
10282 // textContent. E.g. "foo" will match "f<span>oo</span>" but that still
10283 // satisfies our requirement. Our requirement is not to produce perfect
10284 // HTML and attributes. Ideally we should preserve structure but it's
10285 // ok not to if the visible content is still enough to indicate what
10286 // even listeners these nodes might be wired up to.
10287 // TODO: Warn if there is more than a single textNode as a child.
10288 // TODO: Should we use domElement.firstChild.nodeValue to compare?
10289 if (typeof nextProp === 'string') {
10290 if (domElement.textContent !== nextProp) {
10291 if (!suppressHydrationWarning) {
10292 checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
10293 }
10294
10295 updatePayload = [CHILDREN, nextProp];
10296 }
10297 } else if (typeof nextProp === 'number') {
10298 if (domElement.textContent !== '' + nextProp) {
10299 if (!suppressHydrationWarning) {
10300 checkForUnmatchedText(domElement.textContent, nextProp, isConcurrentMode, shouldWarnDev);
10301 }
10302
10303 updatePayload = [CHILDREN, '' + nextProp];
10304 }
10305 }
10306 } else if (registrationNameDependencies.hasOwnProperty(propKey)) {
10307 if (nextProp != null) {
10308 if ( typeof nextProp !== 'function') {
10309 warnForInvalidEventListener(propKey, nextProp);
10310 }
10311
10312 if (propKey === 'onScroll') {
10313 listenToNonDelegatedEvent('scroll', domElement);
10314 }
10315 }
10316 } else if (shouldWarnDev && true && // Convince Flow we've calculated it (it's DEV-only in this method.)
10317 typeof isCustomComponentTag === 'boolean') {
10318 // Validate that the properties correspond to their expected values.
10319 var serverValue = void 0;
10320 var propertyInfo = isCustomComponentTag && enableCustomElementPropertySupport ? null : getPropertyInfo(propKey);
10321
10322 if (suppressHydrationWarning) ; else if (propKey === SUPPRESS_CONTENT_EDITABLE_WARNING || propKey === SUPPRESS_HYDRATION_WARNING || // Controlled attributes are not validated
10323 // TODO: Only ignore them on controlled tags.
10324 propKey === 'value' || propKey === 'checked' || propKey === 'selected') ; else if (propKey === DANGEROUSLY_SET_INNER_HTML) {
10325 var serverHTML = domElement.innerHTML;
10326 var nextHtml = nextProp ? nextProp[HTML$1] : undefined;
10327
10328 if (nextHtml != null) {
10329 var expectedHTML = normalizeHTML(domElement, nextHtml);
10330
10331 if (expectedHTML !== serverHTML) {
10332 warnForPropDifference(propKey, serverHTML, expectedHTML);
10333 }
10334 }
10335 } else if (propKey === STYLE) {
10336 // $FlowFixMe - Should be inferred as not undefined.
10337 extraAttributeNames.delete(propKey);
10338
10339 if (canDiffStyleForHydrationWarning) {
10340 var expectedStyle = createDangerousStringForStyles(nextProp);
10341 serverValue = domElement.getAttribute('style');
10342
10343 if (expectedStyle !== serverValue) {
10344 warnForPropDifference(propKey, serverValue, expectedStyle);
10345 }
10346 }
10347 } else if (isCustomComponentTag && !enableCustomElementPropertySupport) {
10348 // $FlowFixMe - Should be inferred as not undefined.
10349 extraAttributeNames.delete(propKey.toLowerCase());
10350 serverValue = getValueForAttribute(domElement, propKey, nextProp);
10351
10352 if (nextProp !== serverValue) {
10353 warnForPropDifference(propKey, serverValue, nextProp);
10354 }
10355 } else if (!shouldIgnoreAttribute(propKey, propertyInfo, isCustomComponentTag) && !shouldRemoveAttribute(propKey, nextProp, propertyInfo, isCustomComponentTag)) {
10356 var isMismatchDueToBadCasing = false;
10357
10358 if (propertyInfo !== null) {
10359 // $FlowFixMe - Should be inferred as not undefined.
10360 extraAttributeNames.delete(propertyInfo.attributeName);
10361 serverValue = getValueForProperty(domElement, propKey, nextProp, propertyInfo);
10362 } else {
10363 var ownNamespace = parentNamespace;
10364
10365 if (ownNamespace === HTML_NAMESPACE) {
10366 ownNamespace = getIntrinsicNamespace(tag);
10367 }
10368
10369 if (ownNamespace === HTML_NAMESPACE) {
10370 // $FlowFixMe - Should be inferred as not undefined.
10371 extraAttributeNames.delete(propKey.toLowerCase());
10372 } else {
10373 var standardName = getPossibleStandardName(propKey);
10374
10375 if (standardName !== null && standardName !== propKey) {
10376 // If an SVG prop is supplied with bad casing, it will
10377 // be successfully parsed from HTML, but will produce a mismatch
10378 // (and would be incorrectly rendered on the client).
10379 // However, we already warn about bad casing elsewhere.
10380 // So we'll skip the misleading extra mismatch warning in this case.
10381 isMismatchDueToBadCasing = true; // $FlowFixMe - Should be inferred as not undefined.
10382
10383 extraAttributeNames.delete(standardName);
10384 } // $FlowFixMe - Should be inferred as not undefined.
10385
10386
10387 extraAttributeNames.delete(propKey);
10388 }
10389
10390 serverValue = getValueForAttribute(domElement, propKey, nextProp);
10391 }
10392
10393 var dontWarnCustomElement = enableCustomElementPropertySupport ;
10394
10395 if (!dontWarnCustomElement && nextProp !== serverValue && !isMismatchDueToBadCasing) {
10396 warnForPropDifference(propKey, serverValue, nextProp);
10397 }
10398 }
10399 }
10400 }
10401
10402 {
10403 if (shouldWarnDev) {
10404 // $FlowFixMe - Should be inferred as not undefined.
10405 if (extraAttributeNames.size > 0 && !suppressHydrationWarning) {
10406 // $FlowFixMe - Should be inferred as not undefined.
10407 warnForExtraAttributes(extraAttributeNames);
10408 }
10409 }
10410 }
10411
10412 switch (tag) {
10413 case 'input':
10414 // TODO: Make sure we check if this is still unmounted or do any clean
10415 // up necessary since we never stop tracking anymore.
10416 track(domElement);
10417 postMountWrapper(domElement, rawProps, true);
10418 break;
10419
10420 case 'textarea':
10421 // TODO: Make sure we check if this is still unmounted or do any clean
10422 // up necessary since we never stop tracking anymore.
10423 track(domElement);
10424 postMountWrapper$3(domElement);
10425 break;
10426
10427 case 'select':
10428 case 'option':
10429 // For input and textarea we current always set the value property at
10430 // post mount to force it to diverge from attributes. However, for
10431 // option and select we don't quite do the same thing and select
10432 // is not resilient to the DOM state changing so we don't do that here.
10433 // TODO: Consider not doing this for input and textarea.
10434 break;
10435
10436 default:
10437 if (typeof rawProps.onClick === 'function') {
10438 // TODO: This cast may not be sound for SVG, MathML or custom elements.
10439 trapClickOnNonInteractiveElement(domElement);
10440 }
10441
10442 break;
10443 }
10444
10445 return updatePayload;
10446 }
10447 function diffHydratedText(textNode, text, isConcurrentMode) {
10448 var isDifferent = textNode.nodeValue !== text;
10449 return isDifferent;
10450 }
10451 function warnForDeletedHydratableElement(parentNode, child) {
10452 {
10453 if (didWarnInvalidHydration) {
10454 return;
10455 }
10456
10457 didWarnInvalidHydration = true;
10458
10459 error('Did not expect server HTML to contain a <%s> in <%s>.', child.nodeName.toLowerCase(), parentNode.nodeName.toLowerCase());
10460 }
10461 }
10462 function warnForDeletedHydratableText(parentNode, child) {
10463 {
10464 if (didWarnInvalidHydration) {
10465 return;
10466 }
10467
10468 didWarnInvalidHydration = true;
10469
10470 error('Did not expect server HTML to contain the text node "%s" in <%s>.', child.nodeValue, parentNode.nodeName.toLowerCase());
10471 }
10472 }
10473 function warnForInsertedHydratedElement(parentNode, tag, props) {
10474 {
10475 if (didWarnInvalidHydration) {
10476 return;
10477 }
10478
10479 didWarnInvalidHydration = true;
10480
10481 error('Expected server HTML to contain a matching <%s> in <%s>.', tag, parentNode.nodeName.toLowerCase());
10482 }
10483 }
10484 function warnForInsertedHydratedText(parentNode, text) {
10485 {
10486 if (text === '') {
10487 // We expect to insert empty text nodes since they're not represented in
10488 // the HTML.
10489 // TODO: Remove this special case if we can just avoid inserting empty
10490 // text nodes.
10491 return;
10492 }
10493
10494 if (didWarnInvalidHydration) {
10495 return;
10496 }
10497
10498 didWarnInvalidHydration = true;
10499
10500 error('Expected server HTML to contain a matching text node for "%s" in <%s>.', text, parentNode.nodeName.toLowerCase());
10501 }
10502 }
10503 function restoreControlledState$3(domElement, tag, props) {
10504 switch (tag) {
10505 case 'input':
10506 restoreControlledState(domElement, props);
10507 return;
10508
10509 case 'textarea':
10510 restoreControlledState$2(domElement, props);
10511 return;
10512
10513 case 'select':
10514 restoreControlledState$1(domElement, props);
10515 return;
10516 }
10517 }
10518
10519 var validateDOMNesting = function () {};
10520
10521 var updatedAncestorInfo = function () {};
10522
10523 {
10524 // This validation code was written based on the HTML5 parsing spec:
10525 // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
10526 //
10527 // Note: this does not catch all invalid nesting, nor does it try to (as it's
10528 // not clear what practical benefit doing so provides); instead, we warn only
10529 // for cases where the parser will give a parse tree differing from what React
10530 // intended. For example, <b><div></div></b> is invalid but we don't warn
10531 // because it still parses correctly; we do warn for other cases like nested
10532 // <p> tags where the beginning of the second element implicitly closes the
10533 // first, causing a confusing mess.
10534 // https://html.spec.whatwg.org/multipage/syntax.html#special
10535 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
10536
10537 var inScopeTags = ['applet', 'caption', 'html', 'table', 'td', 'th', 'marquee', 'object', 'template', // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
10538 // TODO: Distinguish by namespace here -- for <title>, including it here
10539 // errs on the side of fewer warnings
10540 'foreignObject', 'desc', 'title']; // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
10541
10542 var buttonScopeTags = inScopeTags.concat(['button']); // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
10543
10544 var impliedEndTags = ['dd', 'dt', 'li', 'option', 'optgroup', 'p', 'rp', 'rt'];
10545 var emptyAncestorInfo = {
10546 current: null,
10547 formTag: null,
10548 aTagInScope: null,
10549 buttonTagInScope: null,
10550 nobrTagInScope: null,
10551 pTagInButtonScope: null,
10552 listItemTagAutoclosing: null,
10553 dlItemTagAutoclosing: null
10554 };
10555
10556 updatedAncestorInfo = function (oldInfo, tag) {
10557 var ancestorInfo = assign({}, oldInfo || emptyAncestorInfo);
10558
10559 var info = {
10560 tag: tag
10561 };
10562
10563 if (inScopeTags.indexOf(tag) !== -1) {
10564 ancestorInfo.aTagInScope = null;
10565 ancestorInfo.buttonTagInScope = null;
10566 ancestorInfo.nobrTagInScope = null;
10567 }
10568
10569 if (buttonScopeTags.indexOf(tag) !== -1) {
10570 ancestorInfo.pTagInButtonScope = null;
10571 } // See rules for 'li', 'dd', 'dt' start tags in
10572 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
10573
10574
10575 if (specialTags.indexOf(tag) !== -1 && tag !== 'address' && tag !== 'div' && tag !== 'p') {
10576 ancestorInfo.listItemTagAutoclosing = null;
10577 ancestorInfo.dlItemTagAutoclosing = null;
10578 }
10579
10580 ancestorInfo.current = info;
10581
10582 if (tag === 'form') {
10583 ancestorInfo.formTag = info;
10584 }
10585
10586 if (tag === 'a') {
10587 ancestorInfo.aTagInScope = info;
10588 }
10589
10590 if (tag === 'button') {
10591 ancestorInfo.buttonTagInScope = info;
10592 }
10593
10594 if (tag === 'nobr') {
10595 ancestorInfo.nobrTagInScope = info;
10596 }
10597
10598 if (tag === 'p') {
10599 ancestorInfo.pTagInButtonScope = info;
10600 }
10601
10602 if (tag === 'li') {
10603 ancestorInfo.listItemTagAutoclosing = info;
10604 }
10605
10606 if (tag === 'dd' || tag === 'dt') {
10607 ancestorInfo.dlItemTagAutoclosing = info;
10608 }
10609
10610 return ancestorInfo;
10611 };
10612 /**
10613 * Returns whether
10614 */
10615
10616
10617 var isTagValidWithParent = function (tag, parentTag) {
10618 // First, let's check if we're in an unusual parsing mode...
10619 switch (parentTag) {
10620 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
10621 case 'select':
10622 return tag === 'option' || tag === 'optgroup' || tag === '#text';
10623
10624 case 'optgroup':
10625 return tag === 'option' || tag === '#text';
10626 // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
10627 // but
10628
10629 case 'option':
10630 return tag === '#text';
10631 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
10632 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
10633 // No special behavior since these rules fall back to "in body" mode for
10634 // all except special table nodes which cause bad parsing behavior anyway.
10635 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
10636
10637 case 'tr':
10638 return tag === 'th' || tag === 'td' || tag === 'style' || tag === 'script' || tag === 'template';
10639 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
10640
10641 case 'tbody':
10642 case 'thead':
10643 case 'tfoot':
10644 return tag === 'tr' || tag === 'style' || tag === 'script' || tag === 'template';
10645 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
10646
10647 case 'colgroup':
10648 return tag === 'col' || tag === 'template';
10649 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
10650
10651 case 'table':
10652 return tag === 'caption' || tag === 'colgroup' || tag === 'tbody' || tag === 'tfoot' || tag === 'thead' || tag === 'style' || tag === 'script' || tag === 'template';
10653 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
10654
10655 case 'head':
10656 return tag === 'base' || tag === 'basefont' || tag === 'bgsound' || tag === 'link' || tag === 'meta' || tag === 'title' || tag === 'noscript' || tag === 'noframes' || tag === 'style' || tag === 'script' || tag === 'template';
10657 // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
10658
10659 case 'html':
10660 return tag === 'head' || tag === 'body' || tag === 'frameset';
10661
10662 case 'frameset':
10663 return tag === 'frame';
10664
10665 case '#document':
10666 return tag === 'html';
10667 } // Probably in the "in body" parsing mode, so we outlaw only tag combos
10668 // where the parsing rules cause implicit opens or closes to be added.
10669 // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
10670
10671
10672 switch (tag) {
10673 case 'h1':
10674 case 'h2':
10675 case 'h3':
10676 case 'h4':
10677 case 'h5':
10678 case 'h6':
10679 return parentTag !== 'h1' && parentTag !== 'h2' && parentTag !== 'h3' && parentTag !== 'h4' && parentTag !== 'h5' && parentTag !== 'h6';
10680
10681 case 'rp':
10682 case 'rt':
10683 return impliedEndTags.indexOf(parentTag) === -1;
10684
10685 case 'body':
10686 case 'caption':
10687 case 'col':
10688 case 'colgroup':
10689 case 'frameset':
10690 case 'frame':
10691 case 'head':
10692 case 'html':
10693 case 'tbody':
10694 case 'td':
10695 case 'tfoot':
10696 case 'th':
10697 case 'thead':
10698 case 'tr':
10699 // These tags are only valid with a few parents that have special child
10700 // parsing rules -- if we're down here, then none of those matched and
10701 // so we allow it only if we don't know what the parent is, as all other
10702 // cases are invalid.
10703 return parentTag == null;
10704 }
10705
10706 return true;
10707 };
10708 /**
10709 * Returns whether
10710 */
10711
10712
10713 var findInvalidAncestorForTag = function (tag, ancestorInfo) {
10714 switch (tag) {
10715 case 'address':
10716 case 'article':
10717 case 'aside':
10718 case 'blockquote':
10719 case 'center':
10720 case 'details':
10721 case 'dialog':
10722 case 'dir':
10723 case 'div':
10724 case 'dl':
10725 case 'fieldset':
10726 case 'figcaption':
10727 case 'figure':
10728 case 'footer':
10729 case 'header':
10730 case 'hgroup':
10731 case 'main':
10732 case 'menu':
10733 case 'nav':
10734 case 'ol':
10735 case 'p':
10736 case 'section':
10737 case 'summary':
10738 case 'ul':
10739 case 'pre':
10740 case 'listing':
10741 case 'table':
10742 case 'hr':
10743 case 'xmp':
10744 case 'h1':
10745 case 'h2':
10746 case 'h3':
10747 case 'h4':
10748 case 'h5':
10749 case 'h6':
10750 return ancestorInfo.pTagInButtonScope;
10751
10752 case 'form':
10753 return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
10754
10755 case 'li':
10756 return ancestorInfo.listItemTagAutoclosing;
10757
10758 case 'dd':
10759 case 'dt':
10760 return ancestorInfo.dlItemTagAutoclosing;
10761
10762 case 'button':
10763 return ancestorInfo.buttonTagInScope;
10764
10765 case 'a':
10766 // Spec says something about storing a list of markers, but it sounds
10767 // equivalent to this check.
10768 return ancestorInfo.aTagInScope;
10769
10770 case 'nobr':
10771 return ancestorInfo.nobrTagInScope;
10772 }
10773
10774 return null;
10775 };
10776
10777 var didWarn$1 = {};
10778
10779 validateDOMNesting = function (childTag, childText, ancestorInfo) {
10780 ancestorInfo = ancestorInfo || emptyAncestorInfo;
10781 var parentInfo = ancestorInfo.current;
10782 var parentTag = parentInfo && parentInfo.tag;
10783
10784 if (childText != null) {
10785 if (childTag != null) {
10786 error('validateDOMNesting: when childText is passed, childTag should be null');
10787 }
10788
10789 childTag = '#text';
10790 }
10791
10792 var invalidParent = isTagValidWithParent(childTag, parentTag) ? null : parentInfo;
10793 var invalidAncestor = invalidParent ? null : findInvalidAncestorForTag(childTag, ancestorInfo);
10794 var invalidParentOrAncestor = invalidParent || invalidAncestor;
10795
10796 if (!invalidParentOrAncestor) {
10797 return;
10798 }
10799
10800 var ancestorTag = invalidParentOrAncestor.tag;
10801 var warnKey = !!invalidParent + '|' + childTag + '|' + ancestorTag;
10802
10803 if (didWarn$1[warnKey]) {
10804 return;
10805 }
10806
10807 didWarn$1[warnKey] = true;
10808 var tagDisplayName = childTag;
10809 var whitespaceInfo = '';
10810
10811 if (childTag === '#text') {
10812 if (/\S/.test(childText)) {
10813 tagDisplayName = 'Text nodes';
10814 } else {
10815 tagDisplayName = 'Whitespace text nodes';
10816 whitespaceInfo = " Make sure you don't have any extra whitespace between tags on " + 'each line of your source code.';
10817 }
10818 } else {
10819 tagDisplayName = '<' + childTag + '>';
10820 }
10821
10822 if (invalidParent) {
10823 var info = '';
10824
10825 if (ancestorTag === 'table' && childTag === 'tr') {
10826 info += ' Add a <tbody>, <thead> or <tfoot> to your code to match the DOM tree generated by ' + 'the browser.';
10827 }
10828
10829 error('validateDOMNesting(...): %s cannot appear as a child of <%s>.%s%s', tagDisplayName, ancestorTag, whitespaceInfo, info);
10830 } else {
10831 error('validateDOMNesting(...): %s cannot appear as a descendant of ' + '<%s>.', tagDisplayName, ancestorTag);
10832 }
10833 };
10834 }
10835
10836 var SUPPRESS_HYDRATION_WARNING$1;
10837
10838 {
10839 SUPPRESS_HYDRATION_WARNING$1 = 'suppressHydrationWarning';
10840 }
10841
10842 var SUSPENSE_START_DATA = '$';
10843 var SUSPENSE_END_DATA = '/$';
10844 var SUSPENSE_PENDING_START_DATA = '$?';
10845 var SUSPENSE_FALLBACK_START_DATA = '$!';
10846 var STYLE$1 = 'style';
10847 var selectionInformation = null;
10848 function getRootHostContext(rootContainerInstance) {
10849 var type;
10850 var namespace;
10851 var nodeType = rootContainerInstance.nodeType;
10852
10853 switch (nodeType) {
10854 case DOCUMENT_NODE:
10855 case DOCUMENT_FRAGMENT_NODE:
10856 {
10857 type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
10858 var root = rootContainerInstance.documentElement;
10859 namespace = root ? root.namespaceURI : getChildNamespace(null, '');
10860 break;
10861 }
10862
10863 default:
10864 {
10865 var container = nodeType === COMMENT_NODE ? rootContainerInstance.parentNode : rootContainerInstance;
10866 var ownNamespace = container.namespaceURI || null;
10867 type = container.tagName;
10868 namespace = getChildNamespace(ownNamespace, type);
10869 break;
10870 }
10871 }
10872
10873 {
10874 var validatedTag = type.toLowerCase();
10875 var ancestorInfo = updatedAncestorInfo(null, validatedTag);
10876 return {
10877 namespace: namespace,
10878 ancestorInfo: ancestorInfo
10879 };
10880 }
10881 }
10882 function getChildHostContext(parentHostContext, type, rootContainerInstance) {
10883 {
10884 var parentHostContextDev = parentHostContext;
10885 var namespace = getChildNamespace(parentHostContextDev.namespace, type);
10886 var ancestorInfo = updatedAncestorInfo(parentHostContextDev.ancestorInfo, type);
10887 return {
10888 namespace: namespace,
10889 ancestorInfo: ancestorInfo
10890 };
10891 }
10892 }
10893 function getPublicInstance(instance) {
10894 return instance;
10895 }
10896 function prepareForCommit(containerInfo) {
10897 selectionInformation = getSelectionInformation();
10898 var activeInstance = null;
10899 return activeInstance;
10900 }
10901 function resetAfterCommit(containerInfo) {
10902 restoreSelection(selectionInformation);
10903 selectionInformation = null;
10904 }
10905 function createInstance(type, props, rootContainerInstance, hostContext, internalInstanceHandle) {
10906 var parentNamespace;
10907
10908 {
10909 // TODO: take namespace into account when validating.
10910 var hostContextDev = hostContext;
10911 validateDOMNesting(type, null, hostContextDev.ancestorInfo);
10912
10913 if (typeof props.children === 'string' || typeof props.children === 'number') {
10914 var string = '' + props.children;
10915 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10916 validateDOMNesting(null, string, ownAncestorInfo);
10917 }
10918
10919 parentNamespace = hostContextDev.namespace;
10920 }
10921
10922 var domElement = createElement(type, props, rootContainerInstance, parentNamespace);
10923 precacheFiberNode(internalInstanceHandle, domElement);
10924 updateFiberProps(domElement, props);
10925 return domElement;
10926 }
10927 function appendInitialChild(parentInstance, child) {
10928 parentInstance.appendChild(child);
10929 }
10930 function finalizeInitialChildren(domElement, type, props, rootContainerInstance, hostContext) {
10931 setInitialProperties(domElement, type, props, rootContainerInstance);
10932
10933 switch (type) {
10934 case 'button':
10935 case 'input':
10936 case 'select':
10937 case 'textarea':
10938 return !!props.autoFocus;
10939
10940 case 'img':
10941 return true;
10942
10943 default:
10944 return false;
10945 }
10946 }
10947 function prepareUpdate(domElement, type, oldProps, newProps, rootContainerInstance, hostContext) {
10948 {
10949 var hostContextDev = hostContext;
10950
10951 if (typeof newProps.children !== typeof oldProps.children && (typeof newProps.children === 'string' || typeof newProps.children === 'number')) {
10952 var string = '' + newProps.children;
10953 var ownAncestorInfo = updatedAncestorInfo(hostContextDev.ancestorInfo, type);
10954 validateDOMNesting(null, string, ownAncestorInfo);
10955 }
10956 }
10957
10958 return diffProperties(domElement, type, oldProps, newProps);
10959 }
10960 function shouldSetTextContent(type, props) {
10961 return type === 'textarea' || type === 'noscript' || typeof props.children === 'string' || typeof props.children === 'number' || typeof props.dangerouslySetInnerHTML === 'object' && props.dangerouslySetInnerHTML !== null && props.dangerouslySetInnerHTML.__html != null;
10962 }
10963 function createTextInstance(text, rootContainerInstance, hostContext, internalInstanceHandle) {
10964 {
10965 var hostContextDev = hostContext;
10966 validateDOMNesting(null, text, hostContextDev.ancestorInfo);
10967 }
10968
10969 var textNode = createTextNode(text, rootContainerInstance);
10970 precacheFiberNode(internalInstanceHandle, textNode);
10971 return textNode;
10972 }
10973 function getCurrentEventPriority() {
10974 var currentEvent = window.event;
10975
10976 if (currentEvent === undefined) {
10977 return DefaultEventPriority;
10978 }
10979
10980 return getEventPriority(currentEvent.type);
10981 }
10982 // if a component just imports ReactDOM (e.g. for findDOMNode).
10983 // Some environments might not have setTimeout or clearTimeout.
10984
10985 var scheduleTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
10986 var cancelTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
10987 var noTimeout = -1;
10988 var localPromise = typeof Promise === 'function' ? Promise : undefined; // -------------------
10989 var scheduleMicrotask = typeof queueMicrotask === 'function' ? queueMicrotask : typeof localPromise !== 'undefined' ? function (callback) {
10990 return localPromise.resolve(null).then(callback).catch(handleErrorInNextTick);
10991 } : scheduleTimeout; // TODO: Determine the best fallback here.
10992
10993 function handleErrorInNextTick(error) {
10994 setTimeout(function () {
10995 throw error;
10996 });
10997 } // -------------------
10998 function commitMount(domElement, type, newProps, internalInstanceHandle) {
10999 // Despite the naming that might imply otherwise, this method only
11000 // fires if there is an `Update` effect scheduled during mounting.
11001 // This happens if `finalizeInitialChildren` returns `true` (which it
11002 // does to implement the `autoFocus` attribute on the client). But
11003 // there are also other cases when this might happen (such as patching
11004 // up text content during hydration mismatch). So we'll check this again.
11005 switch (type) {
11006 case 'button':
11007 case 'input':
11008 case 'select':
11009 case 'textarea':
11010 if (newProps.autoFocus) {
11011 domElement.focus();
11012 }
11013
11014 return;
11015
11016 case 'img':
11017 {
11018 if (newProps.src) {
11019 domElement.src = newProps.src;
11020 }
11021
11022 return;
11023 }
11024 }
11025 }
11026 function commitUpdate(domElement, updatePayload, type, oldProps, newProps, internalInstanceHandle) {
11027 // Apply the diff to the DOM node.
11028 updateProperties(domElement, updatePayload, type, oldProps, newProps); // Update the props handle so that we know which props are the ones with
11029 // with current event handlers.
11030
11031 updateFiberProps(domElement, newProps);
11032 }
11033 function resetTextContent(domElement) {
11034 setTextContent(domElement, '');
11035 }
11036 function commitTextUpdate(textInstance, oldText, newText) {
11037 textInstance.nodeValue = newText;
11038 }
11039 function appendChild(parentInstance, child) {
11040 parentInstance.appendChild(child);
11041 }
11042 function appendChildToContainer(container, child) {
11043 var parentNode;
11044
11045 if (container.nodeType === COMMENT_NODE) {
11046 parentNode = container.parentNode;
11047 parentNode.insertBefore(child, container);
11048 } else {
11049 parentNode = container;
11050 parentNode.appendChild(child);
11051 } // This container might be used for a portal.
11052 // If something inside a portal is clicked, that click should bubble
11053 // through the React tree. However, on Mobile Safari the click would
11054 // never bubble through the *DOM* tree unless an ancestor with onclick
11055 // event exists. So we wouldn't see it and dispatch it.
11056 // This is why we ensure that non React root containers have inline onclick
11057 // defined.
11058 // https://github.com/facebook/react/issues/11918
11059
11060
11061 var reactRootContainer = container._reactRootContainer;
11062
11063 if ((reactRootContainer === null || reactRootContainer === undefined) && parentNode.onclick === null) {
11064 // TODO: This cast may not be sound for SVG, MathML or custom elements.
11065 trapClickOnNonInteractiveElement(parentNode);
11066 }
11067 }
11068 function insertBefore(parentInstance, child, beforeChild) {
11069 parentInstance.insertBefore(child, beforeChild);
11070 }
11071 function insertInContainerBefore(container, child, beforeChild) {
11072 if (container.nodeType === COMMENT_NODE) {
11073 container.parentNode.insertBefore(child, beforeChild);
11074 } else {
11075 container.insertBefore(child, beforeChild);
11076 }
11077 }
11078
11079 function removeChild(parentInstance, child) {
11080 parentInstance.removeChild(child);
11081 }
11082 function removeChildFromContainer(container, child) {
11083 if (container.nodeType === COMMENT_NODE) {
11084 container.parentNode.removeChild(child);
11085 } else {
11086 container.removeChild(child);
11087 }
11088 }
11089 function clearSuspenseBoundary(parentInstance, suspenseInstance) {
11090 var node = suspenseInstance; // Delete all nodes within this suspense boundary.
11091 // There might be nested nodes so we need to keep track of how
11092 // deep we are and only break out when we're back on top.
11093
11094 var depth = 0;
11095
11096 do {
11097 var nextNode = node.nextSibling;
11098 parentInstance.removeChild(node);
11099
11100 if (nextNode && nextNode.nodeType === COMMENT_NODE) {
11101 var data = nextNode.data;
11102
11103 if (data === SUSPENSE_END_DATA) {
11104 if (depth === 0) {
11105 parentInstance.removeChild(nextNode); // Retry if any event replaying was blocked on this.
11106
11107 retryIfBlockedOn(suspenseInstance);
11108 return;
11109 } else {
11110 depth--;
11111 }
11112 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_PENDING_START_DATA || data === SUSPENSE_FALLBACK_START_DATA) {
11113 depth++;
11114 }
11115 }
11116
11117 node = nextNode;
11118 } while (node); // TODO: Warn, we didn't find the end comment boundary.
11119 // Retry if any event replaying was blocked on this.
11120
11121
11122 retryIfBlockedOn(suspenseInstance);
11123 }
11124 function clearSuspenseBoundaryFromContainer(container, suspenseInstance) {
11125 if (container.nodeType === COMMENT_NODE) {
11126 clearSuspenseBoundary(container.parentNode, suspenseInstance);
11127 } else if (container.nodeType === ELEMENT_NODE) {
11128 clearSuspenseBoundary(container, suspenseInstance);
11129 } // Retry if any event replaying was blocked on this.
11130
11131
11132 retryIfBlockedOn(container);
11133 }
11134 function hideInstance(instance) {
11135 // TODO: Does this work for all element types? What about MathML? Should we
11136 // pass host context to this method?
11137 instance = instance;
11138 var style = instance.style;
11139
11140 if (typeof style.setProperty === 'function') {
11141 style.setProperty('display', 'none', 'important');
11142 } else {
11143 style.display = 'none';
11144 }
11145 }
11146 function hideTextInstance(textInstance) {
11147 textInstance.nodeValue = '';
11148 }
11149 function unhideInstance(instance, props) {
11150 instance = instance;
11151 var styleProp = props[STYLE$1];
11152 var display = styleProp !== undefined && styleProp !== null && styleProp.hasOwnProperty('display') ? styleProp.display : null;
11153 instance.style.display = dangerousStyleValue('display', display);
11154 }
11155 function unhideTextInstance(textInstance, text) {
11156 textInstance.nodeValue = text;
11157 }
11158 function clearContainer(container) {
11159 if (container.nodeType === ELEMENT_NODE) {
11160 container.textContent = '';
11161 } else if (container.nodeType === DOCUMENT_NODE) {
11162 var body = container.body;
11163
11164 if (body != null) {
11165 body.textContent = '';
11166 }
11167 }
11168 } // -------------------
11169 function canHydrateInstance(instance, type, props) {
11170 if (instance.nodeType !== ELEMENT_NODE || type.toLowerCase() !== instance.nodeName.toLowerCase()) {
11171 return null;
11172 } // This has now been refined to an element node.
11173
11174
11175 return instance;
11176 }
11177 function canHydrateTextInstance(instance, text) {
11178 if (text === '' || instance.nodeType !== TEXT_NODE) {
11179 // Empty strings are not parsed by HTML so there won't be a correct match here.
11180 return null;
11181 } // This has now been refined to a text node.
11182
11183
11184 return instance;
11185 }
11186 function canHydrateSuspenseInstance(instance) {
11187 if (instance.nodeType !== COMMENT_NODE) {
11188 // Empty strings are not parsed by HTML so there won't be a correct match here.
11189 return null;
11190 } // This has now been refined to a suspense node.
11191
11192
11193 return instance;
11194 }
11195 function isSuspenseInstancePending(instance) {
11196 return instance.data === SUSPENSE_PENDING_START_DATA;
11197 }
11198 function isSuspenseInstanceFallback(instance) {
11199 return instance.data === SUSPENSE_FALLBACK_START_DATA;
11200 }
11201 function registerSuspenseInstanceRetry(instance, callback) {
11202 instance._reactRetry = callback;
11203 }
11204
11205 function getNextHydratable(node) {
11206 // Skip non-hydratable nodes.
11207 for (; node != null; node = node.nextSibling) {
11208 var nodeType = node.nodeType;
11209
11210 if (nodeType === ELEMENT_NODE || nodeType === TEXT_NODE) {
11211 break;
11212 }
11213
11214 {
11215 if (nodeType === COMMENT_NODE) {
11216 var nodeData = node.data;
11217
11218 if (nodeData === SUSPENSE_START_DATA || nodeData === SUSPENSE_FALLBACK_START_DATA || nodeData === SUSPENSE_PENDING_START_DATA) {
11219 break;
11220 }
11221
11222 if (nodeData === SUSPENSE_END_DATA) {
11223 return null;
11224 }
11225 }
11226 }
11227 }
11228
11229 return node;
11230 }
11231
11232 function getNextHydratableSibling(instance) {
11233 return getNextHydratable(instance.nextSibling);
11234 }
11235 function getFirstHydratableChild(parentInstance) {
11236 return getNextHydratable(parentInstance.firstChild);
11237 }
11238 function getFirstHydratableChildWithinContainer(parentContainer) {
11239 return getNextHydratable(parentContainer.firstChild);
11240 }
11241 function getFirstHydratableChildWithinSuspenseInstance(parentInstance) {
11242 return getNextHydratable(parentInstance.nextSibling);
11243 }
11244 function hydrateInstance(instance, type, props, rootContainerInstance, hostContext, internalInstanceHandle, shouldWarnDev) {
11245 precacheFiberNode(internalInstanceHandle, instance); // TODO: Possibly defer this until the commit phase where all the events
11246 // get attached.
11247
11248 updateFiberProps(instance, props);
11249 var parentNamespace;
11250
11251 {
11252 var hostContextDev = hostContext;
11253 parentNamespace = hostContextDev.namespace;
11254 } // TODO: Temporary hack to check if we're in a concurrent root. We can delete
11255 // when the legacy root API is removed.
11256
11257
11258 var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
11259 return diffHydratedProperties(instance, type, props, parentNamespace, rootContainerInstance, isConcurrentMode, shouldWarnDev);
11260 }
11261 function hydrateTextInstance(textInstance, text, internalInstanceHandle, shouldWarnDev) {
11262 precacheFiberNode(internalInstanceHandle, textInstance); // TODO: Temporary hack to check if we're in a concurrent root. We can delete
11263 // when the legacy root API is removed.
11264
11265 var isConcurrentMode = (internalInstanceHandle.mode & ConcurrentMode) !== NoMode;
11266 return diffHydratedText(textInstance, text);
11267 }
11268 function hydrateSuspenseInstance(suspenseInstance, internalInstanceHandle) {
11269 precacheFiberNode(internalInstanceHandle, suspenseInstance);
11270 }
11271 function getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance) {
11272 var node = suspenseInstance.nextSibling; // Skip past all nodes within this suspense boundary.
11273 // There might be nested nodes so we need to keep track of how
11274 // deep we are and only break out when we're back on top.
11275
11276 var depth = 0;
11277
11278 while (node) {
11279 if (node.nodeType === COMMENT_NODE) {
11280 var data = node.data;
11281
11282 if (data === SUSPENSE_END_DATA) {
11283 if (depth === 0) {
11284 return getNextHydratableSibling(node);
11285 } else {
11286 depth--;
11287 }
11288 } else if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
11289 depth++;
11290 }
11291 }
11292
11293 node = node.nextSibling;
11294 } // TODO: Warn, we didn't find the end comment boundary.
11295
11296
11297 return null;
11298 } // Returns the SuspenseInstance if this node is a direct child of a
11299 // SuspenseInstance. I.e. if its previous sibling is a Comment with
11300 // SUSPENSE_x_START_DATA. Otherwise, null.
11301
11302 function getParentSuspenseInstance(targetInstance) {
11303 var node = targetInstance.previousSibling; // Skip past all nodes within this suspense boundary.
11304 // There might be nested nodes so we need to keep track of how
11305 // deep we are and only break out when we're back on top.
11306
11307 var depth = 0;
11308
11309 while (node) {
11310 if (node.nodeType === COMMENT_NODE) {
11311 var data = node.data;
11312
11313 if (data === SUSPENSE_START_DATA || data === SUSPENSE_FALLBACK_START_DATA || data === SUSPENSE_PENDING_START_DATA) {
11314 if (depth === 0) {
11315 return node;
11316 } else {
11317 depth--;
11318 }
11319 } else if (data === SUSPENSE_END_DATA) {
11320 depth++;
11321 }
11322 }
11323
11324 node = node.previousSibling;
11325 }
11326
11327 return null;
11328 }
11329 function commitHydratedContainer(container) {
11330 // Retry if any event replaying was blocked on this.
11331 retryIfBlockedOn(container);
11332 }
11333 function commitHydratedSuspenseInstance(suspenseInstance) {
11334 // Retry if any event replaying was blocked on this.
11335 retryIfBlockedOn(suspenseInstance);
11336 }
11337 function shouldDeleteUnhydratedTailInstances(parentType) {
11338 return parentType !== 'head' && parentType !== 'body';
11339 }
11340 function didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, text, isConcurrentMode) {
11341 var shouldWarnDev = true;
11342 checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
11343 }
11344 function didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, text, isConcurrentMode) {
11345 if (parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11346 var shouldWarnDev = true;
11347 checkForUnmatchedText(textInstance.nodeValue, text, isConcurrentMode, shouldWarnDev);
11348 }
11349 }
11350 function didNotHydrateInstanceWithinContainer(parentContainer, instance) {
11351 {
11352 if (instance.nodeType === ELEMENT_NODE) {
11353 warnForDeletedHydratableElement(parentContainer, instance);
11354 } else if (instance.nodeType === COMMENT_NODE) ; else {
11355 warnForDeletedHydratableText(parentContainer, instance);
11356 }
11357 }
11358 }
11359 function didNotHydrateInstanceWithinSuspenseInstance(parentInstance, instance) {
11360 {
11361 // $FlowFixMe: Only Element or Document can be parent nodes.
11362 var parentNode = parentInstance.parentNode;
11363
11364 if (parentNode !== null) {
11365 if (instance.nodeType === ELEMENT_NODE) {
11366 warnForDeletedHydratableElement(parentNode, instance);
11367 } else if (instance.nodeType === COMMENT_NODE) ; else {
11368 warnForDeletedHydratableText(parentNode, instance);
11369 }
11370 }
11371 }
11372 }
11373 function didNotHydrateInstance(parentType, parentProps, parentInstance, instance) {
11374 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11375 if (instance.nodeType === ELEMENT_NODE) {
11376 warnForDeletedHydratableElement(parentInstance, instance);
11377 } else if (instance.nodeType === COMMENT_NODE) ; else {
11378 warnForDeletedHydratableText(parentInstance, instance);
11379 }
11380 }
11381 }
11382 function didNotFindHydratableInstanceWithinContainer(parentContainer, type, props) {
11383 {
11384 warnForInsertedHydratedElement(parentContainer, type);
11385 }
11386 }
11387 function didNotFindHydratableTextInstanceWithinContainer(parentContainer, text) {
11388 {
11389 warnForInsertedHydratedText(parentContainer, text);
11390 }
11391 }
11392 function didNotFindHydratableInstanceWithinSuspenseInstance(parentInstance, type, props) {
11393 {
11394 // $FlowFixMe: Only Element or Document can be parent nodes.
11395 var parentNode = parentInstance.parentNode;
11396 if (parentNode !== null) warnForInsertedHydratedElement(parentNode, type);
11397 }
11398 }
11399 function didNotFindHydratableTextInstanceWithinSuspenseInstance(parentInstance, text) {
11400 {
11401 // $FlowFixMe: Only Element or Document can be parent nodes.
11402 var parentNode = parentInstance.parentNode;
11403 if (parentNode !== null) warnForInsertedHydratedText(parentNode, text);
11404 }
11405 }
11406 function didNotFindHydratableInstance(parentType, parentProps, parentInstance, type, props) {
11407 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11408 warnForInsertedHydratedElement(parentInstance, type);
11409 }
11410 }
11411 function didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, text) {
11412 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) {
11413 warnForInsertedHydratedText(parentInstance, text);
11414 }
11415 }
11416 function didNotFindHydratableSuspenseInstance(parentType, parentProps, parentInstance) {
11417 if ( parentProps[SUPPRESS_HYDRATION_WARNING$1] !== true) ;
11418 }
11419 function errorHydratingContainer(parentContainer) {
11420 {
11421 // TODO: This gets logged by onRecoverableError, too, so we should be
11422 // able to remove it.
11423 error('An error occurred during hydration. The server HTML was replaced with client content in <%s>.', parentContainer.nodeName.toLowerCase());
11424 }
11425 }
11426 function preparePortalMount(portalInstance) {
11427 listenToAllSupportedEvents(portalInstance);
11428 }
11429
11430 var randomKey = Math.random().toString(36).slice(2);
11431 var internalInstanceKey = '__reactFiber$' + randomKey;
11432 var internalPropsKey = '__reactProps$' + randomKey;
11433 var internalContainerInstanceKey = '__reactContainer$' + randomKey;
11434 var internalEventHandlersKey = '__reactEvents$' + randomKey;
11435 var internalEventHandlerListenersKey = '__reactListeners$' + randomKey;
11436 var internalEventHandlesSetKey = '__reactHandles$' + randomKey;
11437 function detachDeletedInstance(node) {
11438 // TODO: This function is only called on host components. I don't think all of
11439 // these fields are relevant.
11440 delete node[internalInstanceKey];
11441 delete node[internalPropsKey];
11442 delete node[internalEventHandlersKey];
11443 delete node[internalEventHandlerListenersKey];
11444 delete node[internalEventHandlesSetKey];
11445 }
11446 function precacheFiberNode(hostInst, node) {
11447 node[internalInstanceKey] = hostInst;
11448 }
11449 function markContainerAsRoot(hostRoot, node) {
11450 node[internalContainerInstanceKey] = hostRoot;
11451 }
11452 function unmarkContainerAsRoot(node) {
11453 node[internalContainerInstanceKey] = null;
11454 }
11455 function isContainerMarkedAsRoot(node) {
11456 return !!node[internalContainerInstanceKey];
11457 } // Given a DOM node, return the closest HostComponent or HostText fiber ancestor.
11458 // If the target node is part of a hydrated or not yet rendered subtree, then
11459 // this may also return a SuspenseComponent or HostRoot to indicate that.
11460 // Conceptually the HostRoot fiber is a child of the Container node. So if you
11461 // pass the Container node as the targetNode, you will not actually get the
11462 // HostRoot back. To get to the HostRoot, you need to pass a child of it.
11463 // The same thing applies to Suspense boundaries.
11464
11465 function getClosestInstanceFromNode(targetNode) {
11466 var targetInst = targetNode[internalInstanceKey];
11467
11468 if (targetInst) {
11469 // Don't return HostRoot or SuspenseComponent here.
11470 return targetInst;
11471 } // If the direct event target isn't a React owned DOM node, we need to look
11472 // to see if one of its parents is a React owned DOM node.
11473
11474
11475 var parentNode = targetNode.parentNode;
11476
11477 while (parentNode) {
11478 // We'll check if this is a container root that could include
11479 // React nodes in the future. We need to check this first because
11480 // if we're a child of a dehydrated container, we need to first
11481 // find that inner container before moving on to finding the parent
11482 // instance. Note that we don't check this field on the targetNode
11483 // itself because the fibers are conceptually between the container
11484 // node and the first child. It isn't surrounding the container node.
11485 // If it's not a container, we check if it's an instance.
11486 targetInst = parentNode[internalContainerInstanceKey] || parentNode[internalInstanceKey];
11487
11488 if (targetInst) {
11489 // Since this wasn't the direct target of the event, we might have
11490 // stepped past dehydrated DOM nodes to get here. However they could
11491 // also have been non-React nodes. We need to answer which one.
11492 // If we the instance doesn't have any children, then there can't be
11493 // a nested suspense boundary within it. So we can use this as a fast
11494 // bailout. Most of the time, when people add non-React children to
11495 // the tree, it is using a ref to a child-less DOM node.
11496 // Normally we'd only need to check one of the fibers because if it
11497 // has ever gone from having children to deleting them or vice versa
11498 // it would have deleted the dehydrated boundary nested inside already.
11499 // However, since the HostRoot starts out with an alternate it might
11500 // have one on the alternate so we need to check in case this was a
11501 // root.
11502 var alternate = targetInst.alternate;
11503
11504 if (targetInst.child !== null || alternate !== null && alternate.child !== null) {
11505 // Next we need to figure out if the node that skipped past is
11506 // nested within a dehydrated boundary and if so, which one.
11507 var suspenseInstance = getParentSuspenseInstance(targetNode);
11508
11509 while (suspenseInstance !== null) {
11510 // We found a suspense instance. That means that we haven't
11511 // hydrated it yet. Even though we leave the comments in the
11512 // DOM after hydrating, and there are boundaries in the DOM
11513 // that could already be hydrated, we wouldn't have found them
11514 // through this pass since if the target is hydrated it would
11515 // have had an internalInstanceKey on it.
11516 // Let's get the fiber associated with the SuspenseComponent
11517 // as the deepest instance.
11518 var targetSuspenseInst = suspenseInstance[internalInstanceKey];
11519
11520 if (targetSuspenseInst) {
11521 return targetSuspenseInst;
11522 } // If we don't find a Fiber on the comment, it might be because
11523 // we haven't gotten to hydrate it yet. There might still be a
11524 // parent boundary that hasn't above this one so we need to find
11525 // the outer most that is known.
11526
11527
11528 suspenseInstance = getParentSuspenseInstance(suspenseInstance); // If we don't find one, then that should mean that the parent
11529 // host component also hasn't hydrated yet. We can return it
11530 // below since it will bail out on the isMounted check later.
11531 }
11532 }
11533
11534 return targetInst;
11535 }
11536
11537 targetNode = parentNode;
11538 parentNode = targetNode.parentNode;
11539 }
11540
11541 return null;
11542 }
11543 /**
11544 * Given a DOM node, return the ReactDOMComponent or ReactDOMTextComponent
11545 * instance, or null if the node was not rendered by this React.
11546 */
11547
11548 function getInstanceFromNode(node) {
11549 var inst = node[internalInstanceKey] || node[internalContainerInstanceKey];
11550
11551 if (inst) {
11552 if (inst.tag === HostComponent || inst.tag === HostText || inst.tag === SuspenseComponent || inst.tag === HostRoot) {
11553 return inst;
11554 } else {
11555 return null;
11556 }
11557 }
11558
11559 return null;
11560 }
11561 /**
11562 * Given a ReactDOMComponent or ReactDOMTextComponent, return the corresponding
11563 * DOM node.
11564 */
11565
11566 function getNodeFromInstance(inst) {
11567 if (inst.tag === HostComponent || inst.tag === HostText) {
11568 // In Fiber this, is just the state node right now. We assume it will be
11569 // a host component or host text.
11570 return inst.stateNode;
11571 } // Without this first invariant, passing a non-DOM-component triggers the next
11572 // invariant for a missing parent, which is super confusing.
11573
11574
11575 throw new Error('getNodeFromInstance: Invalid argument.');
11576 }
11577 function getFiberCurrentPropsFromNode(node) {
11578 return node[internalPropsKey] || null;
11579 }
11580 function updateFiberProps(node, props) {
11581 node[internalPropsKey] = props;
11582 }
11583 function getEventListenerSet(node) {
11584 var elementListenerSet = node[internalEventHandlersKey];
11585
11586 if (elementListenerSet === undefined) {
11587 elementListenerSet = node[internalEventHandlersKey] = new Set();
11588 }
11589
11590 return elementListenerSet;
11591 }
11592
11593 var loggedTypeFailures = {};
11594 var ReactDebugCurrentFrame$1 = ReactSharedInternals.ReactDebugCurrentFrame;
11595
11596 function setCurrentlyValidatingElement(element) {
11597 {
11598 if (element) {
11599 var owner = element._owner;
11600 var stack = describeUnknownElementTypeFrameInDEV(element.type, element._source, owner ? owner.type : null);
11601 ReactDebugCurrentFrame$1.setExtraStackFrame(stack);
11602 } else {
11603 ReactDebugCurrentFrame$1.setExtraStackFrame(null);
11604 }
11605 }
11606 }
11607
11608 function checkPropTypes(typeSpecs, values, location, componentName, element) {
11609 {
11610 // $FlowFixMe This is okay but Flow doesn't know it.
11611 var has = Function.call.bind(hasOwnProperty);
11612
11613 for (var typeSpecName in typeSpecs) {
11614 if (has(typeSpecs, typeSpecName)) {
11615 var error$1 = void 0; // Prop type validation may throw. In case they do, we don't want to
11616 // fail the render phase where it didn't fail before. So we log it.
11617 // After these have been cleaned up, we'll let them throw.
11618
11619 try {
11620 // This is intentionally an invariant that gets caught. It's the same
11621 // behavior as without this statement except with a better message.
11622 if (typeof typeSpecs[typeSpecName] !== 'function') {
11623 // eslint-disable-next-line react-internal/prod-error-codes
11624 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`.');
11625 err.name = 'Invariant Violation';
11626 throw err;
11627 }
11628
11629 error$1 = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED');
11630 } catch (ex) {
11631 error$1 = ex;
11632 }
11633
11634 if (error$1 && !(error$1 instanceof Error)) {
11635 setCurrentlyValidatingElement(element);
11636
11637 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);
11638
11639 setCurrentlyValidatingElement(null);
11640 }
11641
11642 if (error$1 instanceof Error && !(error$1.message in loggedTypeFailures)) {
11643 // Only monitor this failure once because there tends to be a lot of the
11644 // same error.
11645 loggedTypeFailures[error$1.message] = true;
11646 setCurrentlyValidatingElement(element);
11647
11648 error('Failed %s type: %s', location, error$1.message);
11649
11650 setCurrentlyValidatingElement(null);
11651 }
11652 }
11653 }
11654 }
11655 }
11656
11657 var valueStack = [];
11658 var fiberStack;
11659
11660 {
11661 fiberStack = [];
11662 }
11663
11664 var index = -1;
11665
11666 function createCursor(defaultValue) {
11667 return {
11668 current: defaultValue
11669 };
11670 }
11671
11672 function pop(cursor, fiber) {
11673 if (index < 0) {
11674 {
11675 error('Unexpected pop.');
11676 }
11677
11678 return;
11679 }
11680
11681 {
11682 if (fiber !== fiberStack[index]) {
11683 error('Unexpected Fiber popped.');
11684 }
11685 }
11686
11687 cursor.current = valueStack[index];
11688 valueStack[index] = null;
11689
11690 {
11691 fiberStack[index] = null;
11692 }
11693
11694 index--;
11695 }
11696
11697 function push(cursor, value, fiber) {
11698 index++;
11699 valueStack[index] = cursor.current;
11700
11701 {
11702 fiberStack[index] = fiber;
11703 }
11704
11705 cursor.current = value;
11706 }
11707
11708 var warnedAboutMissingGetChildContext;
11709
11710 {
11711 warnedAboutMissingGetChildContext = {};
11712 }
11713
11714 var emptyContextObject = {};
11715
11716 {
11717 Object.freeze(emptyContextObject);
11718 } // A cursor to the current merged context object on the stack.
11719
11720
11721 var contextStackCursor = createCursor(emptyContextObject); // A cursor to a boolean indicating whether the context has changed.
11722
11723 var didPerformWorkStackCursor = createCursor(false); // Keep track of the previous context object that was on the stack.
11724 // We use this to get access to the parent context after we have already
11725 // pushed the next context provider, and now need to merge their contexts.
11726
11727 var previousContext = emptyContextObject;
11728
11729 function getUnmaskedContext(workInProgress, Component, didPushOwnContextIfProvider) {
11730 {
11731 if (didPushOwnContextIfProvider && isContextProvider(Component)) {
11732 // If the fiber is a context provider itself, when we read its context
11733 // we may have already pushed its own child context on the stack. A context
11734 // provider should not "see" its own child context. Therefore we read the
11735 // previous (parent) context instead for a context provider.
11736 return previousContext;
11737 }
11738
11739 return contextStackCursor.current;
11740 }
11741 }
11742
11743 function cacheContext(workInProgress, unmaskedContext, maskedContext) {
11744 {
11745 var instance = workInProgress.stateNode;
11746 instance.__reactInternalMemoizedUnmaskedChildContext = unmaskedContext;
11747 instance.__reactInternalMemoizedMaskedChildContext = maskedContext;
11748 }
11749 }
11750
11751 function getMaskedContext(workInProgress, unmaskedContext) {
11752 {
11753 var type = workInProgress.type;
11754 var contextTypes = type.contextTypes;
11755
11756 if (!contextTypes) {
11757 return emptyContextObject;
11758 } // Avoid recreating masked context unless unmasked context has changed.
11759 // Failing to do this will result in unnecessary calls to componentWillReceiveProps.
11760 // This may trigger infinite loops if componentWillReceiveProps calls setState.
11761
11762
11763 var instance = workInProgress.stateNode;
11764
11765 if (instance && instance.__reactInternalMemoizedUnmaskedChildContext === unmaskedContext) {
11766 return instance.__reactInternalMemoizedMaskedChildContext;
11767 }
11768
11769 var context = {};
11770
11771 for (var key in contextTypes) {
11772 context[key] = unmaskedContext[key];
11773 }
11774
11775 {
11776 var name = getComponentNameFromFiber(workInProgress) || 'Unknown';
11777 checkPropTypes(contextTypes, context, 'context', name);
11778 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
11779 // Context is created before the class component is instantiated so check for instance.
11780
11781
11782 if (instance) {
11783 cacheContext(workInProgress, unmaskedContext, context);
11784 }
11785
11786 return context;
11787 }
11788 }
11789
11790 function hasContextChanged() {
11791 {
11792 return didPerformWorkStackCursor.current;
11793 }
11794 }
11795
11796 function isContextProvider(type) {
11797 {
11798 var childContextTypes = type.childContextTypes;
11799 return childContextTypes !== null && childContextTypes !== undefined;
11800 }
11801 }
11802
11803 function popContext(fiber) {
11804 {
11805 pop(didPerformWorkStackCursor, fiber);
11806 pop(contextStackCursor, fiber);
11807 }
11808 }
11809
11810 function popTopLevelContextObject(fiber) {
11811 {
11812 pop(didPerformWorkStackCursor, fiber);
11813 pop(contextStackCursor, fiber);
11814 }
11815 }
11816
11817 function pushTopLevelContextObject(fiber, context, didChange) {
11818 {
11819 if (contextStackCursor.current !== emptyContextObject) {
11820 throw new Error('Unexpected context found on stack. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11821 }
11822
11823 push(contextStackCursor, context, fiber);
11824 push(didPerformWorkStackCursor, didChange, fiber);
11825 }
11826 }
11827
11828 function processChildContext(fiber, type, parentContext) {
11829 {
11830 var instance = fiber.stateNode;
11831 var childContextTypes = type.childContextTypes; // TODO (bvaughn) Replace this behavior with an invariant() in the future.
11832 // It has only been added in Fiber to match the (unintentional) behavior in Stack.
11833
11834 if (typeof instance.getChildContext !== 'function') {
11835 {
11836 var componentName = getComponentNameFromFiber(fiber) || 'Unknown';
11837
11838 if (!warnedAboutMissingGetChildContext[componentName]) {
11839 warnedAboutMissingGetChildContext[componentName] = true;
11840
11841 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);
11842 }
11843 }
11844
11845 return parentContext;
11846 }
11847
11848 var childContext = instance.getChildContext();
11849
11850 for (var contextKey in childContext) {
11851 if (!(contextKey in childContextTypes)) {
11852 throw new Error((getComponentNameFromFiber(fiber) || 'Unknown') + ".getChildContext(): key \"" + contextKey + "\" is not defined in childContextTypes.");
11853 }
11854 }
11855
11856 {
11857 var name = getComponentNameFromFiber(fiber) || 'Unknown';
11858 checkPropTypes(childContextTypes, childContext, 'child context', name);
11859 }
11860
11861 return assign({}, parentContext, childContext);
11862 }
11863 }
11864
11865 function pushContextProvider(workInProgress) {
11866 {
11867 var instance = workInProgress.stateNode; // We push the context as early as possible to ensure stack integrity.
11868 // If the instance does not exist yet, we will push null at first,
11869 // and replace it on the stack later when invalidating the context.
11870
11871 var memoizedMergedChildContext = instance && instance.__reactInternalMemoizedMergedChildContext || emptyContextObject; // Remember the parent context so we can merge with it later.
11872 // Inherit the parent's did-perform-work value to avoid inadvertently blocking updates.
11873
11874 previousContext = contextStackCursor.current;
11875 push(contextStackCursor, memoizedMergedChildContext, workInProgress);
11876 push(didPerformWorkStackCursor, didPerformWorkStackCursor.current, workInProgress);
11877 return true;
11878 }
11879 }
11880
11881 function invalidateContextProvider(workInProgress, type, didChange) {
11882 {
11883 var instance = workInProgress.stateNode;
11884
11885 if (!instance) {
11886 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.');
11887 }
11888
11889 if (didChange) {
11890 // Merge parent and own context.
11891 // Skip this if we're not updating due to sCU.
11892 // This avoids unnecessarily recomputing memoized values.
11893 var mergedContext = processChildContext(workInProgress, type, previousContext);
11894 instance.__reactInternalMemoizedMergedChildContext = mergedContext; // Replace the old (or empty) context with the new one.
11895 // It is important to unwind the context in the reverse order.
11896
11897 pop(didPerformWorkStackCursor, workInProgress);
11898 pop(contextStackCursor, workInProgress); // Now push the new context and mark that it has changed.
11899
11900 push(contextStackCursor, mergedContext, workInProgress);
11901 push(didPerformWorkStackCursor, didChange, workInProgress);
11902 } else {
11903 pop(didPerformWorkStackCursor, workInProgress);
11904 push(didPerformWorkStackCursor, didChange, workInProgress);
11905 }
11906 }
11907 }
11908
11909 function findCurrentUnmaskedContext(fiber) {
11910 {
11911 // Currently this is only used with renderSubtreeIntoContainer; not sure if it
11912 // makes sense elsewhere
11913 if (!isFiberMounted(fiber) || fiber.tag !== ClassComponent) {
11914 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.');
11915 }
11916
11917 var node = fiber;
11918
11919 do {
11920 switch (node.tag) {
11921 case HostRoot:
11922 return node.stateNode.context;
11923
11924 case ClassComponent:
11925 {
11926 var Component = node.type;
11927
11928 if (isContextProvider(Component)) {
11929 return node.stateNode.__reactInternalMemoizedMergedChildContext;
11930 }
11931
11932 break;
11933 }
11934 }
11935
11936 node = node.return;
11937 } while (node !== null);
11938
11939 throw new Error('Found unexpected detached subtree parent. ' + 'This error is likely caused by a bug in React. Please file an issue.');
11940 }
11941 }
11942
11943 var LegacyRoot = 0;
11944 var ConcurrentRoot = 1;
11945
11946 var syncQueue = null;
11947 var includesLegacySyncCallbacks = false;
11948 var isFlushingSyncQueue = false;
11949 function scheduleSyncCallback(callback) {
11950 // Push this callback into an internal queue. We'll flush these either in
11951 // the next tick, or earlier if something calls `flushSyncCallbackQueue`.
11952 if (syncQueue === null) {
11953 syncQueue = [callback];
11954 } else {
11955 // Push onto existing queue. Don't need to schedule a callback because
11956 // we already scheduled one when we created the queue.
11957 syncQueue.push(callback);
11958 }
11959 }
11960 function scheduleLegacySyncCallback(callback) {
11961 includesLegacySyncCallbacks = true;
11962 scheduleSyncCallback(callback);
11963 }
11964 function flushSyncCallbacksOnlyInLegacyMode() {
11965 // Only flushes the queue if there's a legacy sync callback scheduled.
11966 // TODO: There's only a single type of callback: performSyncOnWorkOnRoot. So
11967 // it might make more sense for the queue to be a list of roots instead of a
11968 // list of generic callbacks. Then we can have two: one for legacy roots, one
11969 // for concurrent roots. And this method would only flush the legacy ones.
11970 if (includesLegacySyncCallbacks) {
11971 flushSyncCallbacks();
11972 }
11973 }
11974 function flushSyncCallbacks() {
11975 if (!isFlushingSyncQueue && syncQueue !== null) {
11976 // Prevent re-entrance.
11977 isFlushingSyncQueue = true;
11978 var i = 0;
11979 var previousUpdatePriority = getCurrentUpdatePriority();
11980
11981 try {
11982 var isSync = true;
11983 var queue = syncQueue; // TODO: Is this necessary anymore? The only user code that runs in this
11984 // queue is in the render or commit phases.
11985
11986 setCurrentUpdatePriority(DiscreteEventPriority);
11987
11988 for (; i < queue.length; i++) {
11989 var callback = queue[i];
11990
11991 do {
11992 callback = callback(isSync);
11993 } while (callback !== null);
11994 }
11995
11996 syncQueue = null;
11997 includesLegacySyncCallbacks = false;
11998 } catch (error) {
11999 // If something throws, leave the remaining callbacks on the queue.
12000 if (syncQueue !== null) {
12001 syncQueue = syncQueue.slice(i + 1);
12002 } // Resume flushing in the next tick
12003
12004
12005 scheduleCallback(ImmediatePriority, flushSyncCallbacks);
12006 throw error;
12007 } finally {
12008 setCurrentUpdatePriority(previousUpdatePriority);
12009 isFlushingSyncQueue = false;
12010 }
12011 }
12012
12013 return null;
12014 }
12015
12016 var ReactCurrentBatchConfig$1 = ReactSharedInternals.ReactCurrentBatchConfig;
12017 var NoTransition = null;
12018 function requestCurrentTransition() {
12019 return ReactCurrentBatchConfig$1.transition;
12020 }
12021
12022 var ReactStrictModeWarnings = {
12023 recordUnsafeLifecycleWarnings: function (fiber, instance) {},
12024 flushPendingUnsafeLifecycleWarnings: function () {},
12025 recordLegacyContextWarning: function (fiber, instance) {},
12026 flushLegacyContextWarning: function () {},
12027 discardPendingWarnings: function () {}
12028 };
12029
12030 {
12031 var findStrictRoot = function (fiber) {
12032 var maybeStrictRoot = null;
12033 var node = fiber;
12034
12035 while (node !== null) {
12036 if (node.mode & StrictLegacyMode) {
12037 maybeStrictRoot = node;
12038 }
12039
12040 node = node.return;
12041 }
12042
12043 return maybeStrictRoot;
12044 };
12045
12046 var setToSortedString = function (set) {
12047 var array = [];
12048 set.forEach(function (value) {
12049 array.push(value);
12050 });
12051 return array.sort().join(', ');
12052 };
12053
12054 var pendingComponentWillMountWarnings = [];
12055 var pendingUNSAFE_ComponentWillMountWarnings = [];
12056 var pendingComponentWillReceivePropsWarnings = [];
12057 var pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12058 var pendingComponentWillUpdateWarnings = [];
12059 var pendingUNSAFE_ComponentWillUpdateWarnings = []; // Tracks components we have already warned about.
12060
12061 var didWarnAboutUnsafeLifecycles = new Set();
12062
12063 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings = function (fiber, instance) {
12064 // Dedupe strategy: Warn once per component.
12065 if (didWarnAboutUnsafeLifecycles.has(fiber.type)) {
12066 return;
12067 }
12068
12069 if (typeof instance.componentWillMount === 'function' && // Don't warn about react-lifecycles-compat polyfilled components.
12070 instance.componentWillMount.__suppressDeprecationWarning !== true) {
12071 pendingComponentWillMountWarnings.push(fiber);
12072 }
12073
12074 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillMount === 'function') {
12075 pendingUNSAFE_ComponentWillMountWarnings.push(fiber);
12076 }
12077
12078 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
12079 pendingComponentWillReceivePropsWarnings.push(fiber);
12080 }
12081
12082 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
12083 pendingUNSAFE_ComponentWillReceivePropsWarnings.push(fiber);
12084 }
12085
12086 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
12087 pendingComponentWillUpdateWarnings.push(fiber);
12088 }
12089
12090 if (fiber.mode & StrictLegacyMode && typeof instance.UNSAFE_componentWillUpdate === 'function') {
12091 pendingUNSAFE_ComponentWillUpdateWarnings.push(fiber);
12092 }
12093 };
12094
12095 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings = function () {
12096 // We do an initial pass to gather component names
12097 var componentWillMountUniqueNames = new Set();
12098
12099 if (pendingComponentWillMountWarnings.length > 0) {
12100 pendingComponentWillMountWarnings.forEach(function (fiber) {
12101 componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12102 didWarnAboutUnsafeLifecycles.add(fiber.type);
12103 });
12104 pendingComponentWillMountWarnings = [];
12105 }
12106
12107 var UNSAFE_componentWillMountUniqueNames = new Set();
12108
12109 if (pendingUNSAFE_ComponentWillMountWarnings.length > 0) {
12110 pendingUNSAFE_ComponentWillMountWarnings.forEach(function (fiber) {
12111 UNSAFE_componentWillMountUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12112 didWarnAboutUnsafeLifecycles.add(fiber.type);
12113 });
12114 pendingUNSAFE_ComponentWillMountWarnings = [];
12115 }
12116
12117 var componentWillReceivePropsUniqueNames = new Set();
12118
12119 if (pendingComponentWillReceivePropsWarnings.length > 0) {
12120 pendingComponentWillReceivePropsWarnings.forEach(function (fiber) {
12121 componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12122 didWarnAboutUnsafeLifecycles.add(fiber.type);
12123 });
12124 pendingComponentWillReceivePropsWarnings = [];
12125 }
12126
12127 var UNSAFE_componentWillReceivePropsUniqueNames = new Set();
12128
12129 if (pendingUNSAFE_ComponentWillReceivePropsWarnings.length > 0) {
12130 pendingUNSAFE_ComponentWillReceivePropsWarnings.forEach(function (fiber) {
12131 UNSAFE_componentWillReceivePropsUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12132 didWarnAboutUnsafeLifecycles.add(fiber.type);
12133 });
12134 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12135 }
12136
12137 var componentWillUpdateUniqueNames = new Set();
12138
12139 if (pendingComponentWillUpdateWarnings.length > 0) {
12140 pendingComponentWillUpdateWarnings.forEach(function (fiber) {
12141 componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12142 didWarnAboutUnsafeLifecycles.add(fiber.type);
12143 });
12144 pendingComponentWillUpdateWarnings = [];
12145 }
12146
12147 var UNSAFE_componentWillUpdateUniqueNames = new Set();
12148
12149 if (pendingUNSAFE_ComponentWillUpdateWarnings.length > 0) {
12150 pendingUNSAFE_ComponentWillUpdateWarnings.forEach(function (fiber) {
12151 UNSAFE_componentWillUpdateUniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12152 didWarnAboutUnsafeLifecycles.add(fiber.type);
12153 });
12154 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12155 } // Finally, we flush all the warnings
12156 // UNSAFE_ ones before the deprecated ones, since they'll be 'louder'
12157
12158
12159 if (UNSAFE_componentWillMountUniqueNames.size > 0) {
12160 var sortedNames = setToSortedString(UNSAFE_componentWillMountUniqueNames);
12161
12162 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);
12163 }
12164
12165 if (UNSAFE_componentWillReceivePropsUniqueNames.size > 0) {
12166 var _sortedNames = setToSortedString(UNSAFE_componentWillReceivePropsUniqueNames);
12167
12168 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);
12169 }
12170
12171 if (UNSAFE_componentWillUpdateUniqueNames.size > 0) {
12172 var _sortedNames2 = setToSortedString(UNSAFE_componentWillUpdateUniqueNames);
12173
12174 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);
12175 }
12176
12177 if (componentWillMountUniqueNames.size > 0) {
12178 var _sortedNames3 = setToSortedString(componentWillMountUniqueNames);
12179
12180 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);
12181 }
12182
12183 if (componentWillReceivePropsUniqueNames.size > 0) {
12184 var _sortedNames4 = setToSortedString(componentWillReceivePropsUniqueNames);
12185
12186 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);
12187 }
12188
12189 if (componentWillUpdateUniqueNames.size > 0) {
12190 var _sortedNames5 = setToSortedString(componentWillUpdateUniqueNames);
12191
12192 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);
12193 }
12194 };
12195
12196 var pendingLegacyContextWarning = new Map(); // Tracks components we have already warned about.
12197
12198 var didWarnAboutLegacyContext = new Set();
12199
12200 ReactStrictModeWarnings.recordLegacyContextWarning = function (fiber, instance) {
12201 var strictRoot = findStrictRoot(fiber);
12202
12203 if (strictRoot === null) {
12204 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.');
12205
12206 return;
12207 } // Dedup strategy: Warn once per component.
12208
12209
12210 if (didWarnAboutLegacyContext.has(fiber.type)) {
12211 return;
12212 }
12213
12214 var warningsForRoot = pendingLegacyContextWarning.get(strictRoot);
12215
12216 if (fiber.type.contextTypes != null || fiber.type.childContextTypes != null || instance !== null && typeof instance.getChildContext === 'function') {
12217 if (warningsForRoot === undefined) {
12218 warningsForRoot = [];
12219 pendingLegacyContextWarning.set(strictRoot, warningsForRoot);
12220 }
12221
12222 warningsForRoot.push(fiber);
12223 }
12224 };
12225
12226 ReactStrictModeWarnings.flushLegacyContextWarning = function () {
12227 pendingLegacyContextWarning.forEach(function (fiberArray, strictRoot) {
12228 if (fiberArray.length === 0) {
12229 return;
12230 }
12231
12232 var firstFiber = fiberArray[0];
12233 var uniqueNames = new Set();
12234 fiberArray.forEach(function (fiber) {
12235 uniqueNames.add(getComponentNameFromFiber(fiber) || 'Component');
12236 didWarnAboutLegacyContext.add(fiber.type);
12237 });
12238 var sortedNames = setToSortedString(uniqueNames);
12239
12240 try {
12241 setCurrentFiber(firstFiber);
12242
12243 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);
12244 } finally {
12245 resetCurrentFiber();
12246 }
12247 });
12248 };
12249
12250 ReactStrictModeWarnings.discardPendingWarnings = function () {
12251 pendingComponentWillMountWarnings = [];
12252 pendingUNSAFE_ComponentWillMountWarnings = [];
12253 pendingComponentWillReceivePropsWarnings = [];
12254 pendingUNSAFE_ComponentWillReceivePropsWarnings = [];
12255 pendingComponentWillUpdateWarnings = [];
12256 pendingUNSAFE_ComponentWillUpdateWarnings = [];
12257 pendingLegacyContextWarning = new Map();
12258 };
12259 }
12260
12261 function resolveDefaultProps(Component, baseProps) {
12262 if (Component && Component.defaultProps) {
12263 // Resolve default props. Taken from ReactElement
12264 var props = assign({}, baseProps);
12265 var defaultProps = Component.defaultProps;
12266
12267 for (var propName in defaultProps) {
12268 if (props[propName] === undefined) {
12269 props[propName] = defaultProps[propName];
12270 }
12271 }
12272
12273 return props;
12274 }
12275
12276 return baseProps;
12277 }
12278
12279 var valueCursor = createCursor(null);
12280 var rendererSigil;
12281
12282 {
12283 // Use this to detect multiple renderers using the same context
12284 rendererSigil = {};
12285 }
12286
12287 var currentlyRenderingFiber = null;
12288 var lastContextDependency = null;
12289 var lastFullyObservedContext = null;
12290 var isDisallowedContextReadInDEV = false;
12291 function resetContextDependencies() {
12292 // This is called right before React yields execution, to ensure `readContext`
12293 // cannot be called outside the render phase.
12294 currentlyRenderingFiber = null;
12295 lastContextDependency = null;
12296 lastFullyObservedContext = null;
12297
12298 {
12299 isDisallowedContextReadInDEV = false;
12300 }
12301 }
12302 function enterDisallowedContextReadInDEV() {
12303 {
12304 isDisallowedContextReadInDEV = true;
12305 }
12306 }
12307 function exitDisallowedContextReadInDEV() {
12308 {
12309 isDisallowedContextReadInDEV = false;
12310 }
12311 }
12312 function pushProvider(providerFiber, context, nextValue) {
12313 {
12314 push(valueCursor, context._currentValue, providerFiber);
12315 context._currentValue = nextValue;
12316
12317 {
12318 if (context._currentRenderer !== undefined && context._currentRenderer !== null && context._currentRenderer !== rendererSigil) {
12319 error('Detected multiple renderers concurrently rendering the ' + 'same context provider. This is currently unsupported.');
12320 }
12321
12322 context._currentRenderer = rendererSigil;
12323 }
12324 }
12325 }
12326 function popProvider(context, providerFiber) {
12327 var currentValue = valueCursor.current;
12328 pop(valueCursor, providerFiber);
12329
12330 {
12331 {
12332 context._currentValue = currentValue;
12333 }
12334 }
12335 }
12336 function scheduleContextWorkOnParentPath(parent, renderLanes, propagationRoot) {
12337 // Update the child lanes of all the ancestors, including the alternates.
12338 var node = parent;
12339
12340 while (node !== null) {
12341 var alternate = node.alternate;
12342
12343 if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
12344 node.childLanes = mergeLanes(node.childLanes, renderLanes);
12345
12346 if (alternate !== null) {
12347 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
12348 }
12349 } else if (alternate !== null && !isSubsetOfLanes(alternate.childLanes, renderLanes)) {
12350 alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
12351 }
12352
12353 if (node === propagationRoot) {
12354 break;
12355 }
12356
12357 node = node.return;
12358 }
12359
12360 {
12361 if (node !== propagationRoot) {
12362 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.');
12363 }
12364 }
12365 }
12366 function propagateContextChange(workInProgress, context, renderLanes) {
12367 {
12368 propagateContextChange_eager(workInProgress, context, renderLanes);
12369 }
12370 }
12371
12372 function propagateContextChange_eager(workInProgress, context, renderLanes) {
12373
12374 var fiber = workInProgress.child;
12375
12376 if (fiber !== null) {
12377 // Set the return pointer of the child to the work-in-progress fiber.
12378 fiber.return = workInProgress;
12379 }
12380
12381 while (fiber !== null) {
12382 var nextFiber = void 0; // Visit this fiber.
12383
12384 var list = fiber.dependencies;
12385
12386 if (list !== null) {
12387 nextFiber = fiber.child;
12388 var dependency = list.firstContext;
12389
12390 while (dependency !== null) {
12391 // Check if the context matches.
12392 if (dependency.context === context) {
12393 // Match! Schedule an update on this fiber.
12394 if (fiber.tag === ClassComponent) {
12395 // Schedule a force update on the work-in-progress.
12396 var lane = pickArbitraryLane(renderLanes);
12397 var update = createUpdate(NoTimestamp, lane);
12398 update.tag = ForceUpdate; // TODO: Because we don't have a work-in-progress, this will add the
12399 // update to the current fiber, too, which means it will persist even if
12400 // this render is thrown away. Since it's a race condition, not sure it's
12401 // worth fixing.
12402 // Inlined `enqueueUpdate` to remove interleaved update check
12403
12404 var updateQueue = fiber.updateQueue;
12405
12406 if (updateQueue === null) ; else {
12407 var sharedQueue = updateQueue.shared;
12408 var pending = sharedQueue.pending;
12409
12410 if (pending === null) {
12411 // This is the first update. Create a circular list.
12412 update.next = update;
12413 } else {
12414 update.next = pending.next;
12415 pending.next = update;
12416 }
12417
12418 sharedQueue.pending = update;
12419 }
12420 }
12421
12422 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
12423 var alternate = fiber.alternate;
12424
12425 if (alternate !== null) {
12426 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
12427 }
12428
12429 scheduleContextWorkOnParentPath(fiber.return, renderLanes, workInProgress); // Mark the updated lanes on the list, too.
12430
12431 list.lanes = mergeLanes(list.lanes, renderLanes); // Since we already found a match, we can stop traversing the
12432 // dependency list.
12433
12434 break;
12435 }
12436
12437 dependency = dependency.next;
12438 }
12439 } else if (fiber.tag === ContextProvider) {
12440 // Don't scan deeper if this is a matching provider
12441 nextFiber = fiber.type === workInProgress.type ? null : fiber.child;
12442 } else if ( fiber.tag === DehydratedFragment) {
12443 // If a dehydrated suspense boundary is in this subtree, we don't know
12444 // if it will have any context consumers in it. The best we can do is
12445 // mark it as having updates.
12446 var parentSuspense = fiber.return;
12447
12448 if (parentSuspense === null) {
12449 throw new Error('We just came from a parent so we must have had a parent. This is a bug in React.');
12450 }
12451
12452 parentSuspense.lanes = mergeLanes(parentSuspense.lanes, renderLanes);
12453 var _alternate = parentSuspense.alternate;
12454
12455 if (_alternate !== null) {
12456 _alternate.lanes = mergeLanes(_alternate.lanes, renderLanes);
12457 } // This is intentionally passing this fiber as the parent
12458 // because we want to schedule this fiber as having work
12459 // on its children. We'll use the childLanes on
12460 // this fiber to indicate that a context has changed.
12461
12462
12463 scheduleContextWorkOnParentPath(parentSuspense, renderLanes, workInProgress);
12464 nextFiber = fiber.sibling;
12465 } else {
12466 // Traverse down.
12467 nextFiber = fiber.child;
12468 }
12469
12470 if (nextFiber !== null) {
12471 // Set the return pointer of the child to the work-in-progress fiber.
12472 nextFiber.return = fiber;
12473 } else {
12474 // No child. Traverse to next sibling.
12475 nextFiber = fiber;
12476
12477 while (nextFiber !== null) {
12478 if (nextFiber === workInProgress) {
12479 // We're back to the root of this subtree. Exit.
12480 nextFiber = null;
12481 break;
12482 }
12483
12484 var sibling = nextFiber.sibling;
12485
12486 if (sibling !== null) {
12487 // Set the return pointer of the sibling to the work-in-progress fiber.
12488 sibling.return = nextFiber.return;
12489 nextFiber = sibling;
12490 break;
12491 } // No more siblings. Traverse up.
12492
12493
12494 nextFiber = nextFiber.return;
12495 }
12496 }
12497
12498 fiber = nextFiber;
12499 }
12500 }
12501 function prepareToReadContext(workInProgress, renderLanes) {
12502 currentlyRenderingFiber = workInProgress;
12503 lastContextDependency = null;
12504 lastFullyObservedContext = null;
12505 var dependencies = workInProgress.dependencies;
12506
12507 if (dependencies !== null) {
12508 {
12509 var firstContext = dependencies.firstContext;
12510
12511 if (firstContext !== null) {
12512 if (includesSomeLane(dependencies.lanes, renderLanes)) {
12513 // Context list has a pending update. Mark that this fiber performed work.
12514 markWorkInProgressReceivedUpdate();
12515 } // Reset the work-in-progress list
12516
12517
12518 dependencies.firstContext = null;
12519 }
12520 }
12521 }
12522 }
12523 function readContext(context) {
12524 {
12525 // This warning would fire if you read context inside a Hook like useMemo.
12526 // Unlike the class check below, it's not enforced in production for perf.
12527 if (isDisallowedContextReadInDEV) {
12528 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().');
12529 }
12530 }
12531
12532 var value = context._currentValue ;
12533
12534 if (lastFullyObservedContext === context) ; else {
12535 var contextItem = {
12536 context: context,
12537 memoizedValue: value,
12538 next: null
12539 };
12540
12541 if (lastContextDependency === null) {
12542 if (currentlyRenderingFiber === null) {
12543 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().');
12544 } // This is the first dependency for this component. Create a new list.
12545
12546
12547 lastContextDependency = contextItem;
12548 currentlyRenderingFiber.dependencies = {
12549 lanes: NoLanes,
12550 firstContext: contextItem
12551 };
12552 } else {
12553 // Append a new context item.
12554 lastContextDependency = lastContextDependency.next = contextItem;
12555 }
12556 }
12557
12558 return value;
12559 }
12560
12561 // An array of all update queues that received updates during the current
12562 // render. When this render exits, either because it finishes or because it is
12563 // interrupted, the interleaved updates will be transferred onto the main part
12564 // of the queue.
12565 var interleavedQueues = null;
12566 function pushInterleavedQueue(queue) {
12567 if (interleavedQueues === null) {
12568 interleavedQueues = [queue];
12569 } else {
12570 interleavedQueues.push(queue);
12571 }
12572 }
12573 function enqueueInterleavedUpdates() {
12574 // Transfer the interleaved updates onto the main queue. Each queue has a
12575 // `pending` field and an `interleaved` field. When they are not null, they
12576 // point to the last node in a circular linked list. We need to append the
12577 // interleaved list to the end of the pending list by joining them into a
12578 // single, circular list.
12579 if (interleavedQueues !== null) {
12580 for (var i = 0; i < interleavedQueues.length; i++) {
12581 var queue = interleavedQueues[i];
12582 var lastInterleavedUpdate = queue.interleaved;
12583
12584 if (lastInterleavedUpdate !== null) {
12585 queue.interleaved = null;
12586 var firstInterleavedUpdate = lastInterleavedUpdate.next;
12587 var lastPendingUpdate = queue.pending;
12588
12589 if (lastPendingUpdate !== null) {
12590 var firstPendingUpdate = lastPendingUpdate.next;
12591 lastPendingUpdate.next = firstInterleavedUpdate;
12592 lastInterleavedUpdate.next = firstPendingUpdate;
12593 }
12594
12595 queue.pending = lastInterleavedUpdate;
12596 }
12597 }
12598
12599 interleavedQueues = null;
12600 }
12601 }
12602
12603 var UpdateState = 0;
12604 var ReplaceState = 1;
12605 var ForceUpdate = 2;
12606 var CaptureUpdate = 3; // Global state that is reset at the beginning of calling `processUpdateQueue`.
12607 // It should only be read right after calling `processUpdateQueue`, via
12608 // `checkHasForceUpdateAfterProcessing`.
12609
12610 var hasForceUpdate = false;
12611 var didWarnUpdateInsideUpdate;
12612 var currentlyProcessingQueue;
12613
12614 {
12615 didWarnUpdateInsideUpdate = false;
12616 currentlyProcessingQueue = null;
12617 }
12618
12619 function initializeUpdateQueue(fiber) {
12620 var queue = {
12621 baseState: fiber.memoizedState,
12622 firstBaseUpdate: null,
12623 lastBaseUpdate: null,
12624 shared: {
12625 pending: null,
12626 interleaved: null,
12627 lanes: NoLanes
12628 },
12629 effects: null
12630 };
12631 fiber.updateQueue = queue;
12632 }
12633 function cloneUpdateQueue(current, workInProgress) {
12634 // Clone the update queue from current. Unless it's already a clone.
12635 var queue = workInProgress.updateQueue;
12636 var currentQueue = current.updateQueue;
12637
12638 if (queue === currentQueue) {
12639 var clone = {
12640 baseState: currentQueue.baseState,
12641 firstBaseUpdate: currentQueue.firstBaseUpdate,
12642 lastBaseUpdate: currentQueue.lastBaseUpdate,
12643 shared: currentQueue.shared,
12644 effects: currentQueue.effects
12645 };
12646 workInProgress.updateQueue = clone;
12647 }
12648 }
12649 function createUpdate(eventTime, lane) {
12650 var update = {
12651 eventTime: eventTime,
12652 lane: lane,
12653 tag: UpdateState,
12654 payload: null,
12655 callback: null,
12656 next: null
12657 };
12658 return update;
12659 }
12660 function enqueueUpdate(fiber, update, lane) {
12661 var updateQueue = fiber.updateQueue;
12662
12663 if (updateQueue === null) {
12664 // Only occurs if the fiber has been unmounted.
12665 return;
12666 }
12667
12668 var sharedQueue = updateQueue.shared;
12669
12670 if (isInterleavedUpdate(fiber)) {
12671 var interleaved = sharedQueue.interleaved;
12672
12673 if (interleaved === null) {
12674 // This is the first update. Create a circular list.
12675 update.next = update; // At the end of the current render, this queue's interleaved updates will
12676 // be transferred to the pending queue.
12677
12678 pushInterleavedQueue(sharedQueue);
12679 } else {
12680 update.next = interleaved.next;
12681 interleaved.next = update;
12682 }
12683
12684 sharedQueue.interleaved = update;
12685 } else {
12686 var pending = sharedQueue.pending;
12687
12688 if (pending === null) {
12689 // This is the first update. Create a circular list.
12690 update.next = update;
12691 } else {
12692 update.next = pending.next;
12693 pending.next = update;
12694 }
12695
12696 sharedQueue.pending = update;
12697 }
12698
12699 {
12700 if (currentlyProcessingQueue === sharedQueue && !didWarnUpdateInsideUpdate) {
12701 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.');
12702
12703 didWarnUpdateInsideUpdate = true;
12704 }
12705 }
12706 }
12707 function entangleTransitions(root, fiber, lane) {
12708 var updateQueue = fiber.updateQueue;
12709
12710 if (updateQueue === null) {
12711 // Only occurs if the fiber has been unmounted.
12712 return;
12713 }
12714
12715 var sharedQueue = updateQueue.shared;
12716
12717 if (isTransitionLane(lane)) {
12718 var queueLanes = sharedQueue.lanes; // If any entangled lanes are no longer pending on the root, then they must
12719 // have finished. We can remove them from the shared queue, which represents
12720 // a superset of the actually pending lanes. In some cases we may entangle
12721 // more than we need to, but that's OK. In fact it's worse if we *don't*
12722 // entangle when we should.
12723
12724 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
12725
12726 var newQueueLanes = mergeLanes(queueLanes, lane);
12727 sharedQueue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
12728 // the lane finished since the last time we entangled it. So we need to
12729 // entangle it again, just to be sure.
12730
12731 markRootEntangled(root, newQueueLanes);
12732 }
12733 }
12734 function enqueueCapturedUpdate(workInProgress, capturedUpdate) {
12735 // Captured updates are updates that are thrown by a child during the render
12736 // phase. They should be discarded if the render is aborted. Therefore,
12737 // we should only put them on the work-in-progress queue, not the current one.
12738 var queue = workInProgress.updateQueue; // Check if the work-in-progress queue is a clone.
12739
12740 var current = workInProgress.alternate;
12741
12742 if (current !== null) {
12743 var currentQueue = current.updateQueue;
12744
12745 if (queue === currentQueue) {
12746 // The work-in-progress queue is the same as current. This happens when
12747 // we bail out on a parent fiber that then captures an error thrown by
12748 // a child. Since we want to append the update only to the work-in
12749 // -progress queue, we need to clone the updates. We usually clone during
12750 // processUpdateQueue, but that didn't happen in this case because we
12751 // skipped over the parent when we bailed out.
12752 var newFirst = null;
12753 var newLast = null;
12754 var firstBaseUpdate = queue.firstBaseUpdate;
12755
12756 if (firstBaseUpdate !== null) {
12757 // Loop through the updates and clone them.
12758 var update = firstBaseUpdate;
12759
12760 do {
12761 var clone = {
12762 eventTime: update.eventTime,
12763 lane: update.lane,
12764 tag: update.tag,
12765 payload: update.payload,
12766 callback: update.callback,
12767 next: null
12768 };
12769
12770 if (newLast === null) {
12771 newFirst = newLast = clone;
12772 } else {
12773 newLast.next = clone;
12774 newLast = clone;
12775 }
12776
12777 update = update.next;
12778 } while (update !== null); // Append the captured update the end of the cloned list.
12779
12780
12781 if (newLast === null) {
12782 newFirst = newLast = capturedUpdate;
12783 } else {
12784 newLast.next = capturedUpdate;
12785 newLast = capturedUpdate;
12786 }
12787 } else {
12788 // There are no base updates.
12789 newFirst = newLast = capturedUpdate;
12790 }
12791
12792 queue = {
12793 baseState: currentQueue.baseState,
12794 firstBaseUpdate: newFirst,
12795 lastBaseUpdate: newLast,
12796 shared: currentQueue.shared,
12797 effects: currentQueue.effects
12798 };
12799 workInProgress.updateQueue = queue;
12800 return;
12801 }
12802 } // Append the update to the end of the list.
12803
12804
12805 var lastBaseUpdate = queue.lastBaseUpdate;
12806
12807 if (lastBaseUpdate === null) {
12808 queue.firstBaseUpdate = capturedUpdate;
12809 } else {
12810 lastBaseUpdate.next = capturedUpdate;
12811 }
12812
12813 queue.lastBaseUpdate = capturedUpdate;
12814 }
12815
12816 function getStateFromUpdate(workInProgress, queue, update, prevState, nextProps, instance) {
12817 switch (update.tag) {
12818 case ReplaceState:
12819 {
12820 var payload = update.payload;
12821
12822 if (typeof payload === 'function') {
12823 // Updater function
12824 {
12825 enterDisallowedContextReadInDEV();
12826 }
12827
12828 var nextState = payload.call(instance, prevState, nextProps);
12829
12830 {
12831 if ( workInProgress.mode & StrictLegacyMode) {
12832 setIsStrictModeForDevtools(true);
12833
12834 try {
12835 payload.call(instance, prevState, nextProps);
12836 } finally {
12837 setIsStrictModeForDevtools(false);
12838 }
12839 }
12840
12841 exitDisallowedContextReadInDEV();
12842 }
12843
12844 return nextState;
12845 } // State object
12846
12847
12848 return payload;
12849 }
12850
12851 case CaptureUpdate:
12852 {
12853 workInProgress.flags = workInProgress.flags & ~ShouldCapture | DidCapture;
12854 }
12855 // Intentional fallthrough
12856
12857 case UpdateState:
12858 {
12859 var _payload = update.payload;
12860 var partialState;
12861
12862 if (typeof _payload === 'function') {
12863 // Updater function
12864 {
12865 enterDisallowedContextReadInDEV();
12866 }
12867
12868 partialState = _payload.call(instance, prevState, nextProps);
12869
12870 {
12871 if ( workInProgress.mode & StrictLegacyMode) {
12872 setIsStrictModeForDevtools(true);
12873
12874 try {
12875 _payload.call(instance, prevState, nextProps);
12876 } finally {
12877 setIsStrictModeForDevtools(false);
12878 }
12879 }
12880
12881 exitDisallowedContextReadInDEV();
12882 }
12883 } else {
12884 // Partial state object
12885 partialState = _payload;
12886 }
12887
12888 if (partialState === null || partialState === undefined) {
12889 // Null and undefined are treated as no-ops.
12890 return prevState;
12891 } // Merge the partial state and the previous state.
12892
12893
12894 return assign({}, prevState, partialState);
12895 }
12896
12897 case ForceUpdate:
12898 {
12899 hasForceUpdate = true;
12900 return prevState;
12901 }
12902 }
12903
12904 return prevState;
12905 }
12906
12907 function processUpdateQueue(workInProgress, props, instance, renderLanes) {
12908 // This is always non-null on a ClassComponent or HostRoot
12909 var queue = workInProgress.updateQueue;
12910 hasForceUpdate = false;
12911
12912 {
12913 currentlyProcessingQueue = queue.shared;
12914 }
12915
12916 var firstBaseUpdate = queue.firstBaseUpdate;
12917 var lastBaseUpdate = queue.lastBaseUpdate; // Check if there are pending updates. If so, transfer them to the base queue.
12918
12919 var pendingQueue = queue.shared.pending;
12920
12921 if (pendingQueue !== null) {
12922 queue.shared.pending = null; // The pending queue is circular. Disconnect the pointer between first
12923 // and last so that it's non-circular.
12924
12925 var lastPendingUpdate = pendingQueue;
12926 var firstPendingUpdate = lastPendingUpdate.next;
12927 lastPendingUpdate.next = null; // Append pending updates to base queue
12928
12929 if (lastBaseUpdate === null) {
12930 firstBaseUpdate = firstPendingUpdate;
12931 } else {
12932 lastBaseUpdate.next = firstPendingUpdate;
12933 }
12934
12935 lastBaseUpdate = lastPendingUpdate; // If there's a current queue, and it's different from the base queue, then
12936 // we need to transfer the updates to that queue, too. Because the base
12937 // queue is a singly-linked list with no cycles, we can append to both
12938 // lists and take advantage of structural sharing.
12939 // TODO: Pass `current` as argument
12940
12941 var current = workInProgress.alternate;
12942
12943 if (current !== null) {
12944 // This is always non-null on a ClassComponent or HostRoot
12945 var currentQueue = current.updateQueue;
12946 var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
12947
12948 if (currentLastBaseUpdate !== lastBaseUpdate) {
12949 if (currentLastBaseUpdate === null) {
12950 currentQueue.firstBaseUpdate = firstPendingUpdate;
12951 } else {
12952 currentLastBaseUpdate.next = firstPendingUpdate;
12953 }
12954
12955 currentQueue.lastBaseUpdate = lastPendingUpdate;
12956 }
12957 }
12958 } // These values may change as we process the queue.
12959
12960
12961 if (firstBaseUpdate !== null) {
12962 // Iterate through the list of updates to compute the result.
12963 var newState = queue.baseState; // TODO: Don't need to accumulate this. Instead, we can remove renderLanes
12964 // from the original lanes.
12965
12966 var newLanes = NoLanes;
12967 var newBaseState = null;
12968 var newFirstBaseUpdate = null;
12969 var newLastBaseUpdate = null;
12970 var update = firstBaseUpdate;
12971
12972 do {
12973 var updateLane = update.lane;
12974 var updateEventTime = update.eventTime;
12975
12976 if (!isSubsetOfLanes(renderLanes, updateLane)) {
12977 // Priority is insufficient. Skip this update. If this is the first
12978 // skipped update, the previous update/state is the new base
12979 // update/state.
12980 var clone = {
12981 eventTime: updateEventTime,
12982 lane: updateLane,
12983 tag: update.tag,
12984 payload: update.payload,
12985 callback: update.callback,
12986 next: null
12987 };
12988
12989 if (newLastBaseUpdate === null) {
12990 newFirstBaseUpdate = newLastBaseUpdate = clone;
12991 newBaseState = newState;
12992 } else {
12993 newLastBaseUpdate = newLastBaseUpdate.next = clone;
12994 } // Update the remaining priority in the queue.
12995
12996
12997 newLanes = mergeLanes(newLanes, updateLane);
12998 } else {
12999 // This update does have sufficient priority.
13000 if (newLastBaseUpdate !== null) {
13001 var _clone = {
13002 eventTime: updateEventTime,
13003 // This update is going to be committed so we never want uncommit
13004 // it. Using NoLane works because 0 is a subset of all bitmasks, so
13005 // this will never be skipped by the check above.
13006 lane: NoLane,
13007 tag: update.tag,
13008 payload: update.payload,
13009 callback: update.callback,
13010 next: null
13011 };
13012 newLastBaseUpdate = newLastBaseUpdate.next = _clone;
13013 } // Process this update.
13014
13015
13016 newState = getStateFromUpdate(workInProgress, queue, update, newState, props, instance);
13017 var callback = update.callback;
13018
13019 if (callback !== null && // If the update was already committed, we should not queue its
13020 // callback again.
13021 update.lane !== NoLane) {
13022 workInProgress.flags |= Callback;
13023 var effects = queue.effects;
13024
13025 if (effects === null) {
13026 queue.effects = [update];
13027 } else {
13028 effects.push(update);
13029 }
13030 }
13031 }
13032
13033 update = update.next;
13034
13035 if (update === null) {
13036 pendingQueue = queue.shared.pending;
13037
13038 if (pendingQueue === null) {
13039 break;
13040 } else {
13041 // An update was scheduled from inside a reducer. Add the new
13042 // pending updates to the end of the list and keep processing.
13043 var _lastPendingUpdate = pendingQueue; // Intentionally unsound. Pending updates form a circular list, but we
13044 // unravel them when transferring them to the base queue.
13045
13046 var _firstPendingUpdate = _lastPendingUpdate.next;
13047 _lastPendingUpdate.next = null;
13048 update = _firstPendingUpdate;
13049 queue.lastBaseUpdate = _lastPendingUpdate;
13050 queue.shared.pending = null;
13051 }
13052 }
13053 } while (true);
13054
13055 if (newLastBaseUpdate === null) {
13056 newBaseState = newState;
13057 }
13058
13059 queue.baseState = newBaseState;
13060 queue.firstBaseUpdate = newFirstBaseUpdate;
13061 queue.lastBaseUpdate = newLastBaseUpdate; // Interleaved updates are stored on a separate queue. We aren't going to
13062 // process them during this render, but we do need to track which lanes
13063 // are remaining.
13064
13065 var lastInterleaved = queue.shared.interleaved;
13066
13067 if (lastInterleaved !== null) {
13068 var interleaved = lastInterleaved;
13069
13070 do {
13071 newLanes = mergeLanes(newLanes, interleaved.lane);
13072 interleaved = interleaved.next;
13073 } while (interleaved !== lastInterleaved);
13074 } else if (firstBaseUpdate === null) {
13075 // `queue.lanes` is used for entangling transitions. We can set it back to
13076 // zero once the queue is empty.
13077 queue.shared.lanes = NoLanes;
13078 } // Set the remaining expiration time to be whatever is remaining in the queue.
13079 // This should be fine because the only two other things that contribute to
13080 // expiration time are props and context. We're already in the middle of the
13081 // begin phase by the time we start processing the queue, so we've already
13082 // dealt with the props. Context in components that specify
13083 // shouldComponentUpdate is tricky; but we'll have to account for
13084 // that regardless.
13085
13086
13087 markSkippedUpdateLanes(newLanes);
13088 workInProgress.lanes = newLanes;
13089 workInProgress.memoizedState = newState;
13090 }
13091
13092 {
13093 currentlyProcessingQueue = null;
13094 }
13095 }
13096
13097 function callCallback(callback, context) {
13098 if (typeof callback !== 'function') {
13099 throw new Error('Invalid argument passed as callback. Expected a function. Instead ' + ("received: " + callback));
13100 }
13101
13102 callback.call(context);
13103 }
13104
13105 function resetHasForceUpdateBeforeProcessing() {
13106 hasForceUpdate = false;
13107 }
13108 function checkHasForceUpdateAfterProcessing() {
13109 return hasForceUpdate;
13110 }
13111 function commitUpdateQueue(finishedWork, finishedQueue, instance) {
13112 // Commit the effects
13113 var effects = finishedQueue.effects;
13114 finishedQueue.effects = null;
13115
13116 if (effects !== null) {
13117 for (var i = 0; i < effects.length; i++) {
13118 var effect = effects[i];
13119 var callback = effect.callback;
13120
13121 if (callback !== null) {
13122 effect.callback = null;
13123 callCallback(callback, instance);
13124 }
13125 }
13126 }
13127 }
13128
13129 var fakeInternalInstance = {}; // React.Component uses a shared frozen object by default.
13130 // We'll use it to determine whether we need to initialize legacy refs.
13131
13132 var emptyRefsObject = new React.Component().refs;
13133 var didWarnAboutStateAssignmentForComponent;
13134 var didWarnAboutUninitializedState;
13135 var didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
13136 var didWarnAboutLegacyLifecyclesAndDerivedState;
13137 var didWarnAboutUndefinedDerivedState;
13138 var warnOnUndefinedDerivedState;
13139 var warnOnInvalidCallback;
13140 var didWarnAboutDirectlyAssigningPropsToState;
13141 var didWarnAboutContextTypeAndContextTypes;
13142 var didWarnAboutInvalidateContextType;
13143
13144 {
13145 didWarnAboutStateAssignmentForComponent = new Set();
13146 didWarnAboutUninitializedState = new Set();
13147 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate = new Set();
13148 didWarnAboutLegacyLifecyclesAndDerivedState = new Set();
13149 didWarnAboutDirectlyAssigningPropsToState = new Set();
13150 didWarnAboutUndefinedDerivedState = new Set();
13151 didWarnAboutContextTypeAndContextTypes = new Set();
13152 didWarnAboutInvalidateContextType = new Set();
13153 var didWarnOnInvalidCallback = new Set();
13154
13155 warnOnInvalidCallback = function (callback, callerName) {
13156 if (callback === null || typeof callback === 'function') {
13157 return;
13158 }
13159
13160 var key = callerName + '_' + callback;
13161
13162 if (!didWarnOnInvalidCallback.has(key)) {
13163 didWarnOnInvalidCallback.add(key);
13164
13165 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
13166 }
13167 };
13168
13169 warnOnUndefinedDerivedState = function (type, partialState) {
13170 if (partialState === undefined) {
13171 var componentName = getComponentNameFromType(type) || 'Component';
13172
13173 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
13174 didWarnAboutUndefinedDerivedState.add(componentName);
13175
13176 error('%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' + 'You have returned undefined.', componentName);
13177 }
13178 }
13179 }; // This is so gross but it's at least non-critical and can be removed if
13180 // it causes problems. This is meant to give a nicer error message for
13181 // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
13182 // ...)) which otherwise throws a "_processChildContext is not a function"
13183 // exception.
13184
13185
13186 Object.defineProperty(fakeInternalInstance, '_processChildContext', {
13187 enumerable: false,
13188 value: function () {
13189 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).');
13190 }
13191 });
13192 Object.freeze(fakeInternalInstance);
13193 }
13194
13195 function applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, nextProps) {
13196 var prevState = workInProgress.memoizedState;
13197 var partialState = getDerivedStateFromProps(nextProps, prevState);
13198
13199 {
13200 if ( workInProgress.mode & StrictLegacyMode) {
13201 setIsStrictModeForDevtools(true);
13202
13203 try {
13204 // Invoke the function an extra time to help detect side-effects.
13205 partialState = getDerivedStateFromProps(nextProps, prevState);
13206 } finally {
13207 setIsStrictModeForDevtools(false);
13208 }
13209 }
13210
13211 warnOnUndefinedDerivedState(ctor, partialState);
13212 } // Merge the partial state and the previous state.
13213
13214
13215 var memoizedState = partialState === null || partialState === undefined ? prevState : assign({}, prevState, partialState);
13216 workInProgress.memoizedState = memoizedState; // Once the update queue is empty, persist the derived state onto the
13217 // base state.
13218
13219 if (workInProgress.lanes === NoLanes) {
13220 // Queue is always non-null for classes
13221 var updateQueue = workInProgress.updateQueue;
13222 updateQueue.baseState = memoizedState;
13223 }
13224 }
13225
13226 var classComponentUpdater = {
13227 isMounted: isMounted,
13228 enqueueSetState: function (inst, payload, callback) {
13229 var fiber = get(inst);
13230 var eventTime = requestEventTime();
13231 var lane = requestUpdateLane(fiber);
13232 var update = createUpdate(eventTime, lane);
13233 update.payload = payload;
13234
13235 if (callback !== undefined && callback !== null) {
13236 {
13237 warnOnInvalidCallback(callback, 'setState');
13238 }
13239
13240 update.callback = callback;
13241 }
13242
13243 enqueueUpdate(fiber, update);
13244 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
13245
13246 if (root !== null) {
13247 entangleTransitions(root, fiber, lane);
13248 }
13249
13250 {
13251 markStateUpdateScheduled(fiber, lane);
13252 }
13253 },
13254 enqueueReplaceState: function (inst, payload, callback) {
13255 var fiber = get(inst);
13256 var eventTime = requestEventTime();
13257 var lane = requestUpdateLane(fiber);
13258 var update = createUpdate(eventTime, lane);
13259 update.tag = ReplaceState;
13260 update.payload = payload;
13261
13262 if (callback !== undefined && callback !== null) {
13263 {
13264 warnOnInvalidCallback(callback, 'replaceState');
13265 }
13266
13267 update.callback = callback;
13268 }
13269
13270 enqueueUpdate(fiber, update);
13271 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
13272
13273 if (root !== null) {
13274 entangleTransitions(root, fiber, lane);
13275 }
13276
13277 {
13278 markStateUpdateScheduled(fiber, lane);
13279 }
13280 },
13281 enqueueForceUpdate: function (inst, callback) {
13282 var fiber = get(inst);
13283 var eventTime = requestEventTime();
13284 var lane = requestUpdateLane(fiber);
13285 var update = createUpdate(eventTime, lane);
13286 update.tag = ForceUpdate;
13287
13288 if (callback !== undefined && callback !== null) {
13289 {
13290 warnOnInvalidCallback(callback, 'forceUpdate');
13291 }
13292
13293 update.callback = callback;
13294 }
13295
13296 enqueueUpdate(fiber, update);
13297 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
13298
13299 if (root !== null) {
13300 entangleTransitions(root, fiber, lane);
13301 }
13302
13303 {
13304 markForceUpdateScheduled(fiber, lane);
13305 }
13306 }
13307 };
13308
13309 function checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext) {
13310 var instance = workInProgress.stateNode;
13311
13312 if (typeof instance.shouldComponentUpdate === 'function') {
13313 var shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
13314
13315 {
13316 if ( workInProgress.mode & StrictLegacyMode) {
13317 setIsStrictModeForDevtools(true);
13318
13319 try {
13320 // Invoke the function an extra time to help detect side-effects.
13321 shouldUpdate = instance.shouldComponentUpdate(newProps, newState, nextContext);
13322 } finally {
13323 setIsStrictModeForDevtools(false);
13324 }
13325 }
13326
13327 if (shouldUpdate === undefined) {
13328 error('%s.shouldComponentUpdate(): Returned undefined instead of a ' + 'boolean value. Make sure to return true or false.', getComponentNameFromType(ctor) || 'Component');
13329 }
13330 }
13331
13332 return shouldUpdate;
13333 }
13334
13335 if (ctor.prototype && ctor.prototype.isPureReactComponent) {
13336 return !shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState);
13337 }
13338
13339 return true;
13340 }
13341
13342 function checkClassInstance(workInProgress, ctor, newProps) {
13343 var instance = workInProgress.stateNode;
13344
13345 {
13346 var name = getComponentNameFromType(ctor) || 'Component';
13347 var renderPresent = instance.render;
13348
13349 if (!renderPresent) {
13350 if (ctor.prototype && typeof ctor.prototype.render === 'function') {
13351 error('%s(...): No `render` method found on the returned component ' + 'instance: did you accidentally return an object from the constructor?', name);
13352 } else {
13353 error('%s(...): No `render` method found on the returned component ' + 'instance: you may have forgotten to define `render`.', name);
13354 }
13355 }
13356
13357 if (instance.getInitialState && !instance.getInitialState.isReactClassApproved && !instance.state) {
13358 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);
13359 }
13360
13361 if (instance.getDefaultProps && !instance.getDefaultProps.isReactClassApproved) {
13362 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);
13363 }
13364
13365 if (instance.propTypes) {
13366 error('propTypes was defined as an instance property on %s. Use a static ' + 'property to define propTypes instead.', name);
13367 }
13368
13369 if (instance.contextType) {
13370 error('contextType was defined as an instance property on %s. Use a static ' + 'property to define contextType instead.', name);
13371 }
13372
13373 {
13374 if (instance.contextTypes) {
13375 error('contextTypes was defined as an instance property on %s. Use a static ' + 'property to define contextTypes instead.', name);
13376 }
13377
13378 if (ctor.contextType && ctor.contextTypes && !didWarnAboutContextTypeAndContextTypes.has(ctor)) {
13379 didWarnAboutContextTypeAndContextTypes.add(ctor);
13380
13381 error('%s declares both contextTypes and contextType static properties. ' + 'The legacy contextTypes property will be ignored.', name);
13382 }
13383 }
13384
13385 if (typeof instance.componentShouldUpdate === 'function') {
13386 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);
13387 }
13388
13389 if (ctor.prototype && ctor.prototype.isPureReactComponent && typeof instance.shouldComponentUpdate !== 'undefined') {
13390 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');
13391 }
13392
13393 if (typeof instance.componentDidUnmount === 'function') {
13394 error('%s has a method called ' + 'componentDidUnmount(). But there is no such lifecycle method. ' + 'Did you mean componentWillUnmount()?', name);
13395 }
13396
13397 if (typeof instance.componentDidReceiveProps === 'function') {
13398 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);
13399 }
13400
13401 if (typeof instance.componentWillRecieveProps === 'function') {
13402 error('%s has a method called ' + 'componentWillRecieveProps(). Did you mean componentWillReceiveProps()?', name);
13403 }
13404
13405 if (typeof instance.UNSAFE_componentWillRecieveProps === 'function') {
13406 error('%s has a method called ' + 'UNSAFE_componentWillRecieveProps(). Did you mean UNSAFE_componentWillReceiveProps()?', name);
13407 }
13408
13409 var hasMutatedProps = instance.props !== newProps;
13410
13411 if (instance.props !== undefined && hasMutatedProps) {
13412 error('%s(...): When calling super() in `%s`, make sure to pass ' + "up the same props that your component's constructor was passed.", name, name);
13413 }
13414
13415 if (instance.defaultProps) {
13416 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);
13417 }
13418
13419 if (typeof instance.getSnapshotBeforeUpdate === 'function' && typeof instance.componentDidUpdate !== 'function' && !didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.has(ctor)) {
13420 didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate.add(ctor);
13421
13422 error('%s: getSnapshotBeforeUpdate() should be used with componentDidUpdate(). ' + 'This component defines getSnapshotBeforeUpdate() only.', getComponentNameFromType(ctor));
13423 }
13424
13425 if (typeof instance.getDerivedStateFromProps === 'function') {
13426 error('%s: getDerivedStateFromProps() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
13427 }
13428
13429 if (typeof instance.getDerivedStateFromError === 'function') {
13430 error('%s: getDerivedStateFromError() is defined as an instance method ' + 'and will be ignored. Instead, declare it as a static method.', name);
13431 }
13432
13433 if (typeof ctor.getSnapshotBeforeUpdate === 'function') {
13434 error('%s: getSnapshotBeforeUpdate() is defined as a static method ' + 'and will be ignored. Instead, declare it as an instance method.', name);
13435 }
13436
13437 var _state = instance.state;
13438
13439 if (_state && (typeof _state !== 'object' || isArray(_state))) {
13440 error('%s.state: must be set to an object or null', name);
13441 }
13442
13443 if (typeof instance.getChildContext === 'function' && typeof ctor.childContextTypes !== 'object') {
13444 error('%s.getChildContext(): childContextTypes must be defined in order to ' + 'use getChildContext().', name);
13445 }
13446 }
13447 }
13448
13449 function adoptClassInstance(workInProgress, instance) {
13450 instance.updater = classComponentUpdater;
13451 workInProgress.stateNode = instance; // The instance needs access to the fiber so that it can schedule updates
13452
13453 set(instance, workInProgress);
13454
13455 {
13456 instance._reactInternalInstance = fakeInternalInstance;
13457 }
13458 }
13459
13460 function constructClassInstance(workInProgress, ctor, props) {
13461 var isLegacyContextConsumer = false;
13462 var unmaskedContext = emptyContextObject;
13463 var context = emptyContextObject;
13464 var contextType = ctor.contextType;
13465
13466 {
13467 if ('contextType' in ctor) {
13468 var isValid = // Allow null for conditional declaration
13469 contextType === null || contextType !== undefined && contextType.$$typeof === REACT_CONTEXT_TYPE && contextType._context === undefined; // Not a <Context.Consumer>
13470
13471 if (!isValid && !didWarnAboutInvalidateContextType.has(ctor)) {
13472 didWarnAboutInvalidateContextType.add(ctor);
13473 var addendum = '';
13474
13475 if (contextType === undefined) {
13476 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.';
13477 } else if (typeof contextType !== 'object') {
13478 addendum = ' However, it is set to a ' + typeof contextType + '.';
13479 } else if (contextType.$$typeof === REACT_PROVIDER_TYPE) {
13480 addendum = ' Did you accidentally pass the Context.Provider instead?';
13481 } else if (contextType._context !== undefined) {
13482 // <Context.Consumer>
13483 addendum = ' Did you accidentally pass the Context.Consumer instead?';
13484 } else {
13485 addendum = ' However, it is set to an object with keys {' + Object.keys(contextType).join(', ') + '}.';
13486 }
13487
13488 error('%s defines an invalid contextType. ' + 'contextType should point to the Context object returned by React.createContext().%s', getComponentNameFromType(ctor) || 'Component', addendum);
13489 }
13490 }
13491 }
13492
13493 if (typeof contextType === 'object' && contextType !== null) {
13494 context = readContext(contextType);
13495 } else {
13496 unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13497 var contextTypes = ctor.contextTypes;
13498 isLegacyContextConsumer = contextTypes !== null && contextTypes !== undefined;
13499 context = isLegacyContextConsumer ? getMaskedContext(workInProgress, unmaskedContext) : emptyContextObject;
13500 }
13501
13502 var instance = new ctor(props, context); // Instantiate twice to help detect side-effects.
13503
13504 {
13505 if ( workInProgress.mode & StrictLegacyMode) {
13506 setIsStrictModeForDevtools(true);
13507
13508 try {
13509 instance = new ctor(props, context); // eslint-disable-line no-new
13510 } finally {
13511 setIsStrictModeForDevtools(false);
13512 }
13513 }
13514 }
13515
13516 var state = workInProgress.memoizedState = instance.state !== null && instance.state !== undefined ? instance.state : null;
13517 adoptClassInstance(workInProgress, instance);
13518
13519 {
13520 if (typeof ctor.getDerivedStateFromProps === 'function' && state === null) {
13521 var componentName = getComponentNameFromType(ctor) || 'Component';
13522
13523 if (!didWarnAboutUninitializedState.has(componentName)) {
13524 didWarnAboutUninitializedState.add(componentName);
13525
13526 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);
13527 }
13528 } // If new component APIs are defined, "unsafe" lifecycles won't be called.
13529 // Warn about these lifecycles if they are present.
13530 // Don't warn about react-lifecycles-compat polyfilled methods though.
13531
13532
13533 if (typeof ctor.getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function') {
13534 var foundWillMountName = null;
13535 var foundWillReceivePropsName = null;
13536 var foundWillUpdateName = null;
13537
13538 if (typeof instance.componentWillMount === 'function' && instance.componentWillMount.__suppressDeprecationWarning !== true) {
13539 foundWillMountName = 'componentWillMount';
13540 } else if (typeof instance.UNSAFE_componentWillMount === 'function') {
13541 foundWillMountName = 'UNSAFE_componentWillMount';
13542 }
13543
13544 if (typeof instance.componentWillReceiveProps === 'function' && instance.componentWillReceiveProps.__suppressDeprecationWarning !== true) {
13545 foundWillReceivePropsName = 'componentWillReceiveProps';
13546 } else if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13547 foundWillReceivePropsName = 'UNSAFE_componentWillReceiveProps';
13548 }
13549
13550 if (typeof instance.componentWillUpdate === 'function' && instance.componentWillUpdate.__suppressDeprecationWarning !== true) {
13551 foundWillUpdateName = 'componentWillUpdate';
13552 } else if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13553 foundWillUpdateName = 'UNSAFE_componentWillUpdate';
13554 }
13555
13556 if (foundWillMountName !== null || foundWillReceivePropsName !== null || foundWillUpdateName !== null) {
13557 var _componentName = getComponentNameFromType(ctor) || 'Component';
13558
13559 var newApiName = typeof ctor.getDerivedStateFromProps === 'function' ? 'getDerivedStateFromProps()' : 'getSnapshotBeforeUpdate()';
13560
13561 if (!didWarnAboutLegacyLifecyclesAndDerivedState.has(_componentName)) {
13562 didWarnAboutLegacyLifecyclesAndDerivedState.add(_componentName);
13563
13564 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 : '');
13565 }
13566 }
13567 }
13568 } // Cache unmasked context so we can avoid recreating masked context unless necessary.
13569 // ReactFiberContext usually updates this cache but can't for newly-created instances.
13570
13571
13572 if (isLegacyContextConsumer) {
13573 cacheContext(workInProgress, unmaskedContext, context);
13574 }
13575
13576 return instance;
13577 }
13578
13579 function callComponentWillMount(workInProgress, instance) {
13580 var oldState = instance.state;
13581
13582 if (typeof instance.componentWillMount === 'function') {
13583 instance.componentWillMount();
13584 }
13585
13586 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13587 instance.UNSAFE_componentWillMount();
13588 }
13589
13590 if (oldState !== instance.state) {
13591 {
13592 error('%s.componentWillMount(): Assigning directly to this.state is ' + "deprecated (except inside a component's " + 'constructor). Use setState instead.', getComponentNameFromFiber(workInProgress) || 'Component');
13593 }
13594
13595 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13596 }
13597 }
13598
13599 function callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext) {
13600 var oldState = instance.state;
13601
13602 if (typeof instance.componentWillReceiveProps === 'function') {
13603 instance.componentWillReceiveProps(newProps, nextContext);
13604 }
13605
13606 if (typeof instance.UNSAFE_componentWillReceiveProps === 'function') {
13607 instance.UNSAFE_componentWillReceiveProps(newProps, nextContext);
13608 }
13609
13610 if (instance.state !== oldState) {
13611 {
13612 var componentName = getComponentNameFromFiber(workInProgress) || 'Component';
13613
13614 if (!didWarnAboutStateAssignmentForComponent.has(componentName)) {
13615 didWarnAboutStateAssignmentForComponent.add(componentName);
13616
13617 error('%s.componentWillReceiveProps(): Assigning directly to ' + "this.state is deprecated (except inside a component's " + 'constructor). Use setState instead.', componentName);
13618 }
13619 }
13620
13621 classComponentUpdater.enqueueReplaceState(instance, instance.state, null);
13622 }
13623 } // Invokes the mount life-cycles on a previously never rendered instance.
13624
13625
13626 function mountClassInstance(workInProgress, ctor, newProps, renderLanes) {
13627 {
13628 checkClassInstance(workInProgress, ctor, newProps);
13629 }
13630
13631 var instance = workInProgress.stateNode;
13632 instance.props = newProps;
13633 instance.state = workInProgress.memoizedState;
13634 instance.refs = emptyRefsObject;
13635 initializeUpdateQueue(workInProgress);
13636 var contextType = ctor.contextType;
13637
13638 if (typeof contextType === 'object' && contextType !== null) {
13639 instance.context = readContext(contextType);
13640 } else {
13641 var unmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13642 instance.context = getMaskedContext(workInProgress, unmaskedContext);
13643 }
13644
13645 {
13646 if (instance.state === newProps) {
13647 var componentName = getComponentNameFromType(ctor) || 'Component';
13648
13649 if (!didWarnAboutDirectlyAssigningPropsToState.has(componentName)) {
13650 didWarnAboutDirectlyAssigningPropsToState.add(componentName);
13651
13652 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);
13653 }
13654 }
13655
13656 if (workInProgress.mode & StrictLegacyMode) {
13657 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, instance);
13658 }
13659
13660 {
13661 ReactStrictModeWarnings.recordUnsafeLifecycleWarnings(workInProgress, instance);
13662 }
13663 }
13664
13665 instance.state = workInProgress.memoizedState;
13666 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13667
13668 if (typeof getDerivedStateFromProps === 'function') {
13669 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13670 instance.state = workInProgress.memoizedState;
13671 } // In order to support react-lifecycles-compat polyfilled components,
13672 // Unsafe lifecycles should not be invoked for components using the new APIs.
13673
13674
13675 if (typeof ctor.getDerivedStateFromProps !== 'function' && typeof instance.getSnapshotBeforeUpdate !== 'function' && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13676 callComponentWillMount(workInProgress, instance); // If we had additional state updates during this life-cycle, let's
13677 // process them now.
13678
13679 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
13680 instance.state = workInProgress.memoizedState;
13681 }
13682
13683 if (typeof instance.componentDidMount === 'function') {
13684 var fiberFlags = Update;
13685
13686 {
13687 fiberFlags |= LayoutStatic;
13688 }
13689
13690 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
13691 fiberFlags |= MountLayoutDev;
13692 }
13693
13694 workInProgress.flags |= fiberFlags;
13695 }
13696 }
13697
13698 function resumeMountClassInstance(workInProgress, ctor, newProps, renderLanes) {
13699 var instance = workInProgress.stateNode;
13700 var oldProps = workInProgress.memoizedProps;
13701 instance.props = oldProps;
13702 var oldContext = instance.context;
13703 var contextType = ctor.contextType;
13704 var nextContext = emptyContextObject;
13705
13706 if (typeof contextType === 'object' && contextType !== null) {
13707 nextContext = readContext(contextType);
13708 } else {
13709 var nextLegacyUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13710 nextContext = getMaskedContext(workInProgress, nextLegacyUnmaskedContext);
13711 }
13712
13713 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13714 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13715 // ever the previously attempted to render - not the "current". However,
13716 // during componentDidUpdate we pass the "current" props.
13717 // In order to support react-lifecycles-compat polyfilled components,
13718 // Unsafe lifecycles should not be invoked for components using the new APIs.
13719
13720 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13721 if (oldProps !== newProps || oldContext !== nextContext) {
13722 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13723 }
13724 }
13725
13726 resetHasForceUpdateBeforeProcessing();
13727 var oldState = workInProgress.memoizedState;
13728 var newState = instance.state = oldState;
13729 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
13730 newState = workInProgress.memoizedState;
13731
13732 if (oldProps === newProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing()) {
13733 // If an update was already in progress, we should schedule an Update
13734 // effect even though we're bailing out, so that cWU/cDU are called.
13735 if (typeof instance.componentDidMount === 'function') {
13736 var fiberFlags = Update;
13737
13738 {
13739 fiberFlags |= LayoutStatic;
13740 }
13741
13742 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
13743 fiberFlags |= MountLayoutDev;
13744 }
13745
13746 workInProgress.flags |= fiberFlags;
13747 }
13748
13749 return false;
13750 }
13751
13752 if (typeof getDerivedStateFromProps === 'function') {
13753 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13754 newState = workInProgress.memoizedState;
13755 }
13756
13757 var shouldUpdate = checkHasForceUpdateAfterProcessing() || checkShouldComponentUpdate(workInProgress, ctor, oldProps, newProps, oldState, newState, nextContext);
13758
13759 if (shouldUpdate) {
13760 // In order to support react-lifecycles-compat polyfilled components,
13761 // Unsafe lifecycles should not be invoked for components using the new APIs.
13762 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillMount === 'function' || typeof instance.componentWillMount === 'function')) {
13763 if (typeof instance.componentWillMount === 'function') {
13764 instance.componentWillMount();
13765 }
13766
13767 if (typeof instance.UNSAFE_componentWillMount === 'function') {
13768 instance.UNSAFE_componentWillMount();
13769 }
13770 }
13771
13772 if (typeof instance.componentDidMount === 'function') {
13773 var _fiberFlags = Update;
13774
13775 {
13776 _fiberFlags |= LayoutStatic;
13777 }
13778
13779 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
13780 _fiberFlags |= MountLayoutDev;
13781 }
13782
13783 workInProgress.flags |= _fiberFlags;
13784 }
13785 } else {
13786 // If an update was already in progress, we should schedule an Update
13787 // effect even though we're bailing out, so that cWU/cDU are called.
13788 if (typeof instance.componentDidMount === 'function') {
13789 var _fiberFlags2 = Update;
13790
13791 {
13792 _fiberFlags2 |= LayoutStatic;
13793 }
13794
13795 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
13796 _fiberFlags2 |= MountLayoutDev;
13797 }
13798
13799 workInProgress.flags |= _fiberFlags2;
13800 } // If shouldComponentUpdate returned false, we should still update the
13801 // memoized state to indicate that this work can be reused.
13802
13803
13804 workInProgress.memoizedProps = newProps;
13805 workInProgress.memoizedState = newState;
13806 } // Update the existing instance's state, props, and context pointers even
13807 // if shouldComponentUpdate returns false.
13808
13809
13810 instance.props = newProps;
13811 instance.state = newState;
13812 instance.context = nextContext;
13813 return shouldUpdate;
13814 } // Invokes the update life-cycles and returns false if it shouldn't rerender.
13815
13816
13817 function updateClassInstance(current, workInProgress, ctor, newProps, renderLanes) {
13818 var instance = workInProgress.stateNode;
13819 cloneUpdateQueue(current, workInProgress);
13820 var unresolvedOldProps = workInProgress.memoizedProps;
13821 var oldProps = workInProgress.type === workInProgress.elementType ? unresolvedOldProps : resolveDefaultProps(workInProgress.type, unresolvedOldProps);
13822 instance.props = oldProps;
13823 var unresolvedNewProps = workInProgress.pendingProps;
13824 var oldContext = instance.context;
13825 var contextType = ctor.contextType;
13826 var nextContext = emptyContextObject;
13827
13828 if (typeof contextType === 'object' && contextType !== null) {
13829 nextContext = readContext(contextType);
13830 } else {
13831 var nextUnmaskedContext = getUnmaskedContext(workInProgress, ctor, true);
13832 nextContext = getMaskedContext(workInProgress, nextUnmaskedContext);
13833 }
13834
13835 var getDerivedStateFromProps = ctor.getDerivedStateFromProps;
13836 var hasNewLifecycles = typeof getDerivedStateFromProps === 'function' || typeof instance.getSnapshotBeforeUpdate === 'function'; // Note: During these life-cycles, instance.props/instance.state are what
13837 // ever the previously attempted to render - not the "current". However,
13838 // during componentDidUpdate we pass the "current" props.
13839 // In order to support react-lifecycles-compat polyfilled components,
13840 // Unsafe lifecycles should not be invoked for components using the new APIs.
13841
13842 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillReceiveProps === 'function' || typeof instance.componentWillReceiveProps === 'function')) {
13843 if (unresolvedOldProps !== unresolvedNewProps || oldContext !== nextContext) {
13844 callComponentWillReceiveProps(workInProgress, instance, newProps, nextContext);
13845 }
13846 }
13847
13848 resetHasForceUpdateBeforeProcessing();
13849 var oldState = workInProgress.memoizedState;
13850 var newState = instance.state = oldState;
13851 processUpdateQueue(workInProgress, newProps, instance, renderLanes);
13852 newState = workInProgress.memoizedState;
13853
13854 if (unresolvedOldProps === unresolvedNewProps && oldState === newState && !hasContextChanged() && !checkHasForceUpdateAfterProcessing() && !(enableLazyContextPropagation )) {
13855 // If an update was already in progress, we should schedule an Update
13856 // effect even though we're bailing out, so that cWU/cDU are called.
13857 if (typeof instance.componentDidUpdate === 'function') {
13858 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13859 workInProgress.flags |= Update;
13860 }
13861 }
13862
13863 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13864 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13865 workInProgress.flags |= Snapshot;
13866 }
13867 }
13868
13869 return false;
13870 }
13871
13872 if (typeof getDerivedStateFromProps === 'function') {
13873 applyDerivedStateFromProps(workInProgress, ctor, getDerivedStateFromProps, newProps);
13874 newState = workInProgress.memoizedState;
13875 }
13876
13877 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,
13878 // both before and after `shouldComponentUpdate` has been called. Not ideal,
13879 // but I'm loath to refactor this function. This only happens for memoized
13880 // components so it's not that common.
13881 enableLazyContextPropagation ;
13882
13883 if (shouldUpdate) {
13884 // In order to support react-lifecycles-compat polyfilled components,
13885 // Unsafe lifecycles should not be invoked for components using the new APIs.
13886 if (!hasNewLifecycles && (typeof instance.UNSAFE_componentWillUpdate === 'function' || typeof instance.componentWillUpdate === 'function')) {
13887 if (typeof instance.componentWillUpdate === 'function') {
13888 instance.componentWillUpdate(newProps, newState, nextContext);
13889 }
13890
13891 if (typeof instance.UNSAFE_componentWillUpdate === 'function') {
13892 instance.UNSAFE_componentWillUpdate(newProps, newState, nextContext);
13893 }
13894 }
13895
13896 if (typeof instance.componentDidUpdate === 'function') {
13897 workInProgress.flags |= Update;
13898 }
13899
13900 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13901 workInProgress.flags |= Snapshot;
13902 }
13903 } else {
13904 // If an update was already in progress, we should schedule an Update
13905 // effect even though we're bailing out, so that cWU/cDU are called.
13906 if (typeof instance.componentDidUpdate === 'function') {
13907 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13908 workInProgress.flags |= Update;
13909 }
13910 }
13911
13912 if (typeof instance.getSnapshotBeforeUpdate === 'function') {
13913 if (unresolvedOldProps !== current.memoizedProps || oldState !== current.memoizedState) {
13914 workInProgress.flags |= Snapshot;
13915 }
13916 } // If shouldComponentUpdate returned false, we should still update the
13917 // memoized props/state to indicate that this work can be reused.
13918
13919
13920 workInProgress.memoizedProps = newProps;
13921 workInProgress.memoizedState = newState;
13922 } // Update the existing instance's state, props, and context pointers even
13923 // if shouldComponentUpdate returns false.
13924
13925
13926 instance.props = newProps;
13927 instance.state = newState;
13928 instance.context = nextContext;
13929 return shouldUpdate;
13930 }
13931
13932 // TODO: Use the unified fiber stack module instead of this local one?
13933 // Intentionally not using it yet to derisk the initial implementation, because
13934 // the way we push/pop these values is a bit unusual. If there's a mistake, I'd
13935 // rather the ids be wrong than crash the whole reconciler.
13936 var forkStack = [];
13937 var forkStackIndex = 0;
13938 var treeForkProvider = null;
13939 var treeForkCount = 0;
13940 var idStack = [];
13941 var idStackIndex = 0;
13942 var treeContextProvider = null;
13943 var treeContextId = 1;
13944 var treeContextOverflow = '';
13945 function isForkedChild(workInProgress) {
13946 warnIfNotHydrating();
13947 return (workInProgress.flags & Forked) !== NoFlags;
13948 }
13949 function getForksAtLevel(workInProgress) {
13950 warnIfNotHydrating();
13951 return treeForkCount;
13952 }
13953 function getTreeId() {
13954 var overflow = treeContextOverflow;
13955 var idWithLeadingBit = treeContextId;
13956 var id = idWithLeadingBit & ~getLeadingBit(idWithLeadingBit);
13957 return id.toString(32) + overflow;
13958 }
13959 function pushTreeFork(workInProgress, totalChildren) {
13960 // This is called right after we reconcile an array (or iterator) of child
13961 // fibers, because that's the only place where we know how many children in
13962 // the whole set without doing extra work later, or storing addtional
13963 // information on the fiber.
13964 //
13965 // That's why this function is separate from pushTreeId — it's called during
13966 // the render phase of the fork parent, not the child, which is where we push
13967 // the other context values.
13968 //
13969 // In the Fizz implementation this is much simpler because the child is
13970 // rendered in the same callstack as the parent.
13971 //
13972 // It might be better to just add a `forks` field to the Fiber type. It would
13973 // make this module simpler.
13974 warnIfNotHydrating();
13975 forkStack[forkStackIndex++] = treeForkCount;
13976 forkStack[forkStackIndex++] = treeForkProvider;
13977 treeForkProvider = workInProgress;
13978 treeForkCount = totalChildren;
13979 }
13980 function pushTreeId(workInProgress, totalChildren, index) {
13981 warnIfNotHydrating();
13982 idStack[idStackIndex++] = treeContextId;
13983 idStack[idStackIndex++] = treeContextOverflow;
13984 idStack[idStackIndex++] = treeContextProvider;
13985 treeContextProvider = workInProgress;
13986 var baseIdWithLeadingBit = treeContextId;
13987 var baseOverflow = treeContextOverflow; // The leftmost 1 marks the end of the sequence, non-inclusive. It's not part
13988 // of the id; we use it to account for leading 0s.
13989
13990 var baseLength = getBitLength(baseIdWithLeadingBit) - 1;
13991 var baseId = baseIdWithLeadingBit & ~(1 << baseLength);
13992 var slot = index + 1;
13993 var length = getBitLength(totalChildren) + baseLength; // 30 is the max length we can store without overflowing, taking into
13994 // consideration the leading 1 we use to mark the end of the sequence.
13995
13996 if (length > 30) {
13997 // We overflowed the bitwise-safe range. Fall back to slower algorithm.
13998 // This branch assumes the length of the base id is greater than 5; it won't
13999 // work for smaller ids, because you need 5 bits per character.
14000 //
14001 // We encode the id in multiple steps: first the base id, then the
14002 // remaining digits.
14003 //
14004 // Each 5 bit sequence corresponds to a single base 32 character. So for
14005 // example, if the current id is 23 bits long, we can convert 20 of those
14006 // bits into a string of 4 characters, with 3 bits left over.
14007 //
14008 // First calculate how many bits in the base id represent a complete
14009 // sequence of characters.
14010 var numberOfOverflowBits = baseLength - baseLength % 5; // Then create a bitmask that selects only those bits.
14011
14012 var newOverflowBits = (1 << numberOfOverflowBits) - 1; // Select the bits, and convert them to a base 32 string.
14013
14014 var newOverflow = (baseId & newOverflowBits).toString(32); // Now we can remove those bits from the base id.
14015
14016 var restOfBaseId = baseId >> numberOfOverflowBits;
14017 var restOfBaseLength = baseLength - numberOfOverflowBits; // Finally, encode the rest of the bits using the normal algorithm. Because
14018 // we made more room, this time it won't overflow.
14019
14020 var restOfLength = getBitLength(totalChildren) + restOfBaseLength;
14021 var restOfNewBits = slot << restOfBaseLength;
14022 var id = restOfNewBits | restOfBaseId;
14023 var overflow = newOverflow + baseOverflow;
14024 treeContextId = 1 << restOfLength | id;
14025 treeContextOverflow = overflow;
14026 } else {
14027 // Normal path
14028 var newBits = slot << baseLength;
14029
14030 var _id = newBits | baseId;
14031
14032 var _overflow = baseOverflow;
14033 treeContextId = 1 << length | _id;
14034 treeContextOverflow = _overflow;
14035 }
14036 }
14037 function pushMaterializedTreeId(workInProgress) {
14038 warnIfNotHydrating(); // This component materialized an id. This will affect any ids that appear
14039 // in its children.
14040
14041 var returnFiber = workInProgress.return;
14042
14043 if (returnFiber !== null) {
14044 var numberOfForks = 1;
14045 var slotIndex = 0;
14046 pushTreeFork(workInProgress, numberOfForks);
14047 pushTreeId(workInProgress, numberOfForks, slotIndex);
14048 }
14049 }
14050
14051 function getBitLength(number) {
14052 return 32 - clz32(number);
14053 }
14054
14055 function getLeadingBit(id) {
14056 return 1 << getBitLength(id) - 1;
14057 }
14058
14059 function popTreeContext(workInProgress) {
14060 // Restore the previous values.
14061 // This is a bit more complicated than other context-like modules in Fiber
14062 // because the same Fiber may appear on the stack multiple times and for
14063 // different reasons. We have to keep popping until the work-in-progress is
14064 // no longer at the top of the stack.
14065 while (workInProgress === treeForkProvider) {
14066 treeForkProvider = forkStack[--forkStackIndex];
14067 forkStack[forkStackIndex] = null;
14068 treeForkCount = forkStack[--forkStackIndex];
14069 forkStack[forkStackIndex] = null;
14070 }
14071
14072 while (workInProgress === treeContextProvider) {
14073 treeContextProvider = idStack[--idStackIndex];
14074 idStack[idStackIndex] = null;
14075 treeContextOverflow = idStack[--idStackIndex];
14076 idStack[idStackIndex] = null;
14077 treeContextId = idStack[--idStackIndex];
14078 idStack[idStackIndex] = null;
14079 }
14080 }
14081 function getSuspendedTreeContext() {
14082 warnIfNotHydrating();
14083
14084 if (treeContextProvider !== null) {
14085 return {
14086 id: treeContextId,
14087 overflow: treeContextOverflow
14088 };
14089 } else {
14090 return null;
14091 }
14092 }
14093 function restoreSuspendedTreeContext(workInProgress, suspendedContext) {
14094 warnIfNotHydrating();
14095 idStack[idStackIndex++] = treeContextId;
14096 idStack[idStackIndex++] = treeContextOverflow;
14097 idStack[idStackIndex++] = treeContextProvider;
14098 treeContextId = suspendedContext.id;
14099 treeContextOverflow = suspendedContext.overflow;
14100 treeContextProvider = workInProgress;
14101 }
14102
14103 function warnIfNotHydrating() {
14104 {
14105 if (!getIsHydrating()) {
14106 error('Expected to be hydrating. This is a bug in React. Please file ' + 'an issue.');
14107 }
14108 }
14109 }
14110
14111 // This may have been an insertion or a hydration.
14112
14113 var hydrationParentFiber = null;
14114 var nextHydratableInstance = null;
14115 var isHydrating = false;
14116 var didSuspend = false; // Hydration errors that were thrown inside this boundary
14117
14118 var hydrationErrors = null;
14119
14120 function warnIfHydrating() {
14121 {
14122 if (isHydrating) {
14123 error('We should not be hydrating here. This is a bug in React. Please file a bug.');
14124 }
14125 }
14126 }
14127
14128 function markDidSuspendWhileHydratingDEV() {
14129 {
14130 didSuspend = true;
14131 }
14132 }
14133
14134 function enterHydrationState(fiber) {
14135
14136 var parentInstance = fiber.stateNode.containerInfo;
14137 nextHydratableInstance = getFirstHydratableChildWithinContainer(parentInstance);
14138 hydrationParentFiber = fiber;
14139 isHydrating = true;
14140 hydrationErrors = null;
14141 didSuspend = false;
14142 return true;
14143 }
14144
14145 function reenterHydrationStateFromDehydratedSuspenseInstance(fiber, suspenseInstance, treeContext) {
14146
14147 nextHydratableInstance = getFirstHydratableChildWithinSuspenseInstance(suspenseInstance);
14148 hydrationParentFiber = fiber;
14149 isHydrating = true;
14150 hydrationErrors = null;
14151 didSuspend = false;
14152
14153 if (treeContext !== null) {
14154 restoreSuspendedTreeContext(fiber, treeContext);
14155 }
14156
14157 return true;
14158 }
14159
14160 function warnUnhydratedInstance(returnFiber, instance) {
14161 {
14162 switch (returnFiber.tag) {
14163 case HostRoot:
14164 didNotHydrateInstanceWithinContainer(returnFiber.stateNode.containerInfo, instance);
14165 break;
14166
14167 case HostComponent:
14168 didNotHydrateInstance(returnFiber.type, returnFiber.memoizedProps, returnFiber.stateNode, instance);
14169 break;
14170
14171 case SuspenseComponent:
14172 var suspenseState = returnFiber.memoizedState;
14173 if (suspenseState.dehydrated !== null) didNotHydrateInstanceWithinSuspenseInstance(suspenseState.dehydrated, instance);
14174 break;
14175 }
14176 }
14177 }
14178
14179 function deleteHydratableInstance(returnFiber, instance) {
14180 warnUnhydratedInstance(returnFiber, instance);
14181 var childToDelete = createFiberFromHostInstanceForDeletion();
14182 childToDelete.stateNode = instance;
14183 childToDelete.return = returnFiber;
14184 var deletions = returnFiber.deletions;
14185
14186 if (deletions === null) {
14187 returnFiber.deletions = [childToDelete];
14188 returnFiber.flags |= ChildDeletion;
14189 } else {
14190 deletions.push(childToDelete);
14191 }
14192 }
14193
14194 function warnNonhydratedInstance(returnFiber, fiber) {
14195 {
14196 if (didSuspend) {
14197 // Inside a boundary that already suspended. We're currently rendering the
14198 // siblings of a suspended node. The mismatch may be due to the missing
14199 // data, so it's probably a false positive.
14200 return;
14201 }
14202
14203 switch (returnFiber.tag) {
14204 case HostRoot:
14205 {
14206 var parentContainer = returnFiber.stateNode.containerInfo;
14207
14208 switch (fiber.tag) {
14209 case HostComponent:
14210 var type = fiber.type;
14211 var props = fiber.pendingProps;
14212 didNotFindHydratableInstanceWithinContainer(parentContainer, type);
14213 break;
14214
14215 case HostText:
14216 var text = fiber.pendingProps;
14217 didNotFindHydratableTextInstanceWithinContainer(parentContainer, text);
14218 break;
14219 }
14220
14221 break;
14222 }
14223
14224 case HostComponent:
14225 {
14226 var parentType = returnFiber.type;
14227 var parentProps = returnFiber.memoizedProps;
14228 var parentInstance = returnFiber.stateNode;
14229
14230 switch (fiber.tag) {
14231 case HostComponent:
14232 var _type = fiber.type;
14233 var _props = fiber.pendingProps;
14234 didNotFindHydratableInstance(parentType, parentProps, parentInstance, _type);
14235 break;
14236
14237 case HostText:
14238 var _text = fiber.pendingProps;
14239 didNotFindHydratableTextInstance(parentType, parentProps, parentInstance, _text);
14240 break;
14241
14242 case SuspenseComponent:
14243 didNotFindHydratableSuspenseInstance(parentType, parentProps);
14244 break;
14245 }
14246
14247 break;
14248 }
14249
14250 case SuspenseComponent:
14251 {
14252 var suspenseState = returnFiber.memoizedState;
14253 var _parentInstance = suspenseState.dehydrated;
14254 if (_parentInstance !== null) switch (fiber.tag) {
14255 case HostComponent:
14256 var _type2 = fiber.type;
14257 var _props2 = fiber.pendingProps;
14258 didNotFindHydratableInstanceWithinSuspenseInstance(_parentInstance, _type2);
14259 break;
14260
14261 case HostText:
14262 var _text2 = fiber.pendingProps;
14263 didNotFindHydratableTextInstanceWithinSuspenseInstance(_parentInstance, _text2);
14264 break;
14265 }
14266 break;
14267 }
14268
14269 default:
14270 return;
14271 }
14272 }
14273 }
14274
14275 function insertNonHydratedInstance(returnFiber, fiber) {
14276 fiber.flags = fiber.flags & ~Hydrating | Placement;
14277 warnNonhydratedInstance(returnFiber, fiber);
14278 }
14279
14280 function tryHydrate(fiber, nextInstance) {
14281 switch (fiber.tag) {
14282 case HostComponent:
14283 {
14284 var type = fiber.type;
14285 var props = fiber.pendingProps;
14286 var instance = canHydrateInstance(nextInstance, type);
14287
14288 if (instance !== null) {
14289 fiber.stateNode = instance;
14290 hydrationParentFiber = fiber;
14291 nextHydratableInstance = getFirstHydratableChild(instance);
14292 return true;
14293 }
14294
14295 return false;
14296 }
14297
14298 case HostText:
14299 {
14300 var text = fiber.pendingProps;
14301 var textInstance = canHydrateTextInstance(nextInstance, text);
14302
14303 if (textInstance !== null) {
14304 fiber.stateNode = textInstance;
14305 hydrationParentFiber = fiber; // Text Instances don't have children so there's nothing to hydrate.
14306
14307 nextHydratableInstance = null;
14308 return true;
14309 }
14310
14311 return false;
14312 }
14313
14314 case SuspenseComponent:
14315 {
14316 {
14317 var suspenseInstance = canHydrateSuspenseInstance(nextInstance);
14318
14319 if (suspenseInstance !== null) {
14320 var suspenseState = {
14321 dehydrated: suspenseInstance,
14322 treeContext: getSuspendedTreeContext(),
14323 retryLane: OffscreenLane
14324 };
14325 fiber.memoizedState = suspenseState; // Store the dehydrated fragment as a child fiber.
14326 // This simplifies the code for getHostSibling and deleting nodes,
14327 // since it doesn't have to consider all Suspense boundaries and
14328 // check if they're dehydrated ones or not.
14329
14330 var dehydratedFragment = createFiberFromDehydratedFragment(suspenseInstance);
14331 dehydratedFragment.return = fiber;
14332 fiber.child = dehydratedFragment;
14333 hydrationParentFiber = fiber; // While a Suspense Instance does have children, we won't step into
14334 // it during the first pass. Instead, we'll reenter it later.
14335
14336 nextHydratableInstance = null;
14337 return true;
14338 }
14339 }
14340
14341 return false;
14342 }
14343
14344 default:
14345 return false;
14346 }
14347 }
14348
14349 function shouldClientRenderOnMismatch(fiber) {
14350 return (fiber.mode & ConcurrentMode) !== NoMode && (fiber.flags & DidCapture) === NoFlags;
14351 }
14352
14353 function throwOnHydrationMismatch(fiber) {
14354 throw new Error('Hydration failed because the initial UI does not match what was ' + 'rendered on the server.');
14355 }
14356
14357 function tryToClaimNextHydratableInstance(fiber) {
14358 if (!isHydrating) {
14359 return;
14360 }
14361
14362 var nextInstance = nextHydratableInstance;
14363
14364 if (!nextInstance) {
14365 if (shouldClientRenderOnMismatch(fiber)) {
14366 warnNonhydratedInstance(hydrationParentFiber, fiber);
14367 throwOnHydrationMismatch();
14368 } // Nothing to hydrate. Make it an insertion.
14369
14370
14371 insertNonHydratedInstance(hydrationParentFiber, fiber);
14372 isHydrating = false;
14373 hydrationParentFiber = fiber;
14374 return;
14375 }
14376
14377 var firstAttemptedInstance = nextInstance;
14378
14379 if (!tryHydrate(fiber, nextInstance)) {
14380 if (shouldClientRenderOnMismatch(fiber)) {
14381 warnNonhydratedInstance(hydrationParentFiber, fiber);
14382 throwOnHydrationMismatch();
14383 } // If we can't hydrate this instance let's try the next one.
14384 // We use this as a heuristic. It's based on intuition and not data so it
14385 // might be flawed or unnecessary.
14386
14387
14388 nextInstance = getNextHydratableSibling(firstAttemptedInstance);
14389 var prevHydrationParentFiber = hydrationParentFiber;
14390
14391 if (!nextInstance || !tryHydrate(fiber, nextInstance)) {
14392 // Nothing to hydrate. Make it an insertion.
14393 insertNonHydratedInstance(hydrationParentFiber, fiber);
14394 isHydrating = false;
14395 hydrationParentFiber = fiber;
14396 return;
14397 } // We matched the next one, we'll now assume that the first one was
14398 // superfluous and we'll delete it. Since we can't eagerly delete it
14399 // we'll have to schedule a deletion. To do that, this node needs a dummy
14400 // fiber associated with it.
14401
14402
14403 deleteHydratableInstance(prevHydrationParentFiber, firstAttemptedInstance);
14404 }
14405 }
14406
14407 function prepareToHydrateHostInstance(fiber, rootContainerInstance, hostContext) {
14408
14409 var instance = fiber.stateNode;
14410 var shouldWarnIfMismatchDev = !didSuspend;
14411 var updatePayload = hydrateInstance(instance, fiber.type, fiber.memoizedProps, rootContainerInstance, hostContext, fiber, shouldWarnIfMismatchDev); // TODO: Type this specific to this type of component.
14412
14413 fiber.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
14414 // is a new ref we mark this as an update.
14415
14416 if (updatePayload !== null) {
14417 return true;
14418 }
14419
14420 return false;
14421 }
14422
14423 function prepareToHydrateHostTextInstance(fiber) {
14424
14425 var textInstance = fiber.stateNode;
14426 var textContent = fiber.memoizedProps;
14427 var shouldUpdate = hydrateTextInstance(textInstance, textContent, fiber);
14428
14429 if (shouldUpdate) {
14430 // We assume that prepareToHydrateHostTextInstance is called in a context where the
14431 // hydration parent is the parent host component of this host text.
14432 var returnFiber = hydrationParentFiber;
14433
14434 if (returnFiber !== null) {
14435 var isConcurrentMode = (returnFiber.mode & ConcurrentMode) !== NoMode;
14436
14437 switch (returnFiber.tag) {
14438 case HostRoot:
14439 {
14440 var parentContainer = returnFiber.stateNode.containerInfo;
14441 didNotMatchHydratedContainerTextInstance(parentContainer, textInstance, textContent, // TODO: Delete this argument when we remove the legacy root API.
14442 isConcurrentMode);
14443 break;
14444 }
14445
14446 case HostComponent:
14447 {
14448 var parentType = returnFiber.type;
14449 var parentProps = returnFiber.memoizedProps;
14450 var parentInstance = returnFiber.stateNode;
14451 didNotMatchHydratedTextInstance(parentType, parentProps, parentInstance, textInstance, textContent, // TODO: Delete this argument when we remove the legacy root API.
14452 isConcurrentMode);
14453 break;
14454 }
14455 }
14456 }
14457 }
14458
14459 return shouldUpdate;
14460 }
14461
14462 function prepareToHydrateHostSuspenseInstance(fiber) {
14463
14464 var suspenseState = fiber.memoizedState;
14465 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
14466
14467 if (!suspenseInstance) {
14468 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.');
14469 }
14470
14471 hydrateSuspenseInstance(suspenseInstance, fiber);
14472 }
14473
14474 function skipPastDehydratedSuspenseInstance(fiber) {
14475
14476 var suspenseState = fiber.memoizedState;
14477 var suspenseInstance = suspenseState !== null ? suspenseState.dehydrated : null;
14478
14479 if (!suspenseInstance) {
14480 throw new Error('Expected to have a hydrated suspense instance. ' + 'This error is likely caused by a bug in React. Please file an issue.');
14481 }
14482
14483 return getNextHydratableInstanceAfterSuspenseInstance(suspenseInstance);
14484 }
14485
14486 function popToNextHostParent(fiber) {
14487 var parent = fiber.return;
14488
14489 while (parent !== null && parent.tag !== HostComponent && parent.tag !== HostRoot && parent.tag !== SuspenseComponent) {
14490 parent = parent.return;
14491 }
14492
14493 hydrationParentFiber = parent;
14494 }
14495
14496 function popHydrationState(fiber) {
14497
14498 if (fiber !== hydrationParentFiber) {
14499 // We're deeper than the current hydration context, inside an inserted
14500 // tree.
14501 return false;
14502 }
14503
14504 if (!isHydrating) {
14505 // If we're not currently hydrating but we're in a hydration context, then
14506 // we were an insertion and now need to pop up reenter hydration of our
14507 // siblings.
14508 popToNextHostParent(fiber);
14509 isHydrating = true;
14510 return false;
14511 } // If we have any remaining hydratable nodes, we need to delete them now.
14512 // We only do this deeper than head and body since they tend to have random
14513 // other nodes in them. We also ignore components with pure text content in
14514 // side of them. We also don't delete anything inside the root container.
14515
14516
14517 if (fiber.tag !== HostRoot && (fiber.tag !== HostComponent || shouldDeleteUnhydratedTailInstances(fiber.type) && !shouldSetTextContent(fiber.type, fiber.memoizedProps))) {
14518 var nextInstance = nextHydratableInstance;
14519
14520 if (nextInstance) {
14521 if (shouldClientRenderOnMismatch(fiber)) {
14522 warnIfUnhydratedTailNodes(fiber);
14523 throwOnHydrationMismatch();
14524 } else {
14525 while (nextInstance) {
14526 deleteHydratableInstance(fiber, nextInstance);
14527 nextInstance = getNextHydratableSibling(nextInstance);
14528 }
14529 }
14530 }
14531 }
14532
14533 popToNextHostParent(fiber);
14534
14535 if (fiber.tag === SuspenseComponent) {
14536 nextHydratableInstance = skipPastDehydratedSuspenseInstance(fiber);
14537 } else {
14538 nextHydratableInstance = hydrationParentFiber ? getNextHydratableSibling(fiber.stateNode) : null;
14539 }
14540
14541 return true;
14542 }
14543
14544 function hasUnhydratedTailNodes() {
14545 return isHydrating && nextHydratableInstance !== null;
14546 }
14547
14548 function warnIfUnhydratedTailNodes(fiber) {
14549 var nextInstance = nextHydratableInstance;
14550
14551 while (nextInstance) {
14552 warnUnhydratedInstance(fiber, nextInstance);
14553 nextInstance = getNextHydratableSibling(nextInstance);
14554 }
14555 }
14556
14557 function resetHydrationState() {
14558
14559 hydrationParentFiber = null;
14560 nextHydratableInstance = null;
14561 isHydrating = false;
14562 didSuspend = false;
14563 }
14564
14565 function upgradeHydrationErrorsToRecoverable() {
14566 if (hydrationErrors !== null) {
14567 // Successfully completed a forced client render. The errors that occurred
14568 // during the hydration attempt are now recovered. We will log them in
14569 // commit phase, once the entire tree has finished.
14570 queueRecoverableErrors(hydrationErrors);
14571 hydrationErrors = null;
14572 }
14573 }
14574
14575 function getIsHydrating() {
14576 return isHydrating;
14577 }
14578
14579 function queueHydrationError(error) {
14580 if (hydrationErrors === null) {
14581 hydrationErrors = [error];
14582 } else {
14583 hydrationErrors.push(error);
14584 }
14585 }
14586
14587 var didWarnAboutMaps;
14588 var didWarnAboutGenerators;
14589 var didWarnAboutStringRefs;
14590 var ownerHasKeyUseWarning;
14591 var ownerHasFunctionTypeWarning;
14592
14593 var warnForMissingKey = function (child, returnFiber) {};
14594
14595 {
14596 didWarnAboutMaps = false;
14597 didWarnAboutGenerators = false;
14598 didWarnAboutStringRefs = {};
14599 /**
14600 * Warn if there's no key explicitly set on dynamic arrays of children or
14601 * object keys are not valid. This allows us to keep track of children between
14602 * updates.
14603 */
14604
14605 ownerHasKeyUseWarning = {};
14606 ownerHasFunctionTypeWarning = {};
14607
14608 warnForMissingKey = function (child, returnFiber) {
14609 if (child === null || typeof child !== 'object') {
14610 return;
14611 }
14612
14613 if (!child._store || child._store.validated || child.key != null) {
14614 return;
14615 }
14616
14617 if (typeof child._store !== 'object') {
14618 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.');
14619 }
14620
14621 child._store.validated = true;
14622 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
14623
14624 if (ownerHasKeyUseWarning[componentName]) {
14625 return;
14626 }
14627
14628 ownerHasKeyUseWarning[componentName] = true;
14629
14630 error('Each child in a list should have a unique ' + '"key" prop. See https://reactjs.org/link/warning-keys for ' + 'more information.');
14631 };
14632 }
14633
14634 function coerceRef(returnFiber, current, element) {
14635 var mixedRef = element.ref;
14636
14637 if (mixedRef !== null && typeof mixedRef !== 'function' && typeof mixedRef !== 'object') {
14638 {
14639 // TODO: Clean this up once we turn on the string ref warning for
14640 // everyone, because the strict mode case will no longer be relevant
14641 if ((returnFiber.mode & StrictLegacyMode || warnAboutStringRefs) && // We warn in ReactElement.js if owner and self are equal for string refs
14642 // because these cannot be automatically converted to an arrow function
14643 // using a codemod. Therefore, we don't have to warn about string refs again.
14644 !(element._owner && element._self && element._owner.stateNode !== element._self)) {
14645 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
14646
14647 if (!didWarnAboutStringRefs[componentName]) {
14648 {
14649 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);
14650 }
14651
14652 didWarnAboutStringRefs[componentName] = true;
14653 }
14654 }
14655 }
14656
14657 if (element._owner) {
14658 var owner = element._owner;
14659 var inst;
14660
14661 if (owner) {
14662 var ownerFiber = owner;
14663
14664 if (ownerFiber.tag !== ClassComponent) {
14665 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');
14666 }
14667
14668 inst = ownerFiber.stateNode;
14669 }
14670
14671 if (!inst) {
14672 throw new Error("Missing owner for string ref " + mixedRef + ". This error is likely caused by a " + 'bug in React. Please file an issue.');
14673 } // Assigning this to a const so Flow knows it won't change in the closure
14674
14675
14676 var resolvedInst = inst;
14677
14678 {
14679 checkPropStringCoercion(mixedRef, 'ref');
14680 }
14681
14682 var stringRef = '' + mixedRef; // Check if previous string ref matches new string ref
14683
14684 if (current !== null && current.ref !== null && typeof current.ref === 'function' && current.ref._stringRef === stringRef) {
14685 return current.ref;
14686 }
14687
14688 var ref = function (value) {
14689 var refs = resolvedInst.refs;
14690
14691 if (refs === emptyRefsObject) {
14692 // This is a lazy pooled frozen object, so we need to initialize.
14693 refs = resolvedInst.refs = {};
14694 }
14695
14696 if (value === null) {
14697 delete refs[stringRef];
14698 } else {
14699 refs[stringRef] = value;
14700 }
14701 };
14702
14703 ref._stringRef = stringRef;
14704 return ref;
14705 } else {
14706 if (typeof mixedRef !== 'string') {
14707 throw new Error('Expected ref to be a function, a string, an object returned by React.createRef(), or null.');
14708 }
14709
14710 if (!element._owner) {
14711 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.');
14712 }
14713 }
14714 }
14715
14716 return mixedRef;
14717 }
14718
14719 function throwOnInvalidObjectType(returnFiber, newChild) {
14720 var childString = Object.prototype.toString.call(newChild);
14721 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.');
14722 }
14723
14724 function warnOnFunctionType(returnFiber) {
14725 {
14726 var componentName = getComponentNameFromFiber(returnFiber) || 'Component';
14727
14728 if (ownerHasFunctionTypeWarning[componentName]) {
14729 return;
14730 }
14731
14732 ownerHasFunctionTypeWarning[componentName] = true;
14733
14734 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.');
14735 }
14736 }
14737
14738 function resolveLazy(lazyType) {
14739 var payload = lazyType._payload;
14740 var init = lazyType._init;
14741 return init(payload);
14742 } // This wrapper function exists because I expect to clone the code in each path
14743 // to be able to optimize each path individually by branching early. This needs
14744 // a compiler or we can do it manually. Helpers that don't need this branching
14745 // live outside of this function.
14746
14747
14748 function ChildReconciler(shouldTrackSideEffects) {
14749 function deleteChild(returnFiber, childToDelete) {
14750 if (!shouldTrackSideEffects) {
14751 // Noop.
14752 return;
14753 }
14754
14755 var deletions = returnFiber.deletions;
14756
14757 if (deletions === null) {
14758 returnFiber.deletions = [childToDelete];
14759 returnFiber.flags |= ChildDeletion;
14760 } else {
14761 deletions.push(childToDelete);
14762 }
14763 }
14764
14765 function deleteRemainingChildren(returnFiber, currentFirstChild) {
14766 if (!shouldTrackSideEffects) {
14767 // Noop.
14768 return null;
14769 } // TODO: For the shouldClone case, this could be micro-optimized a bit by
14770 // assuming that after the first child we've already added everything.
14771
14772
14773 var childToDelete = currentFirstChild;
14774
14775 while (childToDelete !== null) {
14776 deleteChild(returnFiber, childToDelete);
14777 childToDelete = childToDelete.sibling;
14778 }
14779
14780 return null;
14781 }
14782
14783 function mapRemainingChildren(returnFiber, currentFirstChild) {
14784 // Add the remaining children to a temporary map so that we can find them by
14785 // keys quickly. Implicit (null) keys get added to this set with their index
14786 // instead.
14787 var existingChildren = new Map();
14788 var existingChild = currentFirstChild;
14789
14790 while (existingChild !== null) {
14791 if (existingChild.key !== null) {
14792 existingChildren.set(existingChild.key, existingChild);
14793 } else {
14794 existingChildren.set(existingChild.index, existingChild);
14795 }
14796
14797 existingChild = existingChild.sibling;
14798 }
14799
14800 return existingChildren;
14801 }
14802
14803 function useFiber(fiber, pendingProps) {
14804 // We currently set sibling to null and index to 0 here because it is easy
14805 // to forget to do before returning it. E.g. for the single child case.
14806 var clone = createWorkInProgress(fiber, pendingProps);
14807 clone.index = 0;
14808 clone.sibling = null;
14809 return clone;
14810 }
14811
14812 function placeChild(newFiber, lastPlacedIndex, newIndex) {
14813 newFiber.index = newIndex;
14814
14815 if (!shouldTrackSideEffects) {
14816 // During hydration, the useId algorithm needs to know which fibers are
14817 // part of a list of children (arrays, iterators).
14818 newFiber.flags |= Forked;
14819 return lastPlacedIndex;
14820 }
14821
14822 var current = newFiber.alternate;
14823
14824 if (current !== null) {
14825 var oldIndex = current.index;
14826
14827 if (oldIndex < lastPlacedIndex) {
14828 // This is a move.
14829 newFiber.flags |= Placement;
14830 return lastPlacedIndex;
14831 } else {
14832 // This item can stay in place.
14833 return oldIndex;
14834 }
14835 } else {
14836 // This is an insertion.
14837 newFiber.flags |= Placement;
14838 return lastPlacedIndex;
14839 }
14840 }
14841
14842 function placeSingleChild(newFiber) {
14843 // This is simpler for the single child case. We only need to do a
14844 // placement for inserting new children.
14845 if (shouldTrackSideEffects && newFiber.alternate === null) {
14846 newFiber.flags |= Placement;
14847 }
14848
14849 return newFiber;
14850 }
14851
14852 function updateTextNode(returnFiber, current, textContent, lanes) {
14853 if (current === null || current.tag !== HostText) {
14854 // Insert
14855 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
14856 created.return = returnFiber;
14857 return created;
14858 } else {
14859 // Update
14860 var existing = useFiber(current, textContent);
14861 existing.return = returnFiber;
14862 return existing;
14863 }
14864 }
14865
14866 function updateElement(returnFiber, current, element, lanes) {
14867 var elementType = element.type;
14868
14869 if (elementType === REACT_FRAGMENT_TYPE) {
14870 return updateFragment(returnFiber, current, element.props.children, lanes, element.key);
14871 }
14872
14873 if (current !== null) {
14874 if (current.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
14875 isCompatibleFamilyForHotReloading(current, element) ) || // Lazy types should reconcile their resolved type.
14876 // We need to do this after the Hot Reloading check above,
14877 // because hot reloading has different semantics than prod because
14878 // it doesn't resuspend. So we can't let the call below suspend.
14879 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === current.type) {
14880 // Move based on index
14881 var existing = useFiber(current, element.props);
14882 existing.ref = coerceRef(returnFiber, current, element);
14883 existing.return = returnFiber;
14884
14885 {
14886 existing._debugSource = element._source;
14887 existing._debugOwner = element._owner;
14888 }
14889
14890 return existing;
14891 }
14892 } // Insert
14893
14894
14895 var created = createFiberFromElement(element, returnFiber.mode, lanes);
14896 created.ref = coerceRef(returnFiber, current, element);
14897 created.return = returnFiber;
14898 return created;
14899 }
14900
14901 function updatePortal(returnFiber, current, portal, lanes) {
14902 if (current === null || current.tag !== HostPortal || current.stateNode.containerInfo !== portal.containerInfo || current.stateNode.implementation !== portal.implementation) {
14903 // Insert
14904 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
14905 created.return = returnFiber;
14906 return created;
14907 } else {
14908 // Update
14909 var existing = useFiber(current, portal.children || []);
14910 existing.return = returnFiber;
14911 return existing;
14912 }
14913 }
14914
14915 function updateFragment(returnFiber, current, fragment, lanes, key) {
14916 if (current === null || current.tag !== Fragment) {
14917 // Insert
14918 var created = createFiberFromFragment(fragment, returnFiber.mode, lanes, key);
14919 created.return = returnFiber;
14920 return created;
14921 } else {
14922 // Update
14923 var existing = useFiber(current, fragment);
14924 existing.return = returnFiber;
14925 return existing;
14926 }
14927 }
14928
14929 function createChild(returnFiber, newChild, lanes) {
14930 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
14931 // Text nodes don't have keys. If the previous node is implicitly keyed
14932 // we can continue to replace it without aborting even if it is not a text
14933 // node.
14934 var created = createFiberFromText('' + newChild, returnFiber.mode, lanes);
14935 created.return = returnFiber;
14936 return created;
14937 }
14938
14939 if (typeof newChild === 'object' && newChild !== null) {
14940 switch (newChild.$$typeof) {
14941 case REACT_ELEMENT_TYPE:
14942 {
14943 var _created = createFiberFromElement(newChild, returnFiber.mode, lanes);
14944
14945 _created.ref = coerceRef(returnFiber, null, newChild);
14946 _created.return = returnFiber;
14947 return _created;
14948 }
14949
14950 case REACT_PORTAL_TYPE:
14951 {
14952 var _created2 = createFiberFromPortal(newChild, returnFiber.mode, lanes);
14953
14954 _created2.return = returnFiber;
14955 return _created2;
14956 }
14957
14958 case REACT_LAZY_TYPE:
14959 {
14960 {
14961 var payload = newChild._payload;
14962 var init = newChild._init;
14963 return createChild(returnFiber, init(payload), lanes);
14964 }
14965 }
14966 }
14967
14968 if (isArray(newChild) || getIteratorFn(newChild)) {
14969 var _created3 = createFiberFromFragment(newChild, returnFiber.mode, lanes, null);
14970
14971 _created3.return = returnFiber;
14972 return _created3;
14973 }
14974
14975 throwOnInvalidObjectType(returnFiber, newChild);
14976 }
14977
14978 {
14979 if (typeof newChild === 'function') {
14980 warnOnFunctionType(returnFiber);
14981 }
14982 }
14983
14984 return null;
14985 }
14986
14987 function updateSlot(returnFiber, oldFiber, newChild, lanes) {
14988 // Update the fiber if the keys match, otherwise return null.
14989 var key = oldFiber !== null ? oldFiber.key : null;
14990
14991 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
14992 // Text nodes don't have keys. If the previous node is implicitly keyed
14993 // we can continue to replace it without aborting even if it is not a text
14994 // node.
14995 if (key !== null) {
14996 return null;
14997 }
14998
14999 return updateTextNode(returnFiber, oldFiber, '' + newChild, lanes);
15000 }
15001
15002 if (typeof newChild === 'object' && newChild !== null) {
15003 switch (newChild.$$typeof) {
15004 case REACT_ELEMENT_TYPE:
15005 {
15006 if (newChild.key === key) {
15007 return updateElement(returnFiber, oldFiber, newChild, lanes);
15008 } else {
15009 return null;
15010 }
15011 }
15012
15013 case REACT_PORTAL_TYPE:
15014 {
15015 if (newChild.key === key) {
15016 return updatePortal(returnFiber, oldFiber, newChild, lanes);
15017 } else {
15018 return null;
15019 }
15020 }
15021
15022 case REACT_LAZY_TYPE:
15023 {
15024 {
15025 var payload = newChild._payload;
15026 var init = newChild._init;
15027 return updateSlot(returnFiber, oldFiber, init(payload), lanes);
15028 }
15029 }
15030 }
15031
15032 if (isArray(newChild) || getIteratorFn(newChild)) {
15033 if (key !== null) {
15034 return null;
15035 }
15036
15037 return updateFragment(returnFiber, oldFiber, newChild, lanes, null);
15038 }
15039
15040 throwOnInvalidObjectType(returnFiber, newChild);
15041 }
15042
15043 {
15044 if (typeof newChild === 'function') {
15045 warnOnFunctionType(returnFiber);
15046 }
15047 }
15048
15049 return null;
15050 }
15051
15052 function updateFromMap(existingChildren, returnFiber, newIdx, newChild, lanes) {
15053 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
15054 // Text nodes don't have keys, so we neither have to check the old nor
15055 // new node for the key. If both are text nodes, they match.
15056 var matchedFiber = existingChildren.get(newIdx) || null;
15057 return updateTextNode(returnFiber, matchedFiber, '' + newChild, lanes);
15058 }
15059
15060 if (typeof newChild === 'object' && newChild !== null) {
15061 switch (newChild.$$typeof) {
15062 case REACT_ELEMENT_TYPE:
15063 {
15064 var _matchedFiber = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
15065
15066 return updateElement(returnFiber, _matchedFiber, newChild, lanes);
15067 }
15068
15069 case REACT_PORTAL_TYPE:
15070 {
15071 var _matchedFiber2 = existingChildren.get(newChild.key === null ? newIdx : newChild.key) || null;
15072
15073 return updatePortal(returnFiber, _matchedFiber2, newChild, lanes);
15074 }
15075
15076 case REACT_LAZY_TYPE:
15077 {
15078 var payload = newChild._payload;
15079 var init = newChild._init;
15080 return updateFromMap(existingChildren, returnFiber, newIdx, init(payload), lanes);
15081 }
15082
15083 }
15084
15085 if (isArray(newChild) || getIteratorFn(newChild)) {
15086 var _matchedFiber3 = existingChildren.get(newIdx) || null;
15087
15088 return updateFragment(returnFiber, _matchedFiber3, newChild, lanes, null);
15089 }
15090
15091 throwOnInvalidObjectType(returnFiber, newChild);
15092 }
15093
15094 {
15095 if (typeof newChild === 'function') {
15096 warnOnFunctionType(returnFiber);
15097 }
15098 }
15099
15100 return null;
15101 }
15102 /**
15103 * Warns if there is a duplicate or missing key
15104 */
15105
15106
15107 function warnOnInvalidKey(child, knownKeys, returnFiber) {
15108 {
15109 if (typeof child !== 'object' || child === null) {
15110 return knownKeys;
15111 }
15112
15113 switch (child.$$typeof) {
15114 case REACT_ELEMENT_TYPE:
15115 case REACT_PORTAL_TYPE:
15116 warnForMissingKey(child, returnFiber);
15117 var key = child.key;
15118
15119 if (typeof key !== 'string') {
15120 break;
15121 }
15122
15123 if (knownKeys === null) {
15124 knownKeys = new Set();
15125 knownKeys.add(key);
15126 break;
15127 }
15128
15129 if (!knownKeys.has(key)) {
15130 knownKeys.add(key);
15131 break;
15132 }
15133
15134 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);
15135
15136 break;
15137
15138 case REACT_LAZY_TYPE:
15139 {
15140 var payload = child._payload;
15141 var init = child._init;
15142 warnOnInvalidKey(init(payload), knownKeys, returnFiber);
15143 break;
15144 }
15145 }
15146 }
15147
15148 return knownKeys;
15149 }
15150
15151 function reconcileChildrenArray(returnFiber, currentFirstChild, newChildren, lanes) {
15152 // This algorithm can't optimize by searching from both ends since we
15153 // don't have backpointers on fibers. I'm trying to see how far we can get
15154 // with that model. If it ends up not being worth the tradeoffs, we can
15155 // add it later.
15156 // Even with a two ended optimization, we'd want to optimize for the case
15157 // where there are few changes and brute force the comparison instead of
15158 // going for the Map. It'd like to explore hitting that path first in
15159 // forward-only mode and only go for the Map once we notice that we need
15160 // lots of look ahead. This doesn't handle reversal as well as two ended
15161 // search but that's unusual. Besides, for the two ended optimization to
15162 // work on Iterables, we'd need to copy the whole set.
15163 // In this first iteration, we'll just live with hitting the bad case
15164 // (adding everything to a Map) in for every insert/move.
15165 // If you change this code, also update reconcileChildrenIterator() which
15166 // uses the same algorithm.
15167 {
15168 // First, validate keys.
15169 var knownKeys = null;
15170
15171 for (var i = 0; i < newChildren.length; i++) {
15172 var child = newChildren[i];
15173 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
15174 }
15175 }
15176
15177 var resultingFirstChild = null;
15178 var previousNewFiber = null;
15179 var oldFiber = currentFirstChild;
15180 var lastPlacedIndex = 0;
15181 var newIdx = 0;
15182 var nextOldFiber = null;
15183
15184 for (; oldFiber !== null && newIdx < newChildren.length; newIdx++) {
15185 if (oldFiber.index > newIdx) {
15186 nextOldFiber = oldFiber;
15187 oldFiber = null;
15188 } else {
15189 nextOldFiber = oldFiber.sibling;
15190 }
15191
15192 var newFiber = updateSlot(returnFiber, oldFiber, newChildren[newIdx], lanes);
15193
15194 if (newFiber === null) {
15195 // TODO: This breaks on empty slots like null children. That's
15196 // unfortunate because it triggers the slow path all the time. We need
15197 // a better way to communicate whether this was a miss or null,
15198 // boolean, undefined, etc.
15199 if (oldFiber === null) {
15200 oldFiber = nextOldFiber;
15201 }
15202
15203 break;
15204 }
15205
15206 if (shouldTrackSideEffects) {
15207 if (oldFiber && newFiber.alternate === null) {
15208 // We matched the slot, but we didn't reuse the existing fiber, so we
15209 // need to delete the existing child.
15210 deleteChild(returnFiber, oldFiber);
15211 }
15212 }
15213
15214 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
15215
15216 if (previousNewFiber === null) {
15217 // TODO: Move out of the loop. This only happens for the first run.
15218 resultingFirstChild = newFiber;
15219 } else {
15220 // TODO: Defer siblings if we're not at the right index for this slot.
15221 // I.e. if we had null values before, then we want to defer this
15222 // for each null value. However, we also don't want to call updateSlot
15223 // with the previous one.
15224 previousNewFiber.sibling = newFiber;
15225 }
15226
15227 previousNewFiber = newFiber;
15228 oldFiber = nextOldFiber;
15229 }
15230
15231 if (newIdx === newChildren.length) {
15232 // We've reached the end of the new children. We can delete the rest.
15233 deleteRemainingChildren(returnFiber, oldFiber);
15234
15235 if (getIsHydrating()) {
15236 var numberOfForks = newIdx;
15237 pushTreeFork(returnFiber, numberOfForks);
15238 }
15239
15240 return resultingFirstChild;
15241 }
15242
15243 if (oldFiber === null) {
15244 // If we don't have any more existing children we can choose a fast path
15245 // since the rest will all be insertions.
15246 for (; newIdx < newChildren.length; newIdx++) {
15247 var _newFiber = createChild(returnFiber, newChildren[newIdx], lanes);
15248
15249 if (_newFiber === null) {
15250 continue;
15251 }
15252
15253 lastPlacedIndex = placeChild(_newFiber, lastPlacedIndex, newIdx);
15254
15255 if (previousNewFiber === null) {
15256 // TODO: Move out of the loop. This only happens for the first run.
15257 resultingFirstChild = _newFiber;
15258 } else {
15259 previousNewFiber.sibling = _newFiber;
15260 }
15261
15262 previousNewFiber = _newFiber;
15263 }
15264
15265 if (getIsHydrating()) {
15266 var _numberOfForks = newIdx;
15267 pushTreeFork(returnFiber, _numberOfForks);
15268 }
15269
15270 return resultingFirstChild;
15271 } // Add all children to a key map for quick lookups.
15272
15273
15274 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
15275
15276 for (; newIdx < newChildren.length; newIdx++) {
15277 var _newFiber2 = updateFromMap(existingChildren, returnFiber, newIdx, newChildren[newIdx], lanes);
15278
15279 if (_newFiber2 !== null) {
15280 if (shouldTrackSideEffects) {
15281 if (_newFiber2.alternate !== null) {
15282 // The new fiber is a work in progress, but if there exists a
15283 // current, that means that we reused the fiber. We need to delete
15284 // it from the child list so that we don't add it to the deletion
15285 // list.
15286 existingChildren.delete(_newFiber2.key === null ? newIdx : _newFiber2.key);
15287 }
15288 }
15289
15290 lastPlacedIndex = placeChild(_newFiber2, lastPlacedIndex, newIdx);
15291
15292 if (previousNewFiber === null) {
15293 resultingFirstChild = _newFiber2;
15294 } else {
15295 previousNewFiber.sibling = _newFiber2;
15296 }
15297
15298 previousNewFiber = _newFiber2;
15299 }
15300 }
15301
15302 if (shouldTrackSideEffects) {
15303 // Any existing children that weren't consumed above were deleted. We need
15304 // to add them to the deletion list.
15305 existingChildren.forEach(function (child) {
15306 return deleteChild(returnFiber, child);
15307 });
15308 }
15309
15310 if (getIsHydrating()) {
15311 var _numberOfForks2 = newIdx;
15312 pushTreeFork(returnFiber, _numberOfForks2);
15313 }
15314
15315 return resultingFirstChild;
15316 }
15317
15318 function reconcileChildrenIterator(returnFiber, currentFirstChild, newChildrenIterable, lanes) {
15319 // This is the same implementation as reconcileChildrenArray(),
15320 // but using the iterator instead.
15321 var iteratorFn = getIteratorFn(newChildrenIterable);
15322
15323 if (typeof iteratorFn !== 'function') {
15324 throw new Error('An object is not an iterable. This error is likely caused by a bug in ' + 'React. Please file an issue.');
15325 }
15326
15327 {
15328 // We don't support rendering Generators because it's a mutation.
15329 // See https://github.com/facebook/react/issues/12995
15330 if (typeof Symbol === 'function' && // $FlowFixMe Flow doesn't know about toStringTag
15331 newChildrenIterable[Symbol.toStringTag] === 'Generator') {
15332 if (!didWarnAboutGenerators) {
15333 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.');
15334 }
15335
15336 didWarnAboutGenerators = true;
15337 } // Warn about using Maps as children
15338
15339
15340 if (newChildrenIterable.entries === iteratorFn) {
15341 if (!didWarnAboutMaps) {
15342 error('Using Maps as children is not supported. ' + 'Use an array of keyed ReactElements instead.');
15343 }
15344
15345 didWarnAboutMaps = true;
15346 } // First, validate keys.
15347 // We'll get a different iterator later for the main pass.
15348
15349
15350 var _newChildren = iteratorFn.call(newChildrenIterable);
15351
15352 if (_newChildren) {
15353 var knownKeys = null;
15354
15355 var _step = _newChildren.next();
15356
15357 for (; !_step.done; _step = _newChildren.next()) {
15358 var child = _step.value;
15359 knownKeys = warnOnInvalidKey(child, knownKeys, returnFiber);
15360 }
15361 }
15362 }
15363
15364 var newChildren = iteratorFn.call(newChildrenIterable);
15365
15366 if (newChildren == null) {
15367 throw new Error('An iterable object provided no iterator.');
15368 }
15369
15370 var resultingFirstChild = null;
15371 var previousNewFiber = null;
15372 var oldFiber = currentFirstChild;
15373 var lastPlacedIndex = 0;
15374 var newIdx = 0;
15375 var nextOldFiber = null;
15376 var step = newChildren.next();
15377
15378 for (; oldFiber !== null && !step.done; newIdx++, step = newChildren.next()) {
15379 if (oldFiber.index > newIdx) {
15380 nextOldFiber = oldFiber;
15381 oldFiber = null;
15382 } else {
15383 nextOldFiber = oldFiber.sibling;
15384 }
15385
15386 var newFiber = updateSlot(returnFiber, oldFiber, step.value, lanes);
15387
15388 if (newFiber === null) {
15389 // TODO: This breaks on empty slots like null children. That's
15390 // unfortunate because it triggers the slow path all the time. We need
15391 // a better way to communicate whether this was a miss or null,
15392 // boolean, undefined, etc.
15393 if (oldFiber === null) {
15394 oldFiber = nextOldFiber;
15395 }
15396
15397 break;
15398 }
15399
15400 if (shouldTrackSideEffects) {
15401 if (oldFiber && newFiber.alternate === null) {
15402 // We matched the slot, but we didn't reuse the existing fiber, so we
15403 // need to delete the existing child.
15404 deleteChild(returnFiber, oldFiber);
15405 }
15406 }
15407
15408 lastPlacedIndex = placeChild(newFiber, lastPlacedIndex, newIdx);
15409
15410 if (previousNewFiber === null) {
15411 // TODO: Move out of the loop. This only happens for the first run.
15412 resultingFirstChild = newFiber;
15413 } else {
15414 // TODO: Defer siblings if we're not at the right index for this slot.
15415 // I.e. if we had null values before, then we want to defer this
15416 // for each null value. However, we also don't want to call updateSlot
15417 // with the previous one.
15418 previousNewFiber.sibling = newFiber;
15419 }
15420
15421 previousNewFiber = newFiber;
15422 oldFiber = nextOldFiber;
15423 }
15424
15425 if (step.done) {
15426 // We've reached the end of the new children. We can delete the rest.
15427 deleteRemainingChildren(returnFiber, oldFiber);
15428
15429 if (getIsHydrating()) {
15430 var numberOfForks = newIdx;
15431 pushTreeFork(returnFiber, numberOfForks);
15432 }
15433
15434 return resultingFirstChild;
15435 }
15436
15437 if (oldFiber === null) {
15438 // If we don't have any more existing children we can choose a fast path
15439 // since the rest will all be insertions.
15440 for (; !step.done; newIdx++, step = newChildren.next()) {
15441 var _newFiber3 = createChild(returnFiber, step.value, lanes);
15442
15443 if (_newFiber3 === null) {
15444 continue;
15445 }
15446
15447 lastPlacedIndex = placeChild(_newFiber3, lastPlacedIndex, newIdx);
15448
15449 if (previousNewFiber === null) {
15450 // TODO: Move out of the loop. This only happens for the first run.
15451 resultingFirstChild = _newFiber3;
15452 } else {
15453 previousNewFiber.sibling = _newFiber3;
15454 }
15455
15456 previousNewFiber = _newFiber3;
15457 }
15458
15459 if (getIsHydrating()) {
15460 var _numberOfForks3 = newIdx;
15461 pushTreeFork(returnFiber, _numberOfForks3);
15462 }
15463
15464 return resultingFirstChild;
15465 } // Add all children to a key map for quick lookups.
15466
15467
15468 var existingChildren = mapRemainingChildren(returnFiber, oldFiber); // Keep scanning and use the map to restore deleted items as moves.
15469
15470 for (; !step.done; newIdx++, step = newChildren.next()) {
15471 var _newFiber4 = updateFromMap(existingChildren, returnFiber, newIdx, step.value, lanes);
15472
15473 if (_newFiber4 !== null) {
15474 if (shouldTrackSideEffects) {
15475 if (_newFiber4.alternate !== null) {
15476 // The new fiber is a work in progress, but if there exists a
15477 // current, that means that we reused the fiber. We need to delete
15478 // it from the child list so that we don't add it to the deletion
15479 // list.
15480 existingChildren.delete(_newFiber4.key === null ? newIdx : _newFiber4.key);
15481 }
15482 }
15483
15484 lastPlacedIndex = placeChild(_newFiber4, lastPlacedIndex, newIdx);
15485
15486 if (previousNewFiber === null) {
15487 resultingFirstChild = _newFiber4;
15488 } else {
15489 previousNewFiber.sibling = _newFiber4;
15490 }
15491
15492 previousNewFiber = _newFiber4;
15493 }
15494 }
15495
15496 if (shouldTrackSideEffects) {
15497 // Any existing children that weren't consumed above were deleted. We need
15498 // to add them to the deletion list.
15499 existingChildren.forEach(function (child) {
15500 return deleteChild(returnFiber, child);
15501 });
15502 }
15503
15504 if (getIsHydrating()) {
15505 var _numberOfForks4 = newIdx;
15506 pushTreeFork(returnFiber, _numberOfForks4);
15507 }
15508
15509 return resultingFirstChild;
15510 }
15511
15512 function reconcileSingleTextNode(returnFiber, currentFirstChild, textContent, lanes) {
15513 // There's no need to check for keys on text nodes since we don't have a
15514 // way to define them.
15515 if (currentFirstChild !== null && currentFirstChild.tag === HostText) {
15516 // We already have an existing node so let's just update it and delete
15517 // the rest.
15518 deleteRemainingChildren(returnFiber, currentFirstChild.sibling);
15519 var existing = useFiber(currentFirstChild, textContent);
15520 existing.return = returnFiber;
15521 return existing;
15522 } // The existing first child is not a text node so we need to create one
15523 // and delete the existing ones.
15524
15525
15526 deleteRemainingChildren(returnFiber, currentFirstChild);
15527 var created = createFiberFromText(textContent, returnFiber.mode, lanes);
15528 created.return = returnFiber;
15529 return created;
15530 }
15531
15532 function reconcileSingleElement(returnFiber, currentFirstChild, element, lanes) {
15533 var key = element.key;
15534 var child = currentFirstChild;
15535
15536 while (child !== null) {
15537 // TODO: If key === null and child.key === null, then this only applies to
15538 // the first item in the list.
15539 if (child.key === key) {
15540 var elementType = element.type;
15541
15542 if (elementType === REACT_FRAGMENT_TYPE) {
15543 if (child.tag === Fragment) {
15544 deleteRemainingChildren(returnFiber, child.sibling);
15545 var existing = useFiber(child, element.props.children);
15546 existing.return = returnFiber;
15547
15548 {
15549 existing._debugSource = element._source;
15550 existing._debugOwner = element._owner;
15551 }
15552
15553 return existing;
15554 }
15555 } else {
15556 if (child.elementType === elementType || ( // Keep this check inline so it only runs on the false path:
15557 isCompatibleFamilyForHotReloading(child, element) ) || // Lazy types should reconcile their resolved type.
15558 // We need to do this after the Hot Reloading check above,
15559 // because hot reloading has different semantics than prod because
15560 // it doesn't resuspend. So we can't let the call below suspend.
15561 typeof elementType === 'object' && elementType !== null && elementType.$$typeof === REACT_LAZY_TYPE && resolveLazy(elementType) === child.type) {
15562 deleteRemainingChildren(returnFiber, child.sibling);
15563
15564 var _existing = useFiber(child, element.props);
15565
15566 _existing.ref = coerceRef(returnFiber, child, element);
15567 _existing.return = returnFiber;
15568
15569 {
15570 _existing._debugSource = element._source;
15571 _existing._debugOwner = element._owner;
15572 }
15573
15574 return _existing;
15575 }
15576 } // Didn't match.
15577
15578
15579 deleteRemainingChildren(returnFiber, child);
15580 break;
15581 } else {
15582 deleteChild(returnFiber, child);
15583 }
15584
15585 child = child.sibling;
15586 }
15587
15588 if (element.type === REACT_FRAGMENT_TYPE) {
15589 var created = createFiberFromFragment(element.props.children, returnFiber.mode, lanes, element.key);
15590 created.return = returnFiber;
15591 return created;
15592 } else {
15593 var _created4 = createFiberFromElement(element, returnFiber.mode, lanes);
15594
15595 _created4.ref = coerceRef(returnFiber, currentFirstChild, element);
15596 _created4.return = returnFiber;
15597 return _created4;
15598 }
15599 }
15600
15601 function reconcileSinglePortal(returnFiber, currentFirstChild, portal, lanes) {
15602 var key = portal.key;
15603 var child = currentFirstChild;
15604
15605 while (child !== null) {
15606 // TODO: If key === null and child.key === null, then this only applies to
15607 // the first item in the list.
15608 if (child.key === key) {
15609 if (child.tag === HostPortal && child.stateNode.containerInfo === portal.containerInfo && child.stateNode.implementation === portal.implementation) {
15610 deleteRemainingChildren(returnFiber, child.sibling);
15611 var existing = useFiber(child, portal.children || []);
15612 existing.return = returnFiber;
15613 return existing;
15614 } else {
15615 deleteRemainingChildren(returnFiber, child);
15616 break;
15617 }
15618 } else {
15619 deleteChild(returnFiber, child);
15620 }
15621
15622 child = child.sibling;
15623 }
15624
15625 var created = createFiberFromPortal(portal, returnFiber.mode, lanes);
15626 created.return = returnFiber;
15627 return created;
15628 } // This API will tag the children with the side-effect of the reconciliation
15629 // itself. They will be added to the side-effect list as we pass through the
15630 // children and the parent.
15631
15632
15633 function reconcileChildFibers(returnFiber, currentFirstChild, newChild, lanes) {
15634 // This function is not recursive.
15635 // If the top level item is an array, we treat it as a set of children,
15636 // not as a fragment. Nested arrays on the other hand will be treated as
15637 // fragment nodes. Recursion happens at the normal flow.
15638 // Handle top level unkeyed fragments as if they were arrays.
15639 // This leads to an ambiguity between <>{[...]}</> and <>...</>.
15640 // We treat the ambiguous cases above the same.
15641 var isUnkeyedTopLevelFragment = typeof newChild === 'object' && newChild !== null && newChild.type === REACT_FRAGMENT_TYPE && newChild.key === null;
15642
15643 if (isUnkeyedTopLevelFragment) {
15644 newChild = newChild.props.children;
15645 } // Handle object types
15646
15647
15648 if (typeof newChild === 'object' && newChild !== null) {
15649 switch (newChild.$$typeof) {
15650 case REACT_ELEMENT_TYPE:
15651 return placeSingleChild(reconcileSingleElement(returnFiber, currentFirstChild, newChild, lanes));
15652
15653 case REACT_PORTAL_TYPE:
15654 return placeSingleChild(reconcileSinglePortal(returnFiber, currentFirstChild, newChild, lanes));
15655
15656 case REACT_LAZY_TYPE:
15657 {
15658 var payload = newChild._payload;
15659 var init = newChild._init; // TODO: This function is supposed to be non-recursive.
15660
15661 return reconcileChildFibers(returnFiber, currentFirstChild, init(payload), lanes);
15662 }
15663
15664 }
15665
15666 if (isArray(newChild)) {
15667 return reconcileChildrenArray(returnFiber, currentFirstChild, newChild, lanes);
15668 }
15669
15670 if (getIteratorFn(newChild)) {
15671 return reconcileChildrenIterator(returnFiber, currentFirstChild, newChild, lanes);
15672 }
15673
15674 throwOnInvalidObjectType(returnFiber, newChild);
15675 }
15676
15677 if (typeof newChild === 'string' && newChild !== '' || typeof newChild === 'number') {
15678 return placeSingleChild(reconcileSingleTextNode(returnFiber, currentFirstChild, '' + newChild, lanes));
15679 }
15680
15681 {
15682 if (typeof newChild === 'function') {
15683 warnOnFunctionType(returnFiber);
15684 }
15685 } // Remaining cases are all treated as empty.
15686
15687
15688 return deleteRemainingChildren(returnFiber, currentFirstChild);
15689 }
15690
15691 return reconcileChildFibers;
15692 }
15693
15694 var reconcileChildFibers = ChildReconciler(true);
15695 var mountChildFibers = ChildReconciler(false);
15696 function cloneChildFibers(current, workInProgress) {
15697 if (current !== null && workInProgress.child !== current.child) {
15698 throw new Error('Resuming work not yet implemented.');
15699 }
15700
15701 if (workInProgress.child === null) {
15702 return;
15703 }
15704
15705 var currentChild = workInProgress.child;
15706 var newChild = createWorkInProgress(currentChild, currentChild.pendingProps);
15707 workInProgress.child = newChild;
15708 newChild.return = workInProgress;
15709
15710 while (currentChild.sibling !== null) {
15711 currentChild = currentChild.sibling;
15712 newChild = newChild.sibling = createWorkInProgress(currentChild, currentChild.pendingProps);
15713 newChild.return = workInProgress;
15714 }
15715
15716 newChild.sibling = null;
15717 } // Reset a workInProgress child set to prepare it for a second pass.
15718
15719 function resetChildFibers(workInProgress, lanes) {
15720 var child = workInProgress.child;
15721
15722 while (child !== null) {
15723 resetWorkInProgress(child, lanes);
15724 child = child.sibling;
15725 }
15726 }
15727
15728 var NO_CONTEXT = {};
15729 var contextStackCursor$1 = createCursor(NO_CONTEXT);
15730 var contextFiberStackCursor = createCursor(NO_CONTEXT);
15731 var rootInstanceStackCursor = createCursor(NO_CONTEXT);
15732
15733 function requiredContext(c) {
15734 if (c === NO_CONTEXT) {
15735 throw new Error('Expected host context to exist. This error is likely caused by a bug ' + 'in React. Please file an issue.');
15736 }
15737
15738 return c;
15739 }
15740
15741 function getRootHostContainer() {
15742 var rootInstance = requiredContext(rootInstanceStackCursor.current);
15743 return rootInstance;
15744 }
15745
15746 function pushHostContainer(fiber, nextRootInstance) {
15747 // Push current root instance onto the stack;
15748 // This allows us to reset root when portals are popped.
15749 push(rootInstanceStackCursor, nextRootInstance, fiber); // Track the context and the Fiber that provided it.
15750 // This enables us to pop only Fibers that provide unique contexts.
15751
15752 push(contextFiberStackCursor, fiber, fiber); // Finally, we need to push the host context to the stack.
15753 // However, we can't just call getRootHostContext() and push it because
15754 // we'd have a different number of entries on the stack depending on
15755 // whether getRootHostContext() throws somewhere in renderer code or not.
15756 // So we push an empty value first. This lets us safely unwind on errors.
15757
15758 push(contextStackCursor$1, NO_CONTEXT, fiber);
15759 var nextRootContext = getRootHostContext(nextRootInstance); // Now that we know this function doesn't throw, replace it.
15760
15761 pop(contextStackCursor$1, fiber);
15762 push(contextStackCursor$1, nextRootContext, fiber);
15763 }
15764
15765 function popHostContainer(fiber) {
15766 pop(contextStackCursor$1, fiber);
15767 pop(contextFiberStackCursor, fiber);
15768 pop(rootInstanceStackCursor, fiber);
15769 }
15770
15771 function getHostContext() {
15772 var context = requiredContext(contextStackCursor$1.current);
15773 return context;
15774 }
15775
15776 function pushHostContext(fiber) {
15777 var rootInstance = requiredContext(rootInstanceStackCursor.current);
15778 var context = requiredContext(contextStackCursor$1.current);
15779 var nextContext = getChildHostContext(context, fiber.type); // Don't push this Fiber's context unless it's unique.
15780
15781 if (context === nextContext) {
15782 return;
15783 } // Track the context and the Fiber that provided it.
15784 // This enables us to pop only Fibers that provide unique contexts.
15785
15786
15787 push(contextFiberStackCursor, fiber, fiber);
15788 push(contextStackCursor$1, nextContext, fiber);
15789 }
15790
15791 function popHostContext(fiber) {
15792 // Do not pop unless this Fiber provided the current context.
15793 // pushHostContext() only pushes Fibers that provide unique contexts.
15794 if (contextFiberStackCursor.current !== fiber) {
15795 return;
15796 }
15797
15798 pop(contextStackCursor$1, fiber);
15799 pop(contextFiberStackCursor, fiber);
15800 }
15801
15802 var DefaultSuspenseContext = 0; // The Suspense Context is split into two parts. The lower bits is
15803 // inherited deeply down the subtree. The upper bits only affect
15804 // this immediate suspense boundary and gets reset each new
15805 // boundary or suspense list.
15806
15807 var SubtreeSuspenseContextMask = 1; // Subtree Flags:
15808 // InvisibleParentSuspenseContext indicates that one of our parent Suspense
15809 // boundaries is not currently showing visible main content.
15810 // Either because it is already showing a fallback or is not mounted at all.
15811 // We can use this to determine if it is desirable to trigger a fallback at
15812 // the parent. If not, then we might need to trigger undesirable boundaries
15813 // and/or suspend the commit to avoid hiding the parent content.
15814
15815 var InvisibleParentSuspenseContext = 1; // Shallow Flags:
15816 // ForceSuspenseFallback can be used by SuspenseList to force newly added
15817 // items into their fallback state during one of the render passes.
15818
15819 var ForceSuspenseFallback = 2;
15820 var suspenseStackCursor = createCursor(DefaultSuspenseContext);
15821 function hasSuspenseContext(parentContext, flag) {
15822 return (parentContext & flag) !== 0;
15823 }
15824 function setDefaultShallowSuspenseContext(parentContext) {
15825 return parentContext & SubtreeSuspenseContextMask;
15826 }
15827 function setShallowSuspenseContext(parentContext, shallowContext) {
15828 return parentContext & SubtreeSuspenseContextMask | shallowContext;
15829 }
15830 function addSubtreeSuspenseContext(parentContext, subtreeContext) {
15831 return parentContext | subtreeContext;
15832 }
15833 function pushSuspenseContext(fiber, newContext) {
15834 push(suspenseStackCursor, newContext, fiber);
15835 }
15836 function popSuspenseContext(fiber) {
15837 pop(suspenseStackCursor, fiber);
15838 }
15839
15840 function shouldCaptureSuspense(workInProgress, hasInvisibleParent) {
15841 // If it was the primary children that just suspended, capture and render the
15842 // fallback. Otherwise, don't capture and bubble to the next boundary.
15843 var nextState = workInProgress.memoizedState;
15844
15845 if (nextState !== null) {
15846 if (nextState.dehydrated !== null) {
15847 // A dehydrated boundary always captures.
15848 return true;
15849 }
15850
15851 return false;
15852 }
15853
15854 var props = workInProgress.memoizedProps; // Regular boundaries always capture.
15855
15856 {
15857 return true;
15858 } // If it's a boundary we should avoid, then we prefer to bubble up to the
15859 }
15860 function findFirstSuspended(row) {
15861 var node = row;
15862
15863 while (node !== null) {
15864 if (node.tag === SuspenseComponent) {
15865 var state = node.memoizedState;
15866
15867 if (state !== null) {
15868 var dehydrated = state.dehydrated;
15869
15870 if (dehydrated === null || isSuspenseInstancePending(dehydrated) || isSuspenseInstanceFallback(dehydrated)) {
15871 return node;
15872 }
15873 }
15874 } else if (node.tag === SuspenseListComponent && // revealOrder undefined can't be trusted because it don't
15875 // keep track of whether it suspended or not.
15876 node.memoizedProps.revealOrder !== undefined) {
15877 var didSuspend = (node.flags & DidCapture) !== NoFlags;
15878
15879 if (didSuspend) {
15880 return node;
15881 }
15882 } else if (node.child !== null) {
15883 node.child.return = node;
15884 node = node.child;
15885 continue;
15886 }
15887
15888 if (node === row) {
15889 return null;
15890 }
15891
15892 while (node.sibling === null) {
15893 if (node.return === null || node.return === row) {
15894 return null;
15895 }
15896
15897 node = node.return;
15898 }
15899
15900 node.sibling.return = node.return;
15901 node = node.sibling;
15902 }
15903
15904 return null;
15905 }
15906
15907 var NoFlags$1 =
15908 /* */
15909 0; // Represents whether effect should fire.
15910
15911 var HasEffect =
15912 /* */
15913 1; // Represents the phase in which the effect (not the clean-up) fires.
15914
15915 var Insertion =
15916 /* */
15917 2;
15918 var Layout =
15919 /* */
15920 4;
15921 var Passive$1 =
15922 /* */
15923 8;
15924
15925 // and should be reset before starting a new render.
15926 // This tracks which mutable sources need to be reset after a render.
15927
15928 var workInProgressSources = [];
15929 function resetWorkInProgressVersions() {
15930 for (var i = 0; i < workInProgressSources.length; i++) {
15931 var mutableSource = workInProgressSources[i];
15932
15933 {
15934 mutableSource._workInProgressVersionPrimary = null;
15935 }
15936 }
15937
15938 workInProgressSources.length = 0;
15939 }
15940 // This ensures that the version used for server rendering matches the one
15941 // that is eventually read during hydration.
15942 // If they don't match there's a potential tear and a full deopt render is required.
15943
15944 function registerMutableSourceForHydration(root, mutableSource) {
15945 var getVersion = mutableSource._getVersion;
15946 var version = getVersion(mutableSource._source); // TODO Clear this data once all pending hydration work is finished.
15947 // Retaining it forever may interfere with GC.
15948
15949 if (root.mutableSourceEagerHydrationData == null) {
15950 root.mutableSourceEagerHydrationData = [mutableSource, version];
15951 } else {
15952 root.mutableSourceEagerHydrationData.push(mutableSource, version);
15953 }
15954 }
15955
15956 var ReactCurrentDispatcher$1 = ReactSharedInternals.ReactCurrentDispatcher,
15957 ReactCurrentBatchConfig$2 = ReactSharedInternals.ReactCurrentBatchConfig;
15958 var didWarnAboutMismatchedHooksForComponent;
15959 var didWarnUncachedGetSnapshot;
15960
15961 {
15962 didWarnAboutMismatchedHooksForComponent = new Set();
15963 }
15964
15965 // These are set right before calling the component.
15966 var renderLanes = NoLanes; // The work-in-progress fiber. I've named it differently to distinguish it from
15967 // the work-in-progress hook.
15968
15969 var currentlyRenderingFiber$1 = null; // Hooks are stored as a linked list on the fiber's memoizedState field. The
15970 // current hook list is the list that belongs to the current fiber. The
15971 // work-in-progress hook list is a new list that will be added to the
15972 // work-in-progress fiber.
15973
15974 var currentHook = null;
15975 var workInProgressHook = null; // Whether an update was scheduled at any point during the render phase. This
15976 // does not get reset if we do another render pass; only when we're completely
15977 // finished evaluating this component. This is an optimization so we know
15978 // whether we need to clear render phase updates after a throw.
15979
15980 var didScheduleRenderPhaseUpdate = false; // Where an update was scheduled only during the current render pass. This
15981 // gets reset after each attempt.
15982 // TODO: Maybe there's some way to consolidate this with
15983 // `didScheduleRenderPhaseUpdate`. Or with `numberOfReRenders`.
15984
15985 var didScheduleRenderPhaseUpdateDuringThisPass = false; // Counts the number of useId hooks in this component.
15986
15987 var localIdCounter = 0; // Used for ids that are generated completely client-side (i.e. not during
15988 // hydration). This counter is global, so client ids are not stable across
15989 // render attempts.
15990
15991 var globalClientIdCounter = 0;
15992 var RE_RENDER_LIMIT = 25; // In DEV, this is the name of the currently executing primitive hook
15993
15994 var currentHookNameInDev = null; // In DEV, this list ensures that hooks are called in the same order between renders.
15995 // The list stores the order of hooks used during the initial render (mount).
15996 // Subsequent renders (updates) reference this list.
15997
15998 var hookTypesDev = null;
15999 var hookTypesUpdateIndexDev = -1; // In DEV, this tracks whether currently rendering component needs to ignore
16000 // the dependencies for Hooks that need them (e.g. useEffect or useMemo).
16001 // When true, such Hooks will always be "remounted". Only used during hot reload.
16002
16003 var ignorePreviousDependencies = false;
16004
16005 function mountHookTypesDev() {
16006 {
16007 var hookName = currentHookNameInDev;
16008
16009 if (hookTypesDev === null) {
16010 hookTypesDev = [hookName];
16011 } else {
16012 hookTypesDev.push(hookName);
16013 }
16014 }
16015 }
16016
16017 function updateHookTypesDev() {
16018 {
16019 var hookName = currentHookNameInDev;
16020
16021 if (hookTypesDev !== null) {
16022 hookTypesUpdateIndexDev++;
16023
16024 if (hookTypesDev[hookTypesUpdateIndexDev] !== hookName) {
16025 warnOnHookMismatchInDev(hookName);
16026 }
16027 }
16028 }
16029 }
16030
16031 function checkDepsAreArrayDev(deps) {
16032 {
16033 if (deps !== undefined && deps !== null && !isArray(deps)) {
16034 // Verify deps, but only on mount to avoid extra checks.
16035 // It's unlikely their type would change as usually you define them inline.
16036 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);
16037 }
16038 }
16039 }
16040
16041 function warnOnHookMismatchInDev(currentHookName) {
16042 {
16043 var componentName = getComponentNameFromFiber(currentlyRenderingFiber$1);
16044
16045 if (!didWarnAboutMismatchedHooksForComponent.has(componentName)) {
16046 didWarnAboutMismatchedHooksForComponent.add(componentName);
16047
16048 if (hookTypesDev !== null) {
16049 var table = '';
16050 var secondColumnStart = 30;
16051
16052 for (var i = 0; i <= hookTypesUpdateIndexDev; i++) {
16053 var oldHookName = hookTypesDev[i];
16054 var newHookName = i === hookTypesUpdateIndexDev ? currentHookName : oldHookName;
16055 var row = i + 1 + ". " + oldHookName; // Extra space so second column lines up
16056 // lol @ IE not supporting String#repeat
16057
16058 while (row.length < secondColumnStart) {
16059 row += ' ';
16060 }
16061
16062 row += newHookName + '\n';
16063 table += row;
16064 }
16065
16066 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);
16067 }
16068 }
16069 }
16070 }
16071
16072 function throwInvalidHookError() {
16073 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.');
16074 }
16075
16076 function areHookInputsEqual(nextDeps, prevDeps) {
16077 {
16078 if (ignorePreviousDependencies) {
16079 // Only true when this component is being hot reloaded.
16080 return false;
16081 }
16082 }
16083
16084 if (prevDeps === null) {
16085 {
16086 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);
16087 }
16088
16089 return false;
16090 }
16091
16092 {
16093 // Don't bother comparing lengths in prod because these arrays should be
16094 // passed inline.
16095 if (nextDeps.length !== prevDeps.length) {
16096 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(', ') + "]");
16097 }
16098 }
16099
16100 for (var i = 0; i < prevDeps.length && i < nextDeps.length; i++) {
16101 if (objectIs(nextDeps[i], prevDeps[i])) {
16102 continue;
16103 }
16104
16105 return false;
16106 }
16107
16108 return true;
16109 }
16110
16111 function renderWithHooks(current, workInProgress, Component, props, secondArg, nextRenderLanes) {
16112 renderLanes = nextRenderLanes;
16113 currentlyRenderingFiber$1 = workInProgress;
16114
16115 {
16116 hookTypesDev = current !== null ? current._debugHookTypes : null;
16117 hookTypesUpdateIndexDev = -1; // Used for hot reloading:
16118
16119 ignorePreviousDependencies = current !== null && current.type !== workInProgress.type;
16120 }
16121
16122 workInProgress.memoizedState = null;
16123 workInProgress.updateQueue = null;
16124 workInProgress.lanes = NoLanes; // The following should have already been reset
16125 // currentHook = null;
16126 // workInProgressHook = null;
16127 // didScheduleRenderPhaseUpdate = false;
16128 // localIdCounter = 0;
16129 // TODO Warn if no hooks are used at all during mount, then some are used during update.
16130 // Currently we will identify the update render as a mount because memoizedState === null.
16131 // This is tricky because it's valid for certain types of components (e.g. React.lazy)
16132 // Using memoizedState to differentiate between mount/update only works if at least one stateful hook is used.
16133 // Non-stateful hooks (e.g. context) don't get added to memoizedState,
16134 // so memoizedState would be null during updates and mounts.
16135
16136 {
16137 if (current !== null && current.memoizedState !== null) {
16138 ReactCurrentDispatcher$1.current = HooksDispatcherOnUpdateInDEV;
16139 } else if (hookTypesDev !== null) {
16140 // This dispatcher handles an edge case where a component is updating,
16141 // but no stateful hooks have been used.
16142 // We want to match the production code behavior (which will use HooksDispatcherOnMount),
16143 // but with the extra DEV validation to ensure hooks ordering hasn't changed.
16144 // This dispatcher does that.
16145 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountWithHookTypesInDEV;
16146 } else {
16147 ReactCurrentDispatcher$1.current = HooksDispatcherOnMountInDEV;
16148 }
16149 }
16150
16151 var children = Component(props, secondArg); // Check if there was a render phase update
16152
16153 if (didScheduleRenderPhaseUpdateDuringThisPass) {
16154 // Keep rendering in a loop for as long as render phase updates continue to
16155 // be scheduled. Use a counter to prevent infinite loops.
16156 var numberOfReRenders = 0;
16157
16158 do {
16159 didScheduleRenderPhaseUpdateDuringThisPass = false;
16160 localIdCounter = 0;
16161
16162 if (numberOfReRenders >= RE_RENDER_LIMIT) {
16163 throw new Error('Too many re-renders. React limits the number of renders to prevent ' + 'an infinite loop.');
16164 }
16165
16166 numberOfReRenders += 1;
16167
16168 {
16169 // Even when hot reloading, allow dependencies to stabilize
16170 // after first render to prevent infinite render phase updates.
16171 ignorePreviousDependencies = false;
16172 } // Start over from the beginning of the list
16173
16174
16175 currentHook = null;
16176 workInProgressHook = null;
16177 workInProgress.updateQueue = null;
16178
16179 {
16180 // Also validate hook order for cascading updates.
16181 hookTypesUpdateIndexDev = -1;
16182 }
16183
16184 ReactCurrentDispatcher$1.current = HooksDispatcherOnRerenderInDEV ;
16185 children = Component(props, secondArg);
16186 } while (didScheduleRenderPhaseUpdateDuringThisPass);
16187 } // We can assume the previous dispatcher is always this one, since we set it
16188 // at the beginning of the render phase and there's no re-entrance.
16189
16190
16191 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
16192
16193 {
16194 workInProgress._debugHookTypes = hookTypesDev;
16195 } // This check uses currentHook so that it works the same in DEV and prod bundles.
16196 // hookTypesDev could catch more cases (e.g. context) but only in DEV bundles.
16197
16198
16199 var didRenderTooFewHooks = currentHook !== null && currentHook.next !== null;
16200 renderLanes = NoLanes;
16201 currentlyRenderingFiber$1 = null;
16202 currentHook = null;
16203 workInProgressHook = null;
16204
16205 {
16206 currentHookNameInDev = null;
16207 hookTypesDev = null;
16208 hookTypesUpdateIndexDev = -1; // Confirm that a static flag was not added or removed since the last
16209 // render. If this fires, it suggests that we incorrectly reset the static
16210 // flags in some other part of the codebase. This has happened before, for
16211 // example, in the SuspenseList implementation.
16212
16213 if (current !== null && (current.flags & StaticMask) !== (workInProgress.flags & StaticMask) && // Disable this warning in legacy mode, because legacy Suspense is weird
16214 // and creates false positives. To make this work in legacy mode, we'd
16215 // need to mark fibers that commit in an incomplete state, somehow. For
16216 // now I'll disable the warning that most of the bugs that would trigger
16217 // it are either exclusive to concurrent mode or exist in both.
16218 (current.mode & ConcurrentMode) !== NoMode) {
16219 error('Internal React error: Expected static flag was missing. Please ' + 'notify the React team.');
16220 }
16221 }
16222
16223 didScheduleRenderPhaseUpdate = false; // This is reset by checkDidRenderIdHook
16224 // localIdCounter = 0;
16225
16226 if (didRenderTooFewHooks) {
16227 throw new Error('Rendered fewer hooks than expected. This may be caused by an accidental ' + 'early return statement.');
16228 }
16229
16230 return children;
16231 }
16232 function checkDidRenderIdHook() {
16233 // This should be called immediately after every renderWithHooks call.
16234 // Conceptually, it's part of the return value of renderWithHooks; it's only a
16235 // separate function to avoid using an array tuple.
16236 var didRenderIdHook = localIdCounter !== 0;
16237 localIdCounter = 0;
16238 return didRenderIdHook;
16239 }
16240 function bailoutHooks(current, workInProgress, lanes) {
16241 workInProgress.updateQueue = current.updateQueue; // TODO: Don't need to reset the flags here, because they're reset in the
16242 // complete phase (bubbleProperties).
16243
16244 if ( (workInProgress.mode & StrictEffectsMode) !== NoMode) {
16245 workInProgress.flags &= ~(MountPassiveDev | MountLayoutDev | Passive | Update);
16246 } else {
16247 workInProgress.flags &= ~(Passive | Update);
16248 }
16249
16250 current.lanes = removeLanes(current.lanes, lanes);
16251 }
16252 function resetHooksAfterThrow() {
16253 // We can assume the previous dispatcher is always this one, since we set it
16254 // at the beginning of the render phase and there's no re-entrance.
16255 ReactCurrentDispatcher$1.current = ContextOnlyDispatcher;
16256
16257 if (didScheduleRenderPhaseUpdate) {
16258 // There were render phase updates. These are only valid for this render
16259 // phase, which we are now aborting. Remove the updates from the queues so
16260 // they do not persist to the next render. Do not remove updates from hooks
16261 // that weren't processed.
16262 //
16263 // Only reset the updates from the queue if it has a clone. If it does
16264 // not have a clone, that means it wasn't processed, and the updates were
16265 // scheduled before we entered the render phase.
16266 var hook = currentlyRenderingFiber$1.memoizedState;
16267
16268 while (hook !== null) {
16269 var queue = hook.queue;
16270
16271 if (queue !== null) {
16272 queue.pending = null;
16273 }
16274
16275 hook = hook.next;
16276 }
16277
16278 didScheduleRenderPhaseUpdate = false;
16279 }
16280
16281 renderLanes = NoLanes;
16282 currentlyRenderingFiber$1 = null;
16283 currentHook = null;
16284 workInProgressHook = null;
16285
16286 {
16287 hookTypesDev = null;
16288 hookTypesUpdateIndexDev = -1;
16289 currentHookNameInDev = null;
16290 isUpdatingOpaqueValueInRenderPhase = false;
16291 }
16292
16293 didScheduleRenderPhaseUpdateDuringThisPass = false;
16294 localIdCounter = 0;
16295 }
16296
16297 function mountWorkInProgressHook() {
16298 var hook = {
16299 memoizedState: null,
16300 baseState: null,
16301 baseQueue: null,
16302 queue: null,
16303 next: null
16304 };
16305
16306 if (workInProgressHook === null) {
16307 // This is the first hook in the list
16308 currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
16309 } else {
16310 // Append to the end of the list
16311 workInProgressHook = workInProgressHook.next = hook;
16312 }
16313
16314 return workInProgressHook;
16315 }
16316
16317 function updateWorkInProgressHook() {
16318 // This function is used both for updates and for re-renders triggered by a
16319 // render phase update. It assumes there is either a current hook we can
16320 // clone, or a work-in-progress hook from a previous render pass that we can
16321 // use as a base. When we reach the end of the base list, we must switch to
16322 // the dispatcher used for mounts.
16323 var nextCurrentHook;
16324
16325 if (currentHook === null) {
16326 var current = currentlyRenderingFiber$1.alternate;
16327
16328 if (current !== null) {
16329 nextCurrentHook = current.memoizedState;
16330 } else {
16331 nextCurrentHook = null;
16332 }
16333 } else {
16334 nextCurrentHook = currentHook.next;
16335 }
16336
16337 var nextWorkInProgressHook;
16338
16339 if (workInProgressHook === null) {
16340 nextWorkInProgressHook = currentlyRenderingFiber$1.memoizedState;
16341 } else {
16342 nextWorkInProgressHook = workInProgressHook.next;
16343 }
16344
16345 if (nextWorkInProgressHook !== null) {
16346 // There's already a work-in-progress. Reuse it.
16347 workInProgressHook = nextWorkInProgressHook;
16348 nextWorkInProgressHook = workInProgressHook.next;
16349 currentHook = nextCurrentHook;
16350 } else {
16351 // Clone from the current hook.
16352 if (nextCurrentHook === null) {
16353 throw new Error('Rendered more hooks than during the previous render.');
16354 }
16355
16356 currentHook = nextCurrentHook;
16357 var newHook = {
16358 memoizedState: currentHook.memoizedState,
16359 baseState: currentHook.baseState,
16360 baseQueue: currentHook.baseQueue,
16361 queue: currentHook.queue,
16362 next: null
16363 };
16364
16365 if (workInProgressHook === null) {
16366 // This is the first hook in the list.
16367 currentlyRenderingFiber$1.memoizedState = workInProgressHook = newHook;
16368 } else {
16369 // Append to the end of the list.
16370 workInProgressHook = workInProgressHook.next = newHook;
16371 }
16372 }
16373
16374 return workInProgressHook;
16375 }
16376
16377 function createFunctionComponentUpdateQueue() {
16378 return {
16379 lastEffect: null,
16380 stores: null
16381 };
16382 }
16383
16384 function basicStateReducer(state, action) {
16385 // $FlowFixMe: Flow doesn't like mixed types
16386 return typeof action === 'function' ? action(state) : action;
16387 }
16388
16389 function mountReducer(reducer, initialArg, init) {
16390 var hook = mountWorkInProgressHook();
16391 var initialState;
16392
16393 if (init !== undefined) {
16394 initialState = init(initialArg);
16395 } else {
16396 initialState = initialArg;
16397 }
16398
16399 hook.memoizedState = hook.baseState = initialState;
16400 var queue = {
16401 pending: null,
16402 interleaved: null,
16403 lanes: NoLanes,
16404 dispatch: null,
16405 lastRenderedReducer: reducer,
16406 lastRenderedState: initialState
16407 };
16408 hook.queue = queue;
16409 var dispatch = queue.dispatch = dispatchReducerAction.bind(null, currentlyRenderingFiber$1, queue);
16410 return [hook.memoizedState, dispatch];
16411 }
16412
16413 function updateReducer(reducer, initialArg, init) {
16414 var hook = updateWorkInProgressHook();
16415 var queue = hook.queue;
16416
16417 if (queue === null) {
16418 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
16419 }
16420
16421 queue.lastRenderedReducer = reducer;
16422 var current = currentHook; // The last rebase update that is NOT part of the base state.
16423
16424 var baseQueue = current.baseQueue; // The last pending update that hasn't been processed yet.
16425
16426 var pendingQueue = queue.pending;
16427
16428 if (pendingQueue !== null) {
16429 // We have new updates that haven't been processed yet.
16430 // We'll add them to the base queue.
16431 if (baseQueue !== null) {
16432 // Merge the pending queue and the base queue.
16433 var baseFirst = baseQueue.next;
16434 var pendingFirst = pendingQueue.next;
16435 baseQueue.next = pendingFirst;
16436 pendingQueue.next = baseFirst;
16437 }
16438
16439 {
16440 if (current.baseQueue !== baseQueue) {
16441 // Internal invariant that should never happen, but feasibly could in
16442 // the future if we implement resuming, or some form of that.
16443 error('Internal error: Expected work-in-progress queue to be a clone. ' + 'This is a bug in React.');
16444 }
16445 }
16446
16447 current.baseQueue = baseQueue = pendingQueue;
16448 queue.pending = null;
16449 }
16450
16451 if (baseQueue !== null) {
16452 // We have a queue to process.
16453 var first = baseQueue.next;
16454 var newState = current.baseState;
16455 var newBaseState = null;
16456 var newBaseQueueFirst = null;
16457 var newBaseQueueLast = null;
16458 var update = first;
16459
16460 do {
16461 var updateLane = update.lane;
16462
16463 if (!isSubsetOfLanes(renderLanes, updateLane)) {
16464 // Priority is insufficient. Skip this update. If this is the first
16465 // skipped update, the previous update/state is the new base
16466 // update/state.
16467 var clone = {
16468 lane: updateLane,
16469 action: update.action,
16470 hasEagerState: update.hasEagerState,
16471 eagerState: update.eagerState,
16472 next: null
16473 };
16474
16475 if (newBaseQueueLast === null) {
16476 newBaseQueueFirst = newBaseQueueLast = clone;
16477 newBaseState = newState;
16478 } else {
16479 newBaseQueueLast = newBaseQueueLast.next = clone;
16480 } // Update the remaining priority in the queue.
16481 // TODO: Don't need to accumulate this. Instead, we can remove
16482 // renderLanes from the original lanes.
16483
16484
16485 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, updateLane);
16486 markSkippedUpdateLanes(updateLane);
16487 } else {
16488 // This update does have sufficient priority.
16489 if (newBaseQueueLast !== null) {
16490 var _clone = {
16491 // This update is going to be committed so we never want uncommit
16492 // it. Using NoLane works because 0 is a subset of all bitmasks, so
16493 // this will never be skipped by the check above.
16494 lane: NoLane,
16495 action: update.action,
16496 hasEagerState: update.hasEagerState,
16497 eagerState: update.eagerState,
16498 next: null
16499 };
16500 newBaseQueueLast = newBaseQueueLast.next = _clone;
16501 } // Process this update.
16502
16503
16504 if (update.hasEagerState) {
16505 // If this update is a state update (not a reducer) and was processed eagerly,
16506 // we can use the eagerly computed state
16507 newState = update.eagerState;
16508 } else {
16509 var action = update.action;
16510 newState = reducer(newState, action);
16511 }
16512 }
16513
16514 update = update.next;
16515 } while (update !== null && update !== first);
16516
16517 if (newBaseQueueLast === null) {
16518 newBaseState = newState;
16519 } else {
16520 newBaseQueueLast.next = newBaseQueueFirst;
16521 } // Mark that the fiber performed work, but only if the new state is
16522 // different from the current state.
16523
16524
16525 if (!objectIs(newState, hook.memoizedState)) {
16526 markWorkInProgressReceivedUpdate();
16527 }
16528
16529 hook.memoizedState = newState;
16530 hook.baseState = newBaseState;
16531 hook.baseQueue = newBaseQueueLast;
16532 queue.lastRenderedState = newState;
16533 } // Interleaved updates are stored on a separate queue. We aren't going to
16534 // process them during this render, but we do need to track which lanes
16535 // are remaining.
16536
16537
16538 var lastInterleaved = queue.interleaved;
16539
16540 if (lastInterleaved !== null) {
16541 var interleaved = lastInterleaved;
16542
16543 do {
16544 var interleavedLane = interleaved.lane;
16545 currentlyRenderingFiber$1.lanes = mergeLanes(currentlyRenderingFiber$1.lanes, interleavedLane);
16546 markSkippedUpdateLanes(interleavedLane);
16547 interleaved = interleaved.next;
16548 } while (interleaved !== lastInterleaved);
16549 } else if (baseQueue === null) {
16550 // `queue.lanes` is used for entangling transitions. We can set it back to
16551 // zero once the queue is empty.
16552 queue.lanes = NoLanes;
16553 }
16554
16555 var dispatch = queue.dispatch;
16556 return [hook.memoizedState, dispatch];
16557 }
16558
16559 function rerenderReducer(reducer, initialArg, init) {
16560 var hook = updateWorkInProgressHook();
16561 var queue = hook.queue;
16562
16563 if (queue === null) {
16564 throw new Error('Should have a queue. This is likely a bug in React. Please file an issue.');
16565 }
16566
16567 queue.lastRenderedReducer = reducer; // This is a re-render. Apply the new render phase updates to the previous
16568 // work-in-progress hook.
16569
16570 var dispatch = queue.dispatch;
16571 var lastRenderPhaseUpdate = queue.pending;
16572 var newState = hook.memoizedState;
16573
16574 if (lastRenderPhaseUpdate !== null) {
16575 // The queue doesn't persist past this render pass.
16576 queue.pending = null;
16577 var firstRenderPhaseUpdate = lastRenderPhaseUpdate.next;
16578 var update = firstRenderPhaseUpdate;
16579
16580 do {
16581 // Process this render phase update. We don't have to check the
16582 // priority because it will always be the same as the current
16583 // render's.
16584 var action = update.action;
16585 newState = reducer(newState, action);
16586 update = update.next;
16587 } while (update !== firstRenderPhaseUpdate); // Mark that the fiber performed work, but only if the new state is
16588 // different from the current state.
16589
16590
16591 if (!objectIs(newState, hook.memoizedState)) {
16592 markWorkInProgressReceivedUpdate();
16593 }
16594
16595 hook.memoizedState = newState; // Don't persist the state accumulated from the render phase updates to
16596 // the base state unless the queue is empty.
16597 // TODO: Not sure if this is the desired semantics, but it's what we
16598 // do for gDSFP. I can't remember why.
16599
16600 if (hook.baseQueue === null) {
16601 hook.baseState = newState;
16602 }
16603
16604 queue.lastRenderedState = newState;
16605 }
16606
16607 return [newState, dispatch];
16608 }
16609
16610 function mountMutableSource(source, getSnapshot, subscribe) {
16611 {
16612 return undefined;
16613 }
16614 }
16615
16616 function updateMutableSource(source, getSnapshot, subscribe) {
16617 {
16618 return undefined;
16619 }
16620 }
16621
16622 function mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
16623 var fiber = currentlyRenderingFiber$1;
16624 var hook = mountWorkInProgressHook();
16625 var nextSnapshot;
16626 var isHydrating = getIsHydrating();
16627
16628 if (isHydrating) {
16629 if (getServerSnapshot === undefined) {
16630 throw new Error('Missing getServerSnapshot, which is required for ' + 'server-rendered content. Will revert to client rendering.');
16631 }
16632
16633 nextSnapshot = getServerSnapshot();
16634
16635 {
16636 if (!didWarnUncachedGetSnapshot) {
16637 if (nextSnapshot !== getServerSnapshot()) {
16638 error('The result of getServerSnapshot should be cached to avoid an infinite loop');
16639
16640 didWarnUncachedGetSnapshot = true;
16641 }
16642 }
16643 }
16644 } else {
16645 nextSnapshot = getSnapshot();
16646
16647 {
16648 if (!didWarnUncachedGetSnapshot) {
16649 var cachedSnapshot = getSnapshot();
16650
16651 if (!objectIs(nextSnapshot, cachedSnapshot)) {
16652 error('The result of getSnapshot should be cached to avoid an infinite loop');
16653
16654 didWarnUncachedGetSnapshot = true;
16655 }
16656 }
16657 } // Unless we're rendering a blocking lane, schedule a consistency check.
16658 // Right before committing, we will walk the tree and check if any of the
16659 // stores were mutated.
16660 //
16661 // We won't do this if we're hydrating server-rendered content, because if
16662 // the content is stale, it's already visible anyway. Instead we'll patch
16663 // it up in a passive effect.
16664
16665
16666 var root = getWorkInProgressRoot();
16667
16668 if (root === null) {
16669 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
16670 }
16671
16672 if (!includesBlockingLane(root, renderLanes)) {
16673 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
16674 }
16675 } // Read the current snapshot from the store on every render. This breaks the
16676 // normal rules of React, and only works because store updates are
16677 // always synchronous.
16678
16679
16680 hook.memoizedState = nextSnapshot;
16681 var inst = {
16682 value: nextSnapshot,
16683 getSnapshot: getSnapshot
16684 };
16685 hook.queue = inst; // Schedule an effect to subscribe to the store.
16686
16687 mountEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Schedule an effect to update the mutable instance fields. We will update
16688 // this whenever subscribe, getSnapshot, or value changes. Because there's no
16689 // clean-up function, and we track the deps correctly, we can call pushEffect
16690 // directly, without storing any additional state. For the same reason, we
16691 // don't need to set a static flag, either.
16692 // TODO: We can move this to the passive phase once we add a pre-commit
16693 // consistency check. See the next comment.
16694
16695 fiber.flags |= Passive;
16696 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null);
16697 return nextSnapshot;
16698 }
16699
16700 function updateSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
16701 var fiber = currentlyRenderingFiber$1;
16702 var hook = updateWorkInProgressHook(); // Read the current snapshot from the store on every render. This breaks the
16703 // normal rules of React, and only works because store updates are
16704 // always synchronous.
16705
16706 var nextSnapshot = getSnapshot();
16707
16708 {
16709 if (!didWarnUncachedGetSnapshot) {
16710 var cachedSnapshot = getSnapshot();
16711
16712 if (!objectIs(nextSnapshot, cachedSnapshot)) {
16713 error('The result of getSnapshot should be cached to avoid an infinite loop');
16714
16715 didWarnUncachedGetSnapshot = true;
16716 }
16717 }
16718 }
16719
16720 var prevSnapshot = hook.memoizedState;
16721 var snapshotChanged = !objectIs(prevSnapshot, nextSnapshot);
16722
16723 if (snapshotChanged) {
16724 hook.memoizedState = nextSnapshot;
16725 markWorkInProgressReceivedUpdate();
16726 }
16727
16728 var inst = hook.queue;
16729 updateEffect(subscribeToStore.bind(null, fiber, inst, subscribe), [subscribe]); // Whenever getSnapshot or subscribe changes, we need to check in the
16730 // commit phase if there was an interleaved mutation. In concurrent mode
16731 // this can happen all the time, but even in synchronous mode, an earlier
16732 // effect may have mutated the store.
16733
16734 if (inst.getSnapshot !== getSnapshot || snapshotChanged || // Check if the susbcribe function changed. We can save some memory by
16735 // checking whether we scheduled a subscription effect above.
16736 workInProgressHook !== null && workInProgressHook.memoizedState.tag & HasEffect) {
16737 fiber.flags |= Passive;
16738 pushEffect(HasEffect | Passive$1, updateStoreInstance.bind(null, fiber, inst, nextSnapshot, getSnapshot), undefined, null); // Unless we're rendering a blocking lane, schedule a consistency check.
16739 // Right before committing, we will walk the tree and check if any of the
16740 // stores were mutated.
16741
16742 var root = getWorkInProgressRoot();
16743
16744 if (root === null) {
16745 throw new Error('Expected a work-in-progress root. This is a bug in React. Please file an issue.');
16746 }
16747
16748 if (!includesBlockingLane(root, renderLanes)) {
16749 pushStoreConsistencyCheck(fiber, getSnapshot, nextSnapshot);
16750 }
16751 }
16752
16753 return nextSnapshot;
16754 }
16755
16756 function pushStoreConsistencyCheck(fiber, getSnapshot, renderedSnapshot) {
16757 fiber.flags |= StoreConsistency;
16758 var check = {
16759 getSnapshot: getSnapshot,
16760 value: renderedSnapshot
16761 };
16762 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
16763
16764 if (componentUpdateQueue === null) {
16765 componentUpdateQueue = createFunctionComponentUpdateQueue();
16766 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
16767 componentUpdateQueue.stores = [check];
16768 } else {
16769 var stores = componentUpdateQueue.stores;
16770
16771 if (stores === null) {
16772 componentUpdateQueue.stores = [check];
16773 } else {
16774 stores.push(check);
16775 }
16776 }
16777 }
16778
16779 function updateStoreInstance(fiber, inst, nextSnapshot, getSnapshot) {
16780 // These are updated in the passive phase
16781 inst.value = nextSnapshot;
16782 inst.getSnapshot = getSnapshot; // Something may have been mutated in between render and commit. This could
16783 // have been in an event that fired before the passive effects, or it could
16784 // have been in a layout effect. In that case, we would have used the old
16785 // snapsho and getSnapshot values to bail out. We need to check one more time.
16786
16787 if (checkIfSnapshotChanged(inst)) {
16788 // Force a re-render.
16789 forceStoreRerender(fiber);
16790 }
16791 }
16792
16793 function subscribeToStore(fiber, inst, subscribe) {
16794 var handleStoreChange = function () {
16795 // The store changed. Check if the snapshot changed since the last time we
16796 // read from the store.
16797 if (checkIfSnapshotChanged(inst)) {
16798 // Force a re-render.
16799 forceStoreRerender(fiber);
16800 }
16801 }; // Subscribe to the store and return a clean-up function.
16802
16803
16804 return subscribe(handleStoreChange);
16805 }
16806
16807 function checkIfSnapshotChanged(inst) {
16808 var latestGetSnapshot = inst.getSnapshot;
16809 var prevValue = inst.value;
16810
16811 try {
16812 var nextValue = latestGetSnapshot();
16813 return !objectIs(prevValue, nextValue);
16814 } catch (error) {
16815 return true;
16816 }
16817 }
16818
16819 function forceStoreRerender(fiber) {
16820 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
16821 }
16822
16823 function mountState(initialState) {
16824 var hook = mountWorkInProgressHook();
16825
16826 if (typeof initialState === 'function') {
16827 // $FlowFixMe: Flow doesn't like mixed types
16828 initialState = initialState();
16829 }
16830
16831 hook.memoizedState = hook.baseState = initialState;
16832 var queue = {
16833 pending: null,
16834 interleaved: null,
16835 lanes: NoLanes,
16836 dispatch: null,
16837 lastRenderedReducer: basicStateReducer,
16838 lastRenderedState: initialState
16839 };
16840 hook.queue = queue;
16841 var dispatch = queue.dispatch = dispatchSetState.bind(null, currentlyRenderingFiber$1, queue);
16842 return [hook.memoizedState, dispatch];
16843 }
16844
16845 function updateState(initialState) {
16846 return updateReducer(basicStateReducer);
16847 }
16848
16849 function rerenderState(initialState) {
16850 return rerenderReducer(basicStateReducer);
16851 }
16852
16853 function pushEffect(tag, create, destroy, deps) {
16854 var effect = {
16855 tag: tag,
16856 create: create,
16857 destroy: destroy,
16858 deps: deps,
16859 // Circular
16860 next: null
16861 };
16862 var componentUpdateQueue = currentlyRenderingFiber$1.updateQueue;
16863
16864 if (componentUpdateQueue === null) {
16865 componentUpdateQueue = createFunctionComponentUpdateQueue();
16866 currentlyRenderingFiber$1.updateQueue = componentUpdateQueue;
16867 componentUpdateQueue.lastEffect = effect.next = effect;
16868 } else {
16869 var lastEffect = componentUpdateQueue.lastEffect;
16870
16871 if (lastEffect === null) {
16872 componentUpdateQueue.lastEffect = effect.next = effect;
16873 } else {
16874 var firstEffect = lastEffect.next;
16875 lastEffect.next = effect;
16876 effect.next = firstEffect;
16877 componentUpdateQueue.lastEffect = effect;
16878 }
16879 }
16880
16881 return effect;
16882 }
16883
16884 function mountRef(initialValue) {
16885 var hook = mountWorkInProgressHook();
16886
16887 {
16888 var _ref2 = {
16889 current: initialValue
16890 };
16891 hook.memoizedState = _ref2;
16892 return _ref2;
16893 }
16894 }
16895
16896 function updateRef(initialValue) {
16897 var hook = updateWorkInProgressHook();
16898 return hook.memoizedState;
16899 }
16900
16901 function mountEffectImpl(fiberFlags, hookFlags, create, deps) {
16902 var hook = mountWorkInProgressHook();
16903 var nextDeps = deps === undefined ? null : deps;
16904 currentlyRenderingFiber$1.flags |= fiberFlags;
16905 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, undefined, nextDeps);
16906 }
16907
16908 function updateEffectImpl(fiberFlags, hookFlags, create, deps) {
16909 var hook = updateWorkInProgressHook();
16910 var nextDeps = deps === undefined ? null : deps;
16911 var destroy = undefined;
16912
16913 if (currentHook !== null) {
16914 var prevEffect = currentHook.memoizedState;
16915 destroy = prevEffect.destroy;
16916
16917 if (nextDeps !== null) {
16918 var prevDeps = prevEffect.deps;
16919
16920 if (areHookInputsEqual(nextDeps, prevDeps)) {
16921 hook.memoizedState = pushEffect(hookFlags, create, destroy, nextDeps);
16922 return;
16923 }
16924 }
16925 }
16926
16927 currentlyRenderingFiber$1.flags |= fiberFlags;
16928 hook.memoizedState = pushEffect(HasEffect | hookFlags, create, destroy, nextDeps);
16929 }
16930
16931 function mountEffect(create, deps) {
16932 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
16933 return mountEffectImpl(MountPassiveDev | Passive | PassiveStatic, Passive$1, create, deps);
16934 } else {
16935 return mountEffectImpl(Passive | PassiveStatic, Passive$1, create, deps);
16936 }
16937 }
16938
16939 function updateEffect(create, deps) {
16940 return updateEffectImpl(Passive, Passive$1, create, deps);
16941 }
16942
16943 function mountInsertionEffect(create, deps) {
16944 return mountEffectImpl(Update, Insertion, create, deps);
16945 }
16946
16947 function updateInsertionEffect(create, deps) {
16948 return updateEffectImpl(Update, Insertion, create, deps);
16949 }
16950
16951 function mountLayoutEffect(create, deps) {
16952 var fiberFlags = Update;
16953
16954 {
16955 fiberFlags |= LayoutStatic;
16956 }
16957
16958 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
16959 fiberFlags |= MountLayoutDev;
16960 }
16961
16962 return mountEffectImpl(fiberFlags, Layout, create, deps);
16963 }
16964
16965 function updateLayoutEffect(create, deps) {
16966 return updateEffectImpl(Update, Layout, create, deps);
16967 }
16968
16969 function imperativeHandleEffect(create, ref) {
16970 if (typeof ref === 'function') {
16971 var refCallback = ref;
16972
16973 var _inst = create();
16974
16975 refCallback(_inst);
16976 return function () {
16977 refCallback(null);
16978 };
16979 } else if (ref !== null && ref !== undefined) {
16980 var refObject = ref;
16981
16982 {
16983 if (!refObject.hasOwnProperty('current')) {
16984 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(', ') + '}');
16985 }
16986 }
16987
16988 var _inst2 = create();
16989
16990 refObject.current = _inst2;
16991 return function () {
16992 refObject.current = null;
16993 };
16994 }
16995 }
16996
16997 function mountImperativeHandle(ref, create, deps) {
16998 {
16999 if (typeof create !== 'function') {
17000 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
17001 }
17002 } // TODO: If deps are provided, should we skip comparing the ref itself?
17003
17004
17005 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
17006 var fiberFlags = Update;
17007
17008 {
17009 fiberFlags |= LayoutStatic;
17010 }
17011
17012 if ( (currentlyRenderingFiber$1.mode & StrictEffectsMode) !== NoMode) {
17013 fiberFlags |= MountLayoutDev;
17014 }
17015
17016 return mountEffectImpl(fiberFlags, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
17017 }
17018
17019 function updateImperativeHandle(ref, create, deps) {
17020 {
17021 if (typeof create !== 'function') {
17022 error('Expected useImperativeHandle() second argument to be a function ' + 'that creates a handle. Instead received: %s.', create !== null ? typeof create : 'null');
17023 }
17024 } // TODO: If deps are provided, should we skip comparing the ref itself?
17025
17026
17027 var effectDeps = deps !== null && deps !== undefined ? deps.concat([ref]) : null;
17028 return updateEffectImpl(Update, Layout, imperativeHandleEffect.bind(null, create, ref), effectDeps);
17029 }
17030
17031 function mountDebugValue(value, formatterFn) {// This hook is normally a no-op.
17032 // The react-debug-hooks package injects its own implementation
17033 // so that e.g. DevTools can display custom hook values.
17034 }
17035
17036 var updateDebugValue = mountDebugValue;
17037
17038 function mountCallback(callback, deps) {
17039 var hook = mountWorkInProgressHook();
17040 var nextDeps = deps === undefined ? null : deps;
17041 hook.memoizedState = [callback, nextDeps];
17042 return callback;
17043 }
17044
17045 function updateCallback(callback, deps) {
17046 var hook = updateWorkInProgressHook();
17047 var nextDeps = deps === undefined ? null : deps;
17048 var prevState = hook.memoizedState;
17049
17050 if (prevState !== null) {
17051 if (nextDeps !== null) {
17052 var prevDeps = prevState[1];
17053
17054 if (areHookInputsEqual(nextDeps, prevDeps)) {
17055 return prevState[0];
17056 }
17057 }
17058 }
17059
17060 hook.memoizedState = [callback, nextDeps];
17061 return callback;
17062 }
17063
17064 function mountMemo(nextCreate, deps) {
17065 var hook = mountWorkInProgressHook();
17066 var nextDeps = deps === undefined ? null : deps;
17067 var nextValue = nextCreate();
17068 hook.memoizedState = [nextValue, nextDeps];
17069 return nextValue;
17070 }
17071
17072 function updateMemo(nextCreate, deps) {
17073 var hook = updateWorkInProgressHook();
17074 var nextDeps = deps === undefined ? null : deps;
17075 var prevState = hook.memoizedState;
17076
17077 if (prevState !== null) {
17078 // Assume these are defined. If they're not, areHookInputsEqual will warn.
17079 if (nextDeps !== null) {
17080 var prevDeps = prevState[1];
17081
17082 if (areHookInputsEqual(nextDeps, prevDeps)) {
17083 return prevState[0];
17084 }
17085 }
17086 }
17087
17088 var nextValue = nextCreate();
17089 hook.memoizedState = [nextValue, nextDeps];
17090 return nextValue;
17091 }
17092
17093 function mountDeferredValue(value) {
17094 var _mountState = mountState(value),
17095 prevValue = _mountState[0],
17096 setValue = _mountState[1];
17097
17098 mountEffect(function () {
17099 var prevTransition = ReactCurrentBatchConfig$2.transition;
17100 ReactCurrentBatchConfig$2.transition = {};
17101
17102 try {
17103 setValue(value);
17104 } finally {
17105 ReactCurrentBatchConfig$2.transition = prevTransition;
17106 }
17107 }, [value]);
17108 return prevValue;
17109 }
17110
17111 function updateDeferredValue(value) {
17112 var _updateState = updateState(),
17113 prevValue = _updateState[0],
17114 setValue = _updateState[1];
17115
17116 updateEffect(function () {
17117 var prevTransition = ReactCurrentBatchConfig$2.transition;
17118 ReactCurrentBatchConfig$2.transition = {};
17119
17120 try {
17121 setValue(value);
17122 } finally {
17123 ReactCurrentBatchConfig$2.transition = prevTransition;
17124 }
17125 }, [value]);
17126 return prevValue;
17127 }
17128
17129 function rerenderDeferredValue(value) {
17130 var _rerenderState = rerenderState(),
17131 prevValue = _rerenderState[0],
17132 setValue = _rerenderState[1];
17133
17134 updateEffect(function () {
17135 var prevTransition = ReactCurrentBatchConfig$2.transition;
17136 ReactCurrentBatchConfig$2.transition = {};
17137
17138 try {
17139 setValue(value);
17140 } finally {
17141 ReactCurrentBatchConfig$2.transition = prevTransition;
17142 }
17143 }, [value]);
17144 return prevValue;
17145 }
17146
17147 function startTransition(setPending, callback, options) {
17148 var previousPriority = getCurrentUpdatePriority();
17149 setCurrentUpdatePriority(higherEventPriority(previousPriority, ContinuousEventPriority));
17150 setPending(true);
17151 var prevTransition = ReactCurrentBatchConfig$2.transition;
17152 ReactCurrentBatchConfig$2.transition = {};
17153 var currentTransition = ReactCurrentBatchConfig$2.transition;
17154
17155 {
17156 ReactCurrentBatchConfig$2.transition._updatedFibers = new Set();
17157 }
17158
17159 try {
17160 setPending(false);
17161 callback();
17162 } finally {
17163 setCurrentUpdatePriority(previousPriority);
17164 ReactCurrentBatchConfig$2.transition = prevTransition;
17165
17166 {
17167 if (prevTransition === null && currentTransition._updatedFibers) {
17168 var updatedFibersCount = currentTransition._updatedFibers.size;
17169
17170 if (updatedFibersCount > 10) {
17171 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.');
17172 }
17173
17174 currentTransition._updatedFibers.clear();
17175 }
17176 }
17177 }
17178 }
17179
17180 function mountTransition() {
17181 var _mountState2 = mountState(false),
17182 isPending = _mountState2[0],
17183 setPending = _mountState2[1]; // The `start` method never changes.
17184
17185
17186 var start = startTransition.bind(null, setPending);
17187 var hook = mountWorkInProgressHook();
17188 hook.memoizedState = start;
17189 return [isPending, start];
17190 }
17191
17192 function updateTransition() {
17193 var _updateState2 = updateState(),
17194 isPending = _updateState2[0];
17195
17196 var hook = updateWorkInProgressHook();
17197 var start = hook.memoizedState;
17198 return [isPending, start];
17199 }
17200
17201 function rerenderTransition() {
17202 var _rerenderState2 = rerenderState(),
17203 isPending = _rerenderState2[0];
17204
17205 var hook = updateWorkInProgressHook();
17206 var start = hook.memoizedState;
17207 return [isPending, start];
17208 }
17209
17210 var isUpdatingOpaqueValueInRenderPhase = false;
17211 function getIsUpdatingOpaqueValueInRenderPhaseInDEV() {
17212 {
17213 return isUpdatingOpaqueValueInRenderPhase;
17214 }
17215 }
17216
17217 function mountId() {
17218 var hook = mountWorkInProgressHook();
17219 var root = getWorkInProgressRoot(); // TODO: In Fizz, id generation is specific to each server config. Maybe we
17220 // should do this in Fiber, too? Deferring this decision for now because
17221 // there's no other place to store the prefix except for an internal field on
17222 // the public createRoot object, which the fiber tree does not currently have
17223 // a reference to.
17224
17225 var identifierPrefix = root.identifierPrefix;
17226 var id;
17227
17228 if (getIsHydrating()) {
17229 var treeId = getTreeId(); // Use a captial R prefix for server-generated ids.
17230
17231 id = ':' + identifierPrefix + 'R' + treeId; // Unless this is the first id at this level, append a number at the end
17232 // that represents the position of this useId hook among all the useId
17233 // hooks for this fiber.
17234
17235 var localId = localIdCounter++;
17236
17237 if (localId > 0) {
17238 id += 'H' + localId.toString(32);
17239 }
17240
17241 id += ':';
17242 } else {
17243 // Use a lowercase r prefix for client-generated ids.
17244 var globalClientId = globalClientIdCounter++;
17245 id = ':' + identifierPrefix + 'r' + globalClientId.toString(32) + ':';
17246 }
17247
17248 hook.memoizedState = id;
17249 return id;
17250 }
17251
17252 function updateId() {
17253 var hook = updateWorkInProgressHook();
17254 var id = hook.memoizedState;
17255 return id;
17256 }
17257
17258 function dispatchReducerAction(fiber, queue, action) {
17259 {
17260 if (typeof arguments[3] === 'function') {
17261 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().');
17262 }
17263 }
17264
17265 var lane = requestUpdateLane(fiber);
17266 var update = {
17267 lane: lane,
17268 action: action,
17269 hasEagerState: false,
17270 eagerState: null,
17271 next: null
17272 };
17273
17274 if (isRenderPhaseUpdate(fiber)) {
17275 enqueueRenderPhaseUpdate(queue, update);
17276 } else {
17277 enqueueUpdate$1(fiber, queue, update);
17278 var eventTime = requestEventTime();
17279 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
17280
17281 if (root !== null) {
17282 entangleTransitionUpdate(root, queue, lane);
17283 }
17284 }
17285
17286 markUpdateInDevTools(fiber, lane);
17287 }
17288
17289 function dispatchSetState(fiber, queue, action) {
17290 {
17291 if (typeof arguments[3] === 'function') {
17292 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().');
17293 }
17294 }
17295
17296 var lane = requestUpdateLane(fiber);
17297 var update = {
17298 lane: lane,
17299 action: action,
17300 hasEagerState: false,
17301 eagerState: null,
17302 next: null
17303 };
17304
17305 if (isRenderPhaseUpdate(fiber)) {
17306 enqueueRenderPhaseUpdate(queue, update);
17307 } else {
17308 enqueueUpdate$1(fiber, queue, update);
17309 var alternate = fiber.alternate;
17310
17311 if (fiber.lanes === NoLanes && (alternate === null || alternate.lanes === NoLanes)) {
17312 // The queue is currently empty, which means we can eagerly compute the
17313 // next state before entering the render phase. If the new state is the
17314 // same as the current state, we may be able to bail out entirely.
17315 var lastRenderedReducer = queue.lastRenderedReducer;
17316
17317 if (lastRenderedReducer !== null) {
17318 var prevDispatcher;
17319
17320 {
17321 prevDispatcher = ReactCurrentDispatcher$1.current;
17322 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17323 }
17324
17325 try {
17326 var currentState = queue.lastRenderedState;
17327 var eagerState = lastRenderedReducer(currentState, action); // Stash the eagerly computed state, and the reducer used to compute
17328 // it, on the update object. If the reducer hasn't changed by the
17329 // time we enter the render phase, then the eager state can be used
17330 // without calling the reducer again.
17331
17332 update.hasEagerState = true;
17333 update.eagerState = eagerState;
17334
17335 if (objectIs(eagerState, currentState)) {
17336 // Fast path. We can bail out without scheduling React to re-render.
17337 // It's still possible that we'll need to rebase this update later,
17338 // if the component re-renders for a different reason and by that
17339 // time the reducer has changed.
17340 return;
17341 }
17342 } catch (error) {// Suppress the error. It will throw again in the render phase.
17343 } finally {
17344 {
17345 ReactCurrentDispatcher$1.current = prevDispatcher;
17346 }
17347 }
17348 }
17349 }
17350
17351 var eventTime = requestEventTime();
17352 var root = scheduleUpdateOnFiber(fiber, lane, eventTime);
17353
17354 if (root !== null) {
17355 entangleTransitionUpdate(root, queue, lane);
17356 }
17357 }
17358
17359 markUpdateInDevTools(fiber, lane);
17360 }
17361
17362 function isRenderPhaseUpdate(fiber) {
17363 var alternate = fiber.alternate;
17364 return fiber === currentlyRenderingFiber$1 || alternate !== null && alternate === currentlyRenderingFiber$1;
17365 }
17366
17367 function enqueueRenderPhaseUpdate(queue, update) {
17368 // This is a render phase update. Stash it in a lazily-created map of
17369 // queue -> linked list of updates. After this render pass, we'll restart
17370 // and apply the stashed updates on top of the work-in-progress hook.
17371 didScheduleRenderPhaseUpdateDuringThisPass = didScheduleRenderPhaseUpdate = true;
17372 var pending = queue.pending;
17373
17374 if (pending === null) {
17375 // This is the first update. Create a circular list.
17376 update.next = update;
17377 } else {
17378 update.next = pending.next;
17379 pending.next = update;
17380 }
17381
17382 queue.pending = update;
17383 }
17384
17385 function enqueueUpdate$1(fiber, queue, update, lane) {
17386 if (isInterleavedUpdate(fiber)) {
17387 var interleaved = queue.interleaved;
17388
17389 if (interleaved === null) {
17390 // This is the first update. Create a circular list.
17391 update.next = update; // At the end of the current render, this queue's interleaved updates will
17392 // be transferred to the pending queue.
17393
17394 pushInterleavedQueue(queue);
17395 } else {
17396 update.next = interleaved.next;
17397 interleaved.next = update;
17398 }
17399
17400 queue.interleaved = update;
17401 } else {
17402 var pending = queue.pending;
17403
17404 if (pending === null) {
17405 // This is the first update. Create a circular list.
17406 update.next = update;
17407 } else {
17408 update.next = pending.next;
17409 pending.next = update;
17410 }
17411
17412 queue.pending = update;
17413 }
17414 }
17415
17416 function entangleTransitionUpdate(root, queue, lane) {
17417 if (isTransitionLane(lane)) {
17418 var queueLanes = queue.lanes; // If any entangled lanes are no longer pending on the root, then they
17419 // must have finished. We can remove them from the shared queue, which
17420 // represents a superset of the actually pending lanes. In some cases we
17421 // may entangle more than we need to, but that's OK. In fact it's worse if
17422 // we *don't* entangle when we should.
17423
17424 queueLanes = intersectLanes(queueLanes, root.pendingLanes); // Entangle the new transition lane with the other transition lanes.
17425
17426 var newQueueLanes = mergeLanes(queueLanes, lane);
17427 queue.lanes = newQueueLanes; // Even if queue.lanes already include lane, we don't know for certain if
17428 // the lane finished since the last time we entangled it. So we need to
17429 // entangle it again, just to be sure.
17430
17431 markRootEntangled(root, newQueueLanes);
17432 }
17433 }
17434
17435 function markUpdateInDevTools(fiber, lane, action) {
17436
17437 {
17438 markStateUpdateScheduled(fiber, lane);
17439 }
17440 }
17441
17442 var ContextOnlyDispatcher = {
17443 readContext: readContext,
17444 useCallback: throwInvalidHookError,
17445 useContext: throwInvalidHookError,
17446 useEffect: throwInvalidHookError,
17447 useImperativeHandle: throwInvalidHookError,
17448 useInsertionEffect: throwInvalidHookError,
17449 useLayoutEffect: throwInvalidHookError,
17450 useMemo: throwInvalidHookError,
17451 useReducer: throwInvalidHookError,
17452 useRef: throwInvalidHookError,
17453 useState: throwInvalidHookError,
17454 useDebugValue: throwInvalidHookError,
17455 useDeferredValue: throwInvalidHookError,
17456 useTransition: throwInvalidHookError,
17457 useMutableSource: throwInvalidHookError,
17458 useSyncExternalStore: throwInvalidHookError,
17459 useId: throwInvalidHookError,
17460 unstable_isNewReconciler: enableNewReconciler
17461 };
17462
17463 var HooksDispatcherOnMountInDEV = null;
17464 var HooksDispatcherOnMountWithHookTypesInDEV = null;
17465 var HooksDispatcherOnUpdateInDEV = null;
17466 var HooksDispatcherOnRerenderInDEV = null;
17467 var InvalidNestedHooksDispatcherOnMountInDEV = null;
17468 var InvalidNestedHooksDispatcherOnUpdateInDEV = null;
17469 var InvalidNestedHooksDispatcherOnRerenderInDEV = null;
17470
17471 {
17472 var warnInvalidContextAccess = function () {
17473 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().');
17474 };
17475
17476 var warnInvalidHookAccess = function () {
17477 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');
17478 };
17479
17480 HooksDispatcherOnMountInDEV = {
17481 readContext: function (context) {
17482 return readContext(context);
17483 },
17484 useCallback: function (callback, deps) {
17485 currentHookNameInDev = 'useCallback';
17486 mountHookTypesDev();
17487 checkDepsAreArrayDev(deps);
17488 return mountCallback(callback, deps);
17489 },
17490 useContext: function (context) {
17491 currentHookNameInDev = 'useContext';
17492 mountHookTypesDev();
17493 return readContext(context);
17494 },
17495 useEffect: function (create, deps) {
17496 currentHookNameInDev = 'useEffect';
17497 mountHookTypesDev();
17498 checkDepsAreArrayDev(deps);
17499 return mountEffect(create, deps);
17500 },
17501 useImperativeHandle: function (ref, create, deps) {
17502 currentHookNameInDev = 'useImperativeHandle';
17503 mountHookTypesDev();
17504 checkDepsAreArrayDev(deps);
17505 return mountImperativeHandle(ref, create, deps);
17506 },
17507 useInsertionEffect: function (create, deps) {
17508 currentHookNameInDev = 'useInsertionEffect';
17509 mountHookTypesDev();
17510 checkDepsAreArrayDev(deps);
17511 return mountInsertionEffect(create, deps);
17512 },
17513 useLayoutEffect: function (create, deps) {
17514 currentHookNameInDev = 'useLayoutEffect';
17515 mountHookTypesDev();
17516 checkDepsAreArrayDev(deps);
17517 return mountLayoutEffect(create, deps);
17518 },
17519 useMemo: function (create, deps) {
17520 currentHookNameInDev = 'useMemo';
17521 mountHookTypesDev();
17522 checkDepsAreArrayDev(deps);
17523 var prevDispatcher = ReactCurrentDispatcher$1.current;
17524 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17525
17526 try {
17527 return mountMemo(create, deps);
17528 } finally {
17529 ReactCurrentDispatcher$1.current = prevDispatcher;
17530 }
17531 },
17532 useReducer: function (reducer, initialArg, init) {
17533 currentHookNameInDev = 'useReducer';
17534 mountHookTypesDev();
17535 var prevDispatcher = ReactCurrentDispatcher$1.current;
17536 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17537
17538 try {
17539 return mountReducer(reducer, initialArg, init);
17540 } finally {
17541 ReactCurrentDispatcher$1.current = prevDispatcher;
17542 }
17543 },
17544 useRef: function (initialValue) {
17545 currentHookNameInDev = 'useRef';
17546 mountHookTypesDev();
17547 return mountRef(initialValue);
17548 },
17549 useState: function (initialState) {
17550 currentHookNameInDev = 'useState';
17551 mountHookTypesDev();
17552 var prevDispatcher = ReactCurrentDispatcher$1.current;
17553 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17554
17555 try {
17556 return mountState(initialState);
17557 } finally {
17558 ReactCurrentDispatcher$1.current = prevDispatcher;
17559 }
17560 },
17561 useDebugValue: function (value, formatterFn) {
17562 currentHookNameInDev = 'useDebugValue';
17563 mountHookTypesDev();
17564 return mountDebugValue();
17565 },
17566 useDeferredValue: function (value) {
17567 currentHookNameInDev = 'useDeferredValue';
17568 mountHookTypesDev();
17569 return mountDeferredValue(value);
17570 },
17571 useTransition: function () {
17572 currentHookNameInDev = 'useTransition';
17573 mountHookTypesDev();
17574 return mountTransition();
17575 },
17576 useMutableSource: function (source, getSnapshot, subscribe) {
17577 currentHookNameInDev = 'useMutableSource';
17578 mountHookTypesDev();
17579 return mountMutableSource();
17580 },
17581 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17582 currentHookNameInDev = 'useSyncExternalStore';
17583 mountHookTypesDev();
17584 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
17585 },
17586 useId: function () {
17587 currentHookNameInDev = 'useId';
17588 mountHookTypesDev();
17589 return mountId();
17590 },
17591 unstable_isNewReconciler: enableNewReconciler
17592 };
17593
17594 HooksDispatcherOnMountWithHookTypesInDEV = {
17595 readContext: function (context) {
17596 return readContext(context);
17597 },
17598 useCallback: function (callback, deps) {
17599 currentHookNameInDev = 'useCallback';
17600 updateHookTypesDev();
17601 return mountCallback(callback, deps);
17602 },
17603 useContext: function (context) {
17604 currentHookNameInDev = 'useContext';
17605 updateHookTypesDev();
17606 return readContext(context);
17607 },
17608 useEffect: function (create, deps) {
17609 currentHookNameInDev = 'useEffect';
17610 updateHookTypesDev();
17611 return mountEffect(create, deps);
17612 },
17613 useImperativeHandle: function (ref, create, deps) {
17614 currentHookNameInDev = 'useImperativeHandle';
17615 updateHookTypesDev();
17616 return mountImperativeHandle(ref, create, deps);
17617 },
17618 useInsertionEffect: function (create, deps) {
17619 currentHookNameInDev = 'useInsertionEffect';
17620 updateHookTypesDev();
17621 return mountInsertionEffect(create, deps);
17622 },
17623 useLayoutEffect: function (create, deps) {
17624 currentHookNameInDev = 'useLayoutEffect';
17625 updateHookTypesDev();
17626 return mountLayoutEffect(create, deps);
17627 },
17628 useMemo: function (create, deps) {
17629 currentHookNameInDev = 'useMemo';
17630 updateHookTypesDev();
17631 var prevDispatcher = ReactCurrentDispatcher$1.current;
17632 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17633
17634 try {
17635 return mountMemo(create, deps);
17636 } finally {
17637 ReactCurrentDispatcher$1.current = prevDispatcher;
17638 }
17639 },
17640 useReducer: function (reducer, initialArg, init) {
17641 currentHookNameInDev = 'useReducer';
17642 updateHookTypesDev();
17643 var prevDispatcher = ReactCurrentDispatcher$1.current;
17644 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17645
17646 try {
17647 return mountReducer(reducer, initialArg, init);
17648 } finally {
17649 ReactCurrentDispatcher$1.current = prevDispatcher;
17650 }
17651 },
17652 useRef: function (initialValue) {
17653 currentHookNameInDev = 'useRef';
17654 updateHookTypesDev();
17655 return mountRef(initialValue);
17656 },
17657 useState: function (initialState) {
17658 currentHookNameInDev = 'useState';
17659 updateHookTypesDev();
17660 var prevDispatcher = ReactCurrentDispatcher$1.current;
17661 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17662
17663 try {
17664 return mountState(initialState);
17665 } finally {
17666 ReactCurrentDispatcher$1.current = prevDispatcher;
17667 }
17668 },
17669 useDebugValue: function (value, formatterFn) {
17670 currentHookNameInDev = 'useDebugValue';
17671 updateHookTypesDev();
17672 return mountDebugValue();
17673 },
17674 useDeferredValue: function (value) {
17675 currentHookNameInDev = 'useDeferredValue';
17676 updateHookTypesDev();
17677 return mountDeferredValue(value);
17678 },
17679 useTransition: function () {
17680 currentHookNameInDev = 'useTransition';
17681 updateHookTypesDev();
17682 return mountTransition();
17683 },
17684 useMutableSource: function (source, getSnapshot, subscribe) {
17685 currentHookNameInDev = 'useMutableSource';
17686 updateHookTypesDev();
17687 return mountMutableSource();
17688 },
17689 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17690 currentHookNameInDev = 'useSyncExternalStore';
17691 updateHookTypesDev();
17692 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
17693 },
17694 useId: function () {
17695 currentHookNameInDev = 'useId';
17696 updateHookTypesDev();
17697 return mountId();
17698 },
17699 unstable_isNewReconciler: enableNewReconciler
17700 };
17701
17702 HooksDispatcherOnUpdateInDEV = {
17703 readContext: function (context) {
17704 return readContext(context);
17705 },
17706 useCallback: function (callback, deps) {
17707 currentHookNameInDev = 'useCallback';
17708 updateHookTypesDev();
17709 return updateCallback(callback, deps);
17710 },
17711 useContext: function (context) {
17712 currentHookNameInDev = 'useContext';
17713 updateHookTypesDev();
17714 return readContext(context);
17715 },
17716 useEffect: function (create, deps) {
17717 currentHookNameInDev = 'useEffect';
17718 updateHookTypesDev();
17719 return updateEffect(create, deps);
17720 },
17721 useImperativeHandle: function (ref, create, deps) {
17722 currentHookNameInDev = 'useImperativeHandle';
17723 updateHookTypesDev();
17724 return updateImperativeHandle(ref, create, deps);
17725 },
17726 useInsertionEffect: function (create, deps) {
17727 currentHookNameInDev = 'useInsertionEffect';
17728 updateHookTypesDev();
17729 return updateInsertionEffect(create, deps);
17730 },
17731 useLayoutEffect: function (create, deps) {
17732 currentHookNameInDev = 'useLayoutEffect';
17733 updateHookTypesDev();
17734 return updateLayoutEffect(create, deps);
17735 },
17736 useMemo: function (create, deps) {
17737 currentHookNameInDev = 'useMemo';
17738 updateHookTypesDev();
17739 var prevDispatcher = ReactCurrentDispatcher$1.current;
17740 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17741
17742 try {
17743 return updateMemo(create, deps);
17744 } finally {
17745 ReactCurrentDispatcher$1.current = prevDispatcher;
17746 }
17747 },
17748 useReducer: function (reducer, initialArg, init) {
17749 currentHookNameInDev = 'useReducer';
17750 updateHookTypesDev();
17751 var prevDispatcher = ReactCurrentDispatcher$1.current;
17752 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17753
17754 try {
17755 return updateReducer(reducer, initialArg, init);
17756 } finally {
17757 ReactCurrentDispatcher$1.current = prevDispatcher;
17758 }
17759 },
17760 useRef: function (initialValue) {
17761 currentHookNameInDev = 'useRef';
17762 updateHookTypesDev();
17763 return updateRef();
17764 },
17765 useState: function (initialState) {
17766 currentHookNameInDev = 'useState';
17767 updateHookTypesDev();
17768 var prevDispatcher = ReactCurrentDispatcher$1.current;
17769 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
17770
17771 try {
17772 return updateState(initialState);
17773 } finally {
17774 ReactCurrentDispatcher$1.current = prevDispatcher;
17775 }
17776 },
17777 useDebugValue: function (value, formatterFn) {
17778 currentHookNameInDev = 'useDebugValue';
17779 updateHookTypesDev();
17780 return updateDebugValue();
17781 },
17782 useDeferredValue: function (value) {
17783 currentHookNameInDev = 'useDeferredValue';
17784 updateHookTypesDev();
17785 return updateDeferredValue(value);
17786 },
17787 useTransition: function () {
17788 currentHookNameInDev = 'useTransition';
17789 updateHookTypesDev();
17790 return updateTransition();
17791 },
17792 useMutableSource: function (source, getSnapshot, subscribe) {
17793 currentHookNameInDev = 'useMutableSource';
17794 updateHookTypesDev();
17795 return updateMutableSource();
17796 },
17797 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17798 currentHookNameInDev = 'useSyncExternalStore';
17799 updateHookTypesDev();
17800 return updateSyncExternalStore(subscribe, getSnapshot);
17801 },
17802 useId: function () {
17803 currentHookNameInDev = 'useId';
17804 updateHookTypesDev();
17805 return updateId();
17806 },
17807 unstable_isNewReconciler: enableNewReconciler
17808 };
17809
17810 HooksDispatcherOnRerenderInDEV = {
17811 readContext: function (context) {
17812 return readContext(context);
17813 },
17814 useCallback: function (callback, deps) {
17815 currentHookNameInDev = 'useCallback';
17816 updateHookTypesDev();
17817 return updateCallback(callback, deps);
17818 },
17819 useContext: function (context) {
17820 currentHookNameInDev = 'useContext';
17821 updateHookTypesDev();
17822 return readContext(context);
17823 },
17824 useEffect: function (create, deps) {
17825 currentHookNameInDev = 'useEffect';
17826 updateHookTypesDev();
17827 return updateEffect(create, deps);
17828 },
17829 useImperativeHandle: function (ref, create, deps) {
17830 currentHookNameInDev = 'useImperativeHandle';
17831 updateHookTypesDev();
17832 return updateImperativeHandle(ref, create, deps);
17833 },
17834 useInsertionEffect: function (create, deps) {
17835 currentHookNameInDev = 'useInsertionEffect';
17836 updateHookTypesDev();
17837 return updateInsertionEffect(create, deps);
17838 },
17839 useLayoutEffect: function (create, deps) {
17840 currentHookNameInDev = 'useLayoutEffect';
17841 updateHookTypesDev();
17842 return updateLayoutEffect(create, deps);
17843 },
17844 useMemo: function (create, deps) {
17845 currentHookNameInDev = 'useMemo';
17846 updateHookTypesDev();
17847 var prevDispatcher = ReactCurrentDispatcher$1.current;
17848 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
17849
17850 try {
17851 return updateMemo(create, deps);
17852 } finally {
17853 ReactCurrentDispatcher$1.current = prevDispatcher;
17854 }
17855 },
17856 useReducer: function (reducer, initialArg, init) {
17857 currentHookNameInDev = 'useReducer';
17858 updateHookTypesDev();
17859 var prevDispatcher = ReactCurrentDispatcher$1.current;
17860 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
17861
17862 try {
17863 return rerenderReducer(reducer, initialArg, init);
17864 } finally {
17865 ReactCurrentDispatcher$1.current = prevDispatcher;
17866 }
17867 },
17868 useRef: function (initialValue) {
17869 currentHookNameInDev = 'useRef';
17870 updateHookTypesDev();
17871 return updateRef();
17872 },
17873 useState: function (initialState) {
17874 currentHookNameInDev = 'useState';
17875 updateHookTypesDev();
17876 var prevDispatcher = ReactCurrentDispatcher$1.current;
17877 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnRerenderInDEV;
17878
17879 try {
17880 return rerenderState(initialState);
17881 } finally {
17882 ReactCurrentDispatcher$1.current = prevDispatcher;
17883 }
17884 },
17885 useDebugValue: function (value, formatterFn) {
17886 currentHookNameInDev = 'useDebugValue';
17887 updateHookTypesDev();
17888 return updateDebugValue();
17889 },
17890 useDeferredValue: function (value) {
17891 currentHookNameInDev = 'useDeferredValue';
17892 updateHookTypesDev();
17893 return rerenderDeferredValue(value);
17894 },
17895 useTransition: function () {
17896 currentHookNameInDev = 'useTransition';
17897 updateHookTypesDev();
17898 return rerenderTransition();
17899 },
17900 useMutableSource: function (source, getSnapshot, subscribe) {
17901 currentHookNameInDev = 'useMutableSource';
17902 updateHookTypesDev();
17903 return updateMutableSource();
17904 },
17905 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
17906 currentHookNameInDev = 'useSyncExternalStore';
17907 updateHookTypesDev();
17908 return updateSyncExternalStore(subscribe, getSnapshot);
17909 },
17910 useId: function () {
17911 currentHookNameInDev = 'useId';
17912 updateHookTypesDev();
17913 return updateId();
17914 },
17915 unstable_isNewReconciler: enableNewReconciler
17916 };
17917
17918 InvalidNestedHooksDispatcherOnMountInDEV = {
17919 readContext: function (context) {
17920 warnInvalidContextAccess();
17921 return readContext(context);
17922 },
17923 useCallback: function (callback, deps) {
17924 currentHookNameInDev = 'useCallback';
17925 warnInvalidHookAccess();
17926 mountHookTypesDev();
17927 return mountCallback(callback, deps);
17928 },
17929 useContext: function (context) {
17930 currentHookNameInDev = 'useContext';
17931 warnInvalidHookAccess();
17932 mountHookTypesDev();
17933 return readContext(context);
17934 },
17935 useEffect: function (create, deps) {
17936 currentHookNameInDev = 'useEffect';
17937 warnInvalidHookAccess();
17938 mountHookTypesDev();
17939 return mountEffect(create, deps);
17940 },
17941 useImperativeHandle: function (ref, create, deps) {
17942 currentHookNameInDev = 'useImperativeHandle';
17943 warnInvalidHookAccess();
17944 mountHookTypesDev();
17945 return mountImperativeHandle(ref, create, deps);
17946 },
17947 useInsertionEffect: function (create, deps) {
17948 currentHookNameInDev = 'useInsertionEffect';
17949 warnInvalidHookAccess();
17950 mountHookTypesDev();
17951 return mountInsertionEffect(create, deps);
17952 },
17953 useLayoutEffect: function (create, deps) {
17954 currentHookNameInDev = 'useLayoutEffect';
17955 warnInvalidHookAccess();
17956 mountHookTypesDev();
17957 return mountLayoutEffect(create, deps);
17958 },
17959 useMemo: function (create, deps) {
17960 currentHookNameInDev = 'useMemo';
17961 warnInvalidHookAccess();
17962 mountHookTypesDev();
17963 var prevDispatcher = ReactCurrentDispatcher$1.current;
17964 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17965
17966 try {
17967 return mountMemo(create, deps);
17968 } finally {
17969 ReactCurrentDispatcher$1.current = prevDispatcher;
17970 }
17971 },
17972 useReducer: function (reducer, initialArg, init) {
17973 currentHookNameInDev = 'useReducer';
17974 warnInvalidHookAccess();
17975 mountHookTypesDev();
17976 var prevDispatcher = ReactCurrentDispatcher$1.current;
17977 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17978
17979 try {
17980 return mountReducer(reducer, initialArg, init);
17981 } finally {
17982 ReactCurrentDispatcher$1.current = prevDispatcher;
17983 }
17984 },
17985 useRef: function (initialValue) {
17986 currentHookNameInDev = 'useRef';
17987 warnInvalidHookAccess();
17988 mountHookTypesDev();
17989 return mountRef(initialValue);
17990 },
17991 useState: function (initialState) {
17992 currentHookNameInDev = 'useState';
17993 warnInvalidHookAccess();
17994 mountHookTypesDev();
17995 var prevDispatcher = ReactCurrentDispatcher$1.current;
17996 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnMountInDEV;
17997
17998 try {
17999 return mountState(initialState);
18000 } finally {
18001 ReactCurrentDispatcher$1.current = prevDispatcher;
18002 }
18003 },
18004 useDebugValue: function (value, formatterFn) {
18005 currentHookNameInDev = 'useDebugValue';
18006 warnInvalidHookAccess();
18007 mountHookTypesDev();
18008 return mountDebugValue();
18009 },
18010 useDeferredValue: function (value) {
18011 currentHookNameInDev = 'useDeferredValue';
18012 warnInvalidHookAccess();
18013 mountHookTypesDev();
18014 return mountDeferredValue(value);
18015 },
18016 useTransition: function () {
18017 currentHookNameInDev = 'useTransition';
18018 warnInvalidHookAccess();
18019 mountHookTypesDev();
18020 return mountTransition();
18021 },
18022 useMutableSource: function (source, getSnapshot, subscribe) {
18023 currentHookNameInDev = 'useMutableSource';
18024 warnInvalidHookAccess();
18025 mountHookTypesDev();
18026 return mountMutableSource();
18027 },
18028 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
18029 currentHookNameInDev = 'useSyncExternalStore';
18030 warnInvalidHookAccess();
18031 mountHookTypesDev();
18032 return mountSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
18033 },
18034 useId: function () {
18035 currentHookNameInDev = 'useId';
18036 warnInvalidHookAccess();
18037 mountHookTypesDev();
18038 return mountId();
18039 },
18040 unstable_isNewReconciler: enableNewReconciler
18041 };
18042
18043 InvalidNestedHooksDispatcherOnUpdateInDEV = {
18044 readContext: function (context) {
18045 warnInvalidContextAccess();
18046 return readContext(context);
18047 },
18048 useCallback: function (callback, deps) {
18049 currentHookNameInDev = 'useCallback';
18050 warnInvalidHookAccess();
18051 updateHookTypesDev();
18052 return updateCallback(callback, deps);
18053 },
18054 useContext: function (context) {
18055 currentHookNameInDev = 'useContext';
18056 warnInvalidHookAccess();
18057 updateHookTypesDev();
18058 return readContext(context);
18059 },
18060 useEffect: function (create, deps) {
18061 currentHookNameInDev = 'useEffect';
18062 warnInvalidHookAccess();
18063 updateHookTypesDev();
18064 return updateEffect(create, deps);
18065 },
18066 useImperativeHandle: function (ref, create, deps) {
18067 currentHookNameInDev = 'useImperativeHandle';
18068 warnInvalidHookAccess();
18069 updateHookTypesDev();
18070 return updateImperativeHandle(ref, create, deps);
18071 },
18072 useInsertionEffect: function (create, deps) {
18073 currentHookNameInDev = 'useInsertionEffect';
18074 warnInvalidHookAccess();
18075 updateHookTypesDev();
18076 return updateInsertionEffect(create, deps);
18077 },
18078 useLayoutEffect: function (create, deps) {
18079 currentHookNameInDev = 'useLayoutEffect';
18080 warnInvalidHookAccess();
18081 updateHookTypesDev();
18082 return updateLayoutEffect(create, deps);
18083 },
18084 useMemo: function (create, deps) {
18085 currentHookNameInDev = 'useMemo';
18086 warnInvalidHookAccess();
18087 updateHookTypesDev();
18088 var prevDispatcher = ReactCurrentDispatcher$1.current;
18089 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18090
18091 try {
18092 return updateMemo(create, deps);
18093 } finally {
18094 ReactCurrentDispatcher$1.current = prevDispatcher;
18095 }
18096 },
18097 useReducer: function (reducer, initialArg, init) {
18098 currentHookNameInDev = 'useReducer';
18099 warnInvalidHookAccess();
18100 updateHookTypesDev();
18101 var prevDispatcher = ReactCurrentDispatcher$1.current;
18102 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18103
18104 try {
18105 return updateReducer(reducer, initialArg, init);
18106 } finally {
18107 ReactCurrentDispatcher$1.current = prevDispatcher;
18108 }
18109 },
18110 useRef: function (initialValue) {
18111 currentHookNameInDev = 'useRef';
18112 warnInvalidHookAccess();
18113 updateHookTypesDev();
18114 return updateRef();
18115 },
18116 useState: function (initialState) {
18117 currentHookNameInDev = 'useState';
18118 warnInvalidHookAccess();
18119 updateHookTypesDev();
18120 var prevDispatcher = ReactCurrentDispatcher$1.current;
18121 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18122
18123 try {
18124 return updateState(initialState);
18125 } finally {
18126 ReactCurrentDispatcher$1.current = prevDispatcher;
18127 }
18128 },
18129 useDebugValue: function (value, formatterFn) {
18130 currentHookNameInDev = 'useDebugValue';
18131 warnInvalidHookAccess();
18132 updateHookTypesDev();
18133 return updateDebugValue();
18134 },
18135 useDeferredValue: function (value) {
18136 currentHookNameInDev = 'useDeferredValue';
18137 warnInvalidHookAccess();
18138 updateHookTypesDev();
18139 return updateDeferredValue(value);
18140 },
18141 useTransition: function () {
18142 currentHookNameInDev = 'useTransition';
18143 warnInvalidHookAccess();
18144 updateHookTypesDev();
18145 return updateTransition();
18146 },
18147 useMutableSource: function (source, getSnapshot, subscribe) {
18148 currentHookNameInDev = 'useMutableSource';
18149 warnInvalidHookAccess();
18150 updateHookTypesDev();
18151 return updateMutableSource();
18152 },
18153 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
18154 currentHookNameInDev = 'useSyncExternalStore';
18155 warnInvalidHookAccess();
18156 updateHookTypesDev();
18157 return updateSyncExternalStore(subscribe, getSnapshot);
18158 },
18159 useId: function () {
18160 currentHookNameInDev = 'useId';
18161 warnInvalidHookAccess();
18162 updateHookTypesDev();
18163 return updateId();
18164 },
18165 unstable_isNewReconciler: enableNewReconciler
18166 };
18167
18168 InvalidNestedHooksDispatcherOnRerenderInDEV = {
18169 readContext: function (context) {
18170 warnInvalidContextAccess();
18171 return readContext(context);
18172 },
18173 useCallback: function (callback, deps) {
18174 currentHookNameInDev = 'useCallback';
18175 warnInvalidHookAccess();
18176 updateHookTypesDev();
18177 return updateCallback(callback, deps);
18178 },
18179 useContext: function (context) {
18180 currentHookNameInDev = 'useContext';
18181 warnInvalidHookAccess();
18182 updateHookTypesDev();
18183 return readContext(context);
18184 },
18185 useEffect: function (create, deps) {
18186 currentHookNameInDev = 'useEffect';
18187 warnInvalidHookAccess();
18188 updateHookTypesDev();
18189 return updateEffect(create, deps);
18190 },
18191 useImperativeHandle: function (ref, create, deps) {
18192 currentHookNameInDev = 'useImperativeHandle';
18193 warnInvalidHookAccess();
18194 updateHookTypesDev();
18195 return updateImperativeHandle(ref, create, deps);
18196 },
18197 useInsertionEffect: function (create, deps) {
18198 currentHookNameInDev = 'useInsertionEffect';
18199 warnInvalidHookAccess();
18200 updateHookTypesDev();
18201 return updateInsertionEffect(create, deps);
18202 },
18203 useLayoutEffect: function (create, deps) {
18204 currentHookNameInDev = 'useLayoutEffect';
18205 warnInvalidHookAccess();
18206 updateHookTypesDev();
18207 return updateLayoutEffect(create, deps);
18208 },
18209 useMemo: function (create, deps) {
18210 currentHookNameInDev = 'useMemo';
18211 warnInvalidHookAccess();
18212 updateHookTypesDev();
18213 var prevDispatcher = ReactCurrentDispatcher$1.current;
18214 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18215
18216 try {
18217 return updateMemo(create, deps);
18218 } finally {
18219 ReactCurrentDispatcher$1.current = prevDispatcher;
18220 }
18221 },
18222 useReducer: function (reducer, initialArg, init) {
18223 currentHookNameInDev = 'useReducer';
18224 warnInvalidHookAccess();
18225 updateHookTypesDev();
18226 var prevDispatcher = ReactCurrentDispatcher$1.current;
18227 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18228
18229 try {
18230 return rerenderReducer(reducer, initialArg, init);
18231 } finally {
18232 ReactCurrentDispatcher$1.current = prevDispatcher;
18233 }
18234 },
18235 useRef: function (initialValue) {
18236 currentHookNameInDev = 'useRef';
18237 warnInvalidHookAccess();
18238 updateHookTypesDev();
18239 return updateRef();
18240 },
18241 useState: function (initialState) {
18242 currentHookNameInDev = 'useState';
18243 warnInvalidHookAccess();
18244 updateHookTypesDev();
18245 var prevDispatcher = ReactCurrentDispatcher$1.current;
18246 ReactCurrentDispatcher$1.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
18247
18248 try {
18249 return rerenderState(initialState);
18250 } finally {
18251 ReactCurrentDispatcher$1.current = prevDispatcher;
18252 }
18253 },
18254 useDebugValue: function (value, formatterFn) {
18255 currentHookNameInDev = 'useDebugValue';
18256 warnInvalidHookAccess();
18257 updateHookTypesDev();
18258 return updateDebugValue();
18259 },
18260 useDeferredValue: function (value) {
18261 currentHookNameInDev = 'useDeferredValue';
18262 warnInvalidHookAccess();
18263 updateHookTypesDev();
18264 return rerenderDeferredValue(value);
18265 },
18266 useTransition: function () {
18267 currentHookNameInDev = 'useTransition';
18268 warnInvalidHookAccess();
18269 updateHookTypesDev();
18270 return rerenderTransition();
18271 },
18272 useMutableSource: function (source, getSnapshot, subscribe) {
18273 currentHookNameInDev = 'useMutableSource';
18274 warnInvalidHookAccess();
18275 updateHookTypesDev();
18276 return updateMutableSource();
18277 },
18278 useSyncExternalStore: function (subscribe, getSnapshot, getServerSnapshot) {
18279 currentHookNameInDev = 'useSyncExternalStore';
18280 warnInvalidHookAccess();
18281 updateHookTypesDev();
18282 return updateSyncExternalStore(subscribe, getSnapshot);
18283 },
18284 useId: function () {
18285 currentHookNameInDev = 'useId';
18286 warnInvalidHookAccess();
18287 updateHookTypesDev();
18288 return updateId();
18289 },
18290 unstable_isNewReconciler: enableNewReconciler
18291 };
18292 }
18293
18294 var now$1 = unstable_now;
18295 var commitTime = 0;
18296 var layoutEffectStartTime = -1;
18297 var profilerStartTime = -1;
18298 var passiveEffectStartTime = -1;
18299 /**
18300 * Tracks whether the current update was a nested/cascading update (scheduled from a layout effect).
18301 *
18302 * The overall sequence is:
18303 * 1. render
18304 * 2. commit (and call `onRender`, `onCommit`)
18305 * 3. check for nested updates
18306 * 4. flush passive effects (and call `onPostCommit`)
18307 *
18308 * Nested updates are identified in step 3 above,
18309 * but step 4 still applies to the work that was just committed.
18310 * We use two flags to track nested updates then:
18311 * one tracks whether the upcoming update is a nested update,
18312 * and the other tracks whether the current update was a nested update.
18313 * The first value gets synced to the second at the start of the render phase.
18314 */
18315
18316 var currentUpdateIsNested = false;
18317 var nestedUpdateScheduled = false;
18318
18319 function isCurrentUpdateNested() {
18320 return currentUpdateIsNested;
18321 }
18322
18323 function markNestedUpdateScheduled() {
18324 {
18325 nestedUpdateScheduled = true;
18326 }
18327 }
18328
18329 function resetNestedUpdateFlag() {
18330 {
18331 currentUpdateIsNested = false;
18332 nestedUpdateScheduled = false;
18333 }
18334 }
18335
18336 function syncNestedUpdateFlag() {
18337 {
18338 currentUpdateIsNested = nestedUpdateScheduled;
18339 nestedUpdateScheduled = false;
18340 }
18341 }
18342
18343 function getCommitTime() {
18344 return commitTime;
18345 }
18346
18347 function recordCommitTime() {
18348
18349 commitTime = now$1();
18350 }
18351
18352 function startProfilerTimer(fiber) {
18353
18354 profilerStartTime = now$1();
18355
18356 if (fiber.actualStartTime < 0) {
18357 fiber.actualStartTime = now$1();
18358 }
18359 }
18360
18361 function stopProfilerTimerIfRunning(fiber) {
18362
18363 profilerStartTime = -1;
18364 }
18365
18366 function stopProfilerTimerIfRunningAndRecordDelta(fiber, overrideBaseTime) {
18367
18368 if (profilerStartTime >= 0) {
18369 var elapsedTime = now$1() - profilerStartTime;
18370 fiber.actualDuration += elapsedTime;
18371
18372 if (overrideBaseTime) {
18373 fiber.selfBaseDuration = elapsedTime;
18374 }
18375
18376 profilerStartTime = -1;
18377 }
18378 }
18379
18380 function recordLayoutEffectDuration(fiber) {
18381
18382 if (layoutEffectStartTime >= 0) {
18383 var elapsedTime = now$1() - layoutEffectStartTime;
18384 layoutEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
18385 // Or the root (for the DevTools Profiler to read)
18386
18387 var parentFiber = fiber.return;
18388
18389 while (parentFiber !== null) {
18390 switch (parentFiber.tag) {
18391 case HostRoot:
18392 var root = parentFiber.stateNode;
18393 root.effectDuration += elapsedTime;
18394 return;
18395
18396 case Profiler:
18397 var parentStateNode = parentFiber.stateNode;
18398 parentStateNode.effectDuration += elapsedTime;
18399 return;
18400 }
18401
18402 parentFiber = parentFiber.return;
18403 }
18404 }
18405 }
18406
18407 function recordPassiveEffectDuration(fiber) {
18408
18409 if (passiveEffectStartTime >= 0) {
18410 var elapsedTime = now$1() - passiveEffectStartTime;
18411 passiveEffectStartTime = -1; // Store duration on the next nearest Profiler ancestor
18412 // Or the root (for the DevTools Profiler to read)
18413
18414 var parentFiber = fiber.return;
18415
18416 while (parentFiber !== null) {
18417 switch (parentFiber.tag) {
18418 case HostRoot:
18419 var root = parentFiber.stateNode;
18420
18421 if (root !== null) {
18422 root.passiveEffectDuration += elapsedTime;
18423 }
18424
18425 return;
18426
18427 case Profiler:
18428 var parentStateNode = parentFiber.stateNode;
18429
18430 if (parentStateNode !== null) {
18431 // Detached fibers have their state node cleared out.
18432 // In this case, the return pointer is also cleared out,
18433 // so we won't be able to report the time spent in this Profiler's subtree.
18434 parentStateNode.passiveEffectDuration += elapsedTime;
18435 }
18436
18437 return;
18438 }
18439
18440 parentFiber = parentFiber.return;
18441 }
18442 }
18443 }
18444
18445 function startLayoutEffectTimer() {
18446
18447 layoutEffectStartTime = now$1();
18448 }
18449
18450 function startPassiveEffectTimer() {
18451
18452 passiveEffectStartTime = now$1();
18453 }
18454
18455 function transferActualDuration(fiber) {
18456 // Transfer time spent rendering these children so we don't lose it
18457 // after we rerender. This is used as a helper in special cases
18458 // where we should count the work of multiple passes.
18459 var child = fiber.child;
18460
18461 while (child) {
18462 fiber.actualDuration += child.actualDuration;
18463 child = child.sibling;
18464 }
18465 }
18466
18467 function createCapturedValue(value, source) {
18468 // If the value is an error, call this function immediately after it is thrown
18469 // so the stack is accurate.
18470 return {
18471 value: value,
18472 source: source,
18473 stack: getStackByFiberInDevAndProd(source)
18474 };
18475 }
18476
18477 // This module is forked in different environments.
18478 // By default, return `true` to log errors to the console.
18479 // Forks can return `false` if this isn't desirable.
18480 function showErrorDialog(boundary, errorInfo) {
18481 return true;
18482 }
18483
18484 function logCapturedError(boundary, errorInfo) {
18485 try {
18486 var logError = showErrorDialog(boundary, errorInfo); // Allow injected showErrorDialog() to prevent default console.error logging.
18487 // This enables renderers like ReactNative to better manage redbox behavior.
18488
18489 if (logError === false) {
18490 return;
18491 }
18492
18493 var error = errorInfo.value;
18494
18495 if (true) {
18496 var source = errorInfo.source;
18497 var stack = errorInfo.stack;
18498 var componentStack = stack !== null ? stack : ''; // Browsers support silencing uncaught errors by calling
18499 // `preventDefault()` in window `error` handler.
18500 // We record this information as an expando on the error.
18501
18502 if (error != null && error._suppressLogging) {
18503 if (boundary.tag === ClassComponent) {
18504 // The error is recoverable and was silenced.
18505 // Ignore it and don't print the stack addendum.
18506 // This is handy for testing error boundaries without noise.
18507 return;
18508 } // The error is fatal. Since the silencing might have
18509 // been accidental, we'll surface it anyway.
18510 // However, the browser would have silenced the original error
18511 // so we'll print it first, and then print the stack addendum.
18512
18513
18514 console['error'](error); // Don't transform to our wrapper
18515 // For a more detailed description of this block, see:
18516 // https://github.com/facebook/react/pull/13384
18517 }
18518
18519 var componentName = source ? getComponentNameFromFiber(source) : null;
18520 var componentNameMessage = componentName ? "The above error occurred in the <" + componentName + "> component:" : 'The above error occurred in one of your React components:';
18521 var errorBoundaryMessage;
18522
18523 if (boundary.tag === HostRoot) {
18524 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.';
18525 } else {
18526 var errorBoundaryName = getComponentNameFromFiber(boundary) || 'Anonymous';
18527 errorBoundaryMessage = "React will try to recreate this component tree from scratch " + ("using the error boundary you provided, " + errorBoundaryName + ".");
18528 }
18529
18530 var combinedMessage = componentNameMessage + "\n" + componentStack + "\n\n" + ("" + errorBoundaryMessage); // In development, we provide our own message with just the component stack.
18531 // We don't include the original error message and JS stack because the browser
18532 // has already printed it. Even if the application swallows the error, it is still
18533 // displayed by the browser thanks to the DEV-only fake event trick in ReactErrorUtils.
18534
18535 console['error'](combinedMessage); // Don't transform to our wrapper
18536 } else {
18537 // In production, we print the error directly.
18538 // This will include the message, the JS stack, and anything the browser wants to show.
18539 // We pass the error object instead of custom message so that the browser displays the error natively.
18540 console['error'](error); // Don't transform to our wrapper
18541 }
18542 } catch (e) {
18543 // This method must not throw, or React internal state will get messed up.
18544 // If console.error is overridden, or logCapturedError() shows a dialog that throws,
18545 // we want to report this error outside of the normal stack as a last resort.
18546 // https://github.com/facebook/react/issues/13188
18547 setTimeout(function () {
18548 throw e;
18549 });
18550 }
18551 }
18552
18553 var PossiblyWeakMap$1 = typeof WeakMap === 'function' ? WeakMap : Map;
18554
18555 function createRootErrorUpdate(fiber, errorInfo, lane) {
18556 var update = createUpdate(NoTimestamp, lane); // Unmount the root by rendering null.
18557
18558 update.tag = CaptureUpdate; // Caution: React DevTools currently depends on this property
18559 // being called "element".
18560
18561 update.payload = {
18562 element: null
18563 };
18564 var error = errorInfo.value;
18565
18566 update.callback = function () {
18567 onUncaughtError(error);
18568 logCapturedError(fiber, errorInfo);
18569 };
18570
18571 return update;
18572 }
18573
18574 function createClassErrorUpdate(fiber, errorInfo, lane) {
18575 var update = createUpdate(NoTimestamp, lane);
18576 update.tag = CaptureUpdate;
18577 var getDerivedStateFromError = fiber.type.getDerivedStateFromError;
18578
18579 if (typeof getDerivedStateFromError === 'function') {
18580 var error$1 = errorInfo.value;
18581
18582 update.payload = function () {
18583 return getDerivedStateFromError(error$1);
18584 };
18585
18586 update.callback = function () {
18587 {
18588 markFailedErrorBoundaryForHotReloading(fiber);
18589 }
18590
18591 logCapturedError(fiber, errorInfo);
18592 };
18593 }
18594
18595 var inst = fiber.stateNode;
18596
18597 if (inst !== null && typeof inst.componentDidCatch === 'function') {
18598 update.callback = function callback() {
18599 {
18600 markFailedErrorBoundaryForHotReloading(fiber);
18601 }
18602
18603 logCapturedError(fiber, errorInfo);
18604
18605 if (typeof getDerivedStateFromError !== 'function') {
18606 // To preserve the preexisting retry behavior of error boundaries,
18607 // we keep track of which ones already failed during this batch.
18608 // This gets reset before we yield back to the browser.
18609 // TODO: Warn in strict mode if getDerivedStateFromError is
18610 // not defined.
18611 markLegacyErrorBoundaryAsFailed(this);
18612 }
18613
18614 var error$1 = errorInfo.value;
18615 var stack = errorInfo.stack;
18616 this.componentDidCatch(error$1, {
18617 componentStack: stack !== null ? stack : ''
18618 });
18619
18620 {
18621 if (typeof getDerivedStateFromError !== 'function') {
18622 // If componentDidCatch is the only error boundary method defined,
18623 // then it needs to call setState to recover from errors.
18624 // If no state update is scheduled then the boundary will swallow the error.
18625 if (!includesSomeLane(fiber.lanes, SyncLane)) {
18626 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');
18627 }
18628 }
18629 }
18630 };
18631 }
18632
18633 return update;
18634 }
18635
18636 function attachPingListener(root, wakeable, lanes) {
18637 // Attach a ping listener
18638 //
18639 // The data might resolve before we have a chance to commit the fallback. Or,
18640 // in the case of a refresh, we'll never commit a fallback. So we need to
18641 // attach a listener now. When it resolves ("pings"), we can decide whether to
18642 // try rendering the tree again.
18643 //
18644 // Only attach a listener if one does not already exist for the lanes
18645 // we're currently rendering (which acts like a "thread ID" here).
18646 //
18647 // We only need to do this in concurrent mode. Legacy Suspense always
18648 // commits fallbacks synchronously, so there are no pings.
18649 var pingCache = root.pingCache;
18650 var threadIDs;
18651
18652 if (pingCache === null) {
18653 pingCache = root.pingCache = new PossiblyWeakMap$1();
18654 threadIDs = new Set();
18655 pingCache.set(wakeable, threadIDs);
18656 } else {
18657 threadIDs = pingCache.get(wakeable);
18658
18659 if (threadIDs === undefined) {
18660 threadIDs = new Set();
18661 pingCache.set(wakeable, threadIDs);
18662 }
18663 }
18664
18665 if (!threadIDs.has(lanes)) {
18666 // Memoize using the thread ID to prevent redundant listeners.
18667 threadIDs.add(lanes);
18668 var ping = pingSuspendedRoot.bind(null, root, wakeable, lanes);
18669
18670 {
18671 if (isDevToolsPresent) {
18672 // If we have pending work still, restore the original updaters
18673 restorePendingUpdaters(root, lanes);
18674 }
18675 }
18676
18677 wakeable.then(ping, ping);
18678 }
18679 }
18680
18681 function attachRetryListener(suspenseBoundary, root, wakeable, lanes) {
18682 // Retry listener
18683 //
18684 // If the fallback does commit, we need to attach a different type of
18685 // listener. This one schedules an update on the Suspense boundary to turn
18686 // the fallback state off.
18687 //
18688 // Stash the wakeable on the boundary fiber so we can access it in the
18689 // commit phase.
18690 //
18691 // When the wakeable resolves, we'll attempt to render the boundary
18692 // again ("retry").
18693 var wakeables = suspenseBoundary.updateQueue;
18694
18695 if (wakeables === null) {
18696 var updateQueue = new Set();
18697 updateQueue.add(wakeable);
18698 suspenseBoundary.updateQueue = updateQueue;
18699 } else {
18700 wakeables.add(wakeable);
18701 }
18702 }
18703
18704 function resetSuspendedComponent(sourceFiber, rootRenderLanes) {
18705 // A legacy mode Suspense quirk, only relevant to hook components.
18706
18707
18708 var tag = sourceFiber.tag;
18709
18710 if ((sourceFiber.mode & ConcurrentMode) === NoMode && (tag === FunctionComponent || tag === ForwardRef || tag === SimpleMemoComponent)) {
18711 var currentSource = sourceFiber.alternate;
18712
18713 if (currentSource) {
18714 sourceFiber.updateQueue = currentSource.updateQueue;
18715 sourceFiber.memoizedState = currentSource.memoizedState;
18716 sourceFiber.lanes = currentSource.lanes;
18717 } else {
18718 sourceFiber.updateQueue = null;
18719 sourceFiber.memoizedState = null;
18720 }
18721 }
18722 }
18723
18724 function getNearestSuspenseBoundaryToCapture(returnFiber) {
18725 var node = returnFiber;
18726
18727 do {
18728 if (node.tag === SuspenseComponent && shouldCaptureSuspense(node)) {
18729 return node;
18730 } // This boundary already captured during this render. Continue to the next
18731 // boundary.
18732
18733
18734 node = node.return;
18735 } while (node !== null);
18736
18737 return null;
18738 }
18739
18740 function markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes) {
18741 // This marks a Suspense boundary so that when we're unwinding the stack,
18742 // it captures the suspended "exception" and does a second (fallback) pass.
18743 if ((suspenseBoundary.mode & ConcurrentMode) === NoMode) {
18744 // Legacy Mode Suspense
18745 //
18746 // If the boundary is in legacy mode, we should *not*
18747 // suspend the commit. Pretend as if the suspended component rendered
18748 // null and keep rendering. When the Suspense boundary completes,
18749 // we'll do a second pass to render the fallback.
18750 if (suspenseBoundary === returnFiber) {
18751 // Special case where we suspended while reconciling the children of
18752 // a Suspense boundary's inner Offscreen wrapper fiber. This happens
18753 // when a React.lazy component is a direct child of a
18754 // Suspense boundary.
18755 //
18756 // Suspense boundaries are implemented as multiple fibers, but they
18757 // are a single conceptual unit. The legacy mode behavior where we
18758 // pretend the suspended fiber committed as `null` won't work,
18759 // because in this case the "suspended" fiber is the inner
18760 // Offscreen wrapper.
18761 //
18762 // Because the contents of the boundary haven't started rendering
18763 // yet (i.e. nothing in the tree has partially rendered) we can
18764 // switch to the regular, concurrent mode behavior: mark the
18765 // boundary with ShouldCapture and enter the unwind phase.
18766 suspenseBoundary.flags |= ShouldCapture;
18767 } else {
18768 suspenseBoundary.flags |= DidCapture;
18769 sourceFiber.flags |= ForceUpdateForLegacySuspense; // We're going to commit this fiber even though it didn't complete.
18770 // But we shouldn't call any lifecycle methods or callbacks. Remove
18771 // all lifecycle effect tags.
18772
18773 sourceFiber.flags &= ~(LifecycleEffectMask | Incomplete);
18774
18775 if (sourceFiber.tag === ClassComponent) {
18776 var currentSourceFiber = sourceFiber.alternate;
18777
18778 if (currentSourceFiber === null) {
18779 // This is a new mount. Change the tag so it's not mistaken for a
18780 // completed class component. For example, we should not call
18781 // componentWillUnmount if it is deleted.
18782 sourceFiber.tag = IncompleteClassComponent;
18783 } else {
18784 // When we try rendering again, we should not reuse the current fiber,
18785 // since it's known to be in an inconsistent state. Use a force update to
18786 // prevent a bail out.
18787 var update = createUpdate(NoTimestamp, SyncLane);
18788 update.tag = ForceUpdate;
18789 enqueueUpdate(sourceFiber, update);
18790 }
18791 } // The source fiber did not complete. Mark it with Sync priority to
18792 // indicate that it still has pending work.
18793
18794
18795 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, SyncLane);
18796 }
18797
18798 return suspenseBoundary;
18799 } // Confirmed that the boundary is in a concurrent mode tree. Continue
18800 // with the normal suspend path.
18801 //
18802 // After this we'll use a set of heuristics to determine whether this
18803 // render pass will run to completion or restart or "suspend" the commit.
18804 // The actual logic for this is spread out in different places.
18805 //
18806 // This first principle is that if we're going to suspend when we complete
18807 // a root, then we should also restart if we get an update or ping that
18808 // might unsuspend it, and vice versa. The only reason to suspend is
18809 // because you think you might want to restart before committing. However,
18810 // it doesn't make sense to restart only while in the period we're suspended.
18811 //
18812 // Restarting too aggressively is also not good because it starves out any
18813 // intermediate loading state. So we use heuristics to determine when.
18814 // Suspense Heuristics
18815 //
18816 // If nothing threw a Promise or all the same fallbacks are already showing,
18817 // then don't suspend/restart.
18818 //
18819 // If this is an initial render of a new tree of Suspense boundaries and
18820 // those trigger a fallback, then don't suspend/restart. We want to ensure
18821 // that we can show the initial loading state as quickly as possible.
18822 //
18823 // If we hit a "Delayed" case, such as when we'd switch from content back into
18824 // a fallback, then we should always suspend/restart. Transitions apply
18825 // to this case. If none is defined, JND is used instead.
18826 //
18827 // If we're already showing a fallback and it gets "retried", allowing us to show
18828 // another level, but there's still an inner boundary that would show a fallback,
18829 // then we suspend/restart for 500ms since the last time we showed a fallback
18830 // anywhere in the tree. This effectively throttles progressive loading into a
18831 // consistent train of commits. This also gives us an opportunity to restart to
18832 // get to the completed state slightly earlier.
18833 //
18834 // If there's ambiguity due to batching it's resolved in preference of:
18835 // 1) "delayed", 2) "initial render", 3) "retry".
18836 //
18837 // We want to ensure that a "busy" state doesn't get force committed. We want to
18838 // ensure that new initial loading states can commit as soon as possible.
18839
18840
18841 suspenseBoundary.flags |= ShouldCapture; // TODO: I think we can remove this, since we now use `DidCapture` in
18842 // the begin phase to prevent an early bailout.
18843
18844 suspenseBoundary.lanes = rootRenderLanes;
18845 return suspenseBoundary;
18846 }
18847
18848 function throwException(root, returnFiber, sourceFiber, value, rootRenderLanes) {
18849 // The source fiber did not complete.
18850 sourceFiber.flags |= Incomplete;
18851
18852 {
18853 if (isDevToolsPresent) {
18854 // If we have pending work still, restore the original updaters
18855 restorePendingUpdaters(root, rootRenderLanes);
18856 }
18857 }
18858
18859 if (value !== null && typeof value === 'object' && typeof value.then === 'function') {
18860 // This is a wakeable. The component suspended.
18861 var wakeable = value;
18862 resetSuspendedComponent(sourceFiber);
18863
18864
18865 var suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber);
18866
18867 if (suspenseBoundary !== null) {
18868 suspenseBoundary.flags &= ~ForceClientRender;
18869 markSuspenseBoundaryShouldCapture(suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // We only attach ping listeners in concurrent mode. Legacy Suspense always
18870 // commits fallbacks synchronously, so there are no pings.
18871
18872 if (suspenseBoundary.mode & ConcurrentMode) {
18873 attachPingListener(root, wakeable, rootRenderLanes);
18874 }
18875
18876 attachRetryListener(suspenseBoundary, root, wakeable);
18877 return;
18878 } else {
18879 // No boundary was found. Unless this is a sync update, this is OK.
18880 // We can suspend and wait for more data to arrive.
18881 if (!includesSyncLane(rootRenderLanes)) {
18882 // This is not a sync update. Suspend. Since we're not activating a
18883 // Suspense boundary, this will unwind all the way to the root without
18884 // performing a second pass to render a fallback. (This is arguably how
18885 // refresh transitions should work, too, since we're not going to commit
18886 // the fallbacks anyway.)
18887 //
18888 // This case also applies to initial hydration.
18889 attachPingListener(root, wakeable, rootRenderLanes);
18890 renderDidSuspendDelayIfPossible();
18891 return;
18892 } // This is a sync/discrete update. We treat this case like an error
18893 // because discrete renders are expected to produce a complete tree
18894 // synchronously to maintain consistency with external state.
18895
18896
18897 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.
18898 // The error will be caught by the nearest suspense boundary.
18899
18900 value = uncaughtSuspenseError;
18901 }
18902 } else {
18903 // This is a regular error, not a Suspense wakeable.
18904 if (getIsHydrating() && sourceFiber.mode & ConcurrentMode) {
18905 markDidSuspendWhileHydratingDEV();
18906
18907 var _suspenseBoundary = getNearestSuspenseBoundaryToCapture(returnFiber); // If the error was thrown during hydration, we may be able to recover by
18908 // discarding the dehydrated content and switching to a client render.
18909 // Instead of surfacing the error, find the nearest Suspense boundary
18910 // and render it again without hydration.
18911
18912
18913 if (_suspenseBoundary !== null) {
18914 if ((_suspenseBoundary.flags & ShouldCapture) === NoFlags) {
18915 // Set a flag to indicate that we should try rendering the normal
18916 // children again, not the fallback.
18917 _suspenseBoundary.flags |= ForceClientRender;
18918 }
18919
18920 markSuspenseBoundaryShouldCapture(_suspenseBoundary, returnFiber, sourceFiber, root, rootRenderLanes); // Even though the user may not be affected by this error, we should
18921 // still log it so it can be fixed.
18922
18923 queueHydrationError(value);
18924 return;
18925 }
18926 }
18927 } // We didn't find a boundary that could handle this type of exception. Start
18928 // over and traverse parent path again, this time treating the exception
18929 // as an error.
18930
18931
18932 renderDidError(value);
18933 value = createCapturedValue(value, sourceFiber);
18934 var workInProgress = returnFiber;
18935
18936 do {
18937 switch (workInProgress.tag) {
18938 case HostRoot:
18939 {
18940 var _errorInfo = value;
18941 workInProgress.flags |= ShouldCapture;
18942 var lane = pickArbitraryLane(rootRenderLanes);
18943 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane);
18944 var update = createRootErrorUpdate(workInProgress, _errorInfo, lane);
18945 enqueueCapturedUpdate(workInProgress, update);
18946 return;
18947 }
18948
18949 case ClassComponent:
18950 // Capture and retry
18951 var errorInfo = value;
18952 var ctor = workInProgress.type;
18953 var instance = workInProgress.stateNode;
18954
18955 if ((workInProgress.flags & DidCapture) === NoFlags && (typeof ctor.getDerivedStateFromError === 'function' || instance !== null && typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance))) {
18956 workInProgress.flags |= ShouldCapture;
18957
18958 var _lane = pickArbitraryLane(rootRenderLanes);
18959
18960 workInProgress.lanes = mergeLanes(workInProgress.lanes, _lane); // Schedule the error boundary to re-render using updated state
18961
18962 var _update = createClassErrorUpdate(workInProgress, errorInfo, _lane);
18963
18964 enqueueCapturedUpdate(workInProgress, _update);
18965 return;
18966 }
18967
18968 break;
18969 }
18970
18971 workInProgress = workInProgress.return;
18972 } while (workInProgress !== null);
18973 }
18974
18975 function getSuspendedCache() {
18976 {
18977 return null;
18978 } // This function is called when a Suspense boundary suspends. It returns the
18979 }
18980
18981 function markUpdate(workInProgress) {
18982 // Tag the fiber with an update effect. This turns a Placement into
18983 // a PlacementAndUpdate.
18984 workInProgress.flags |= Update;
18985 }
18986
18987 function markRef(workInProgress) {
18988 workInProgress.flags |= Ref;
18989
18990 {
18991 workInProgress.flags |= RefStatic;
18992 }
18993 }
18994
18995 var appendAllChildren;
18996 var updateHostContainer;
18997 var updateHostComponent;
18998 var updateHostText;
18999
19000 {
19001 // Mutation mode
19002 appendAllChildren = function (parent, workInProgress, needsVisibilityToggle, isHidden) {
19003 // We only have the top Fiber that was created but we need recurse down its
19004 // children to find all the terminal nodes.
19005 var node = workInProgress.child;
19006
19007 while (node !== null) {
19008 if (node.tag === HostComponent || node.tag === HostText) {
19009 appendInitialChild(parent, node.stateNode);
19010 } else if (node.tag === HostPortal) ; else if (node.child !== null) {
19011 node.child.return = node;
19012 node = node.child;
19013 continue;
19014 }
19015
19016 if (node === workInProgress) {
19017 return;
19018 }
19019
19020 while (node.sibling === null) {
19021 if (node.return === null || node.return === workInProgress) {
19022 return;
19023 }
19024
19025 node = node.return;
19026 }
19027
19028 node.sibling.return = node.return;
19029 node = node.sibling;
19030 }
19031 };
19032
19033 updateHostContainer = function (current, workInProgress) {// Noop
19034 };
19035
19036 updateHostComponent = function (current, workInProgress, type, newProps, rootContainerInstance) {
19037 // If we have an alternate, that means this is an update and we need to
19038 // schedule a side-effect to do the updates.
19039 var oldProps = current.memoizedProps;
19040
19041 if (oldProps === newProps) {
19042 // In mutation mode, this is sufficient for a bailout because
19043 // we won't touch this node even if children changed.
19044 return;
19045 } // If we get updated because one of our children updated, we don't
19046 // have newProps so we'll have to reuse them.
19047 // TODO: Split the update API as separate for the props vs. children.
19048 // Even better would be if children weren't special cased at all tho.
19049
19050
19051 var instance = workInProgress.stateNode;
19052 var currentHostContext = getHostContext(); // TODO: Experiencing an error where oldProps is null. Suggests a host
19053 // component is hitting the resume path. Figure out why. Possibly
19054 // related to `hidden`.
19055
19056 var updatePayload = prepareUpdate(instance, type, oldProps, newProps, rootContainerInstance, currentHostContext); // TODO: Type this specific to this type of component.
19057
19058 workInProgress.updateQueue = updatePayload; // If the update payload indicates that there is a change or if there
19059 // is a new ref we mark this as an update. All the work is done in commitWork.
19060
19061 if (updatePayload) {
19062 markUpdate(workInProgress);
19063 }
19064 };
19065
19066 updateHostText = function (current, workInProgress, oldText, newText) {
19067 // If the text differs, mark it as an update. All the work in done in commitWork.
19068 if (oldText !== newText) {
19069 markUpdate(workInProgress);
19070 }
19071 };
19072 }
19073
19074 function cutOffTailIfNeeded(renderState, hasRenderedATailFallback) {
19075 if (getIsHydrating()) {
19076 // If we're hydrating, we should consume as many items as we can
19077 // so we don't leave any behind.
19078 return;
19079 }
19080
19081 switch (renderState.tailMode) {
19082 case 'hidden':
19083 {
19084 // Any insertions at the end of the tail list after this point
19085 // should be invisible. If there are already mounted boundaries
19086 // anything before them are not considered for collapsing.
19087 // Therefore we need to go through the whole tail to find if
19088 // there are any.
19089 var tailNode = renderState.tail;
19090 var lastTailNode = null;
19091
19092 while (tailNode !== null) {
19093 if (tailNode.alternate !== null) {
19094 lastTailNode = tailNode;
19095 }
19096
19097 tailNode = tailNode.sibling;
19098 } // Next we're simply going to delete all insertions after the
19099 // last rendered item.
19100
19101
19102 if (lastTailNode === null) {
19103 // All remaining items in the tail are insertions.
19104 renderState.tail = null;
19105 } else {
19106 // Detach the insertion after the last node that was already
19107 // inserted.
19108 lastTailNode.sibling = null;
19109 }
19110
19111 break;
19112 }
19113
19114 case 'collapsed':
19115 {
19116 // Any insertions at the end of the tail list after this point
19117 // should be invisible. If there are already mounted boundaries
19118 // anything before them are not considered for collapsing.
19119 // Therefore we need to go through the whole tail to find if
19120 // there are any.
19121 var _tailNode = renderState.tail;
19122 var _lastTailNode = null;
19123
19124 while (_tailNode !== null) {
19125 if (_tailNode.alternate !== null) {
19126 _lastTailNode = _tailNode;
19127 }
19128
19129 _tailNode = _tailNode.sibling;
19130 } // Next we're simply going to delete all insertions after the
19131 // last rendered item.
19132
19133
19134 if (_lastTailNode === null) {
19135 // All remaining items in the tail are insertions.
19136 if (!hasRenderedATailFallback && renderState.tail !== null) {
19137 // We suspended during the head. We want to show at least one
19138 // row at the tail. So we'll keep on and cut off the rest.
19139 renderState.tail.sibling = null;
19140 } else {
19141 renderState.tail = null;
19142 }
19143 } else {
19144 // Detach the insertion after the last node that was already
19145 // inserted.
19146 _lastTailNode.sibling = null;
19147 }
19148
19149 break;
19150 }
19151 }
19152 }
19153
19154 function bubbleProperties(completedWork) {
19155 var didBailout = completedWork.alternate !== null && completedWork.alternate.child === completedWork.child;
19156 var newChildLanes = NoLanes;
19157 var subtreeFlags = NoFlags;
19158
19159 if (!didBailout) {
19160 // Bubble up the earliest expiration time.
19161 if ( (completedWork.mode & ProfileMode) !== NoMode) {
19162 // In profiling mode, resetChildExpirationTime is also used to reset
19163 // profiler durations.
19164 var actualDuration = completedWork.actualDuration;
19165 var treeBaseDuration = completedWork.selfBaseDuration;
19166 var child = completedWork.child;
19167
19168 while (child !== null) {
19169 newChildLanes = mergeLanes(newChildLanes, mergeLanes(child.lanes, child.childLanes));
19170 subtreeFlags |= child.subtreeFlags;
19171 subtreeFlags |= child.flags; // When a fiber is cloned, its actualDuration is reset to 0. This value will
19172 // only be updated if work is done on the fiber (i.e. it doesn't bailout).
19173 // When work is done, it should bubble to the parent's actualDuration. If
19174 // the fiber has not been cloned though, (meaning no work was done), then
19175 // this value will reflect the amount of time spent working on a previous
19176 // render. In that case it should not bubble. We determine whether it was
19177 // cloned by comparing the child pointer.
19178
19179 actualDuration += child.actualDuration;
19180 treeBaseDuration += child.treeBaseDuration;
19181 child = child.sibling;
19182 }
19183
19184 completedWork.actualDuration = actualDuration;
19185 completedWork.treeBaseDuration = treeBaseDuration;
19186 } else {
19187 var _child = completedWork.child;
19188
19189 while (_child !== null) {
19190 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child.lanes, _child.childLanes));
19191 subtreeFlags |= _child.subtreeFlags;
19192 subtreeFlags |= _child.flags; // Update the return pointer so the tree is consistent. This is a code
19193 // smell because it assumes the commit phase is never concurrent with
19194 // the render phase. Will address during refactor to alternate model.
19195
19196 _child.return = completedWork;
19197 _child = _child.sibling;
19198 }
19199 }
19200
19201 completedWork.subtreeFlags |= subtreeFlags;
19202 } else {
19203 // Bubble up the earliest expiration time.
19204 if ( (completedWork.mode & ProfileMode) !== NoMode) {
19205 // In profiling mode, resetChildExpirationTime is also used to reset
19206 // profiler durations.
19207 var _treeBaseDuration = completedWork.selfBaseDuration;
19208 var _child2 = completedWork.child;
19209
19210 while (_child2 !== null) {
19211 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child2.lanes, _child2.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
19212 // so we should bubble those up even during a bailout. All the other
19213 // flags have a lifetime only of a single render + commit, so we should
19214 // ignore them.
19215
19216 subtreeFlags |= _child2.subtreeFlags & StaticMask;
19217 subtreeFlags |= _child2.flags & StaticMask;
19218 _treeBaseDuration += _child2.treeBaseDuration;
19219 _child2 = _child2.sibling;
19220 }
19221
19222 completedWork.treeBaseDuration = _treeBaseDuration;
19223 } else {
19224 var _child3 = completedWork.child;
19225
19226 while (_child3 !== null) {
19227 newChildLanes = mergeLanes(newChildLanes, mergeLanes(_child3.lanes, _child3.childLanes)); // "Static" flags share the lifetime of the fiber/hook they belong to,
19228 // so we should bubble those up even during a bailout. All the other
19229 // flags have a lifetime only of a single render + commit, so we should
19230 // ignore them.
19231
19232 subtreeFlags |= _child3.subtreeFlags & StaticMask;
19233 subtreeFlags |= _child3.flags & StaticMask; // Update the return pointer so the tree is consistent. This is a code
19234 // smell because it assumes the commit phase is never concurrent with
19235 // the render phase. Will address during refactor to alternate model.
19236
19237 _child3.return = completedWork;
19238 _child3 = _child3.sibling;
19239 }
19240 }
19241
19242 completedWork.subtreeFlags |= subtreeFlags;
19243 }
19244
19245 completedWork.childLanes = newChildLanes;
19246 return didBailout;
19247 }
19248
19249 function completeWork(current, workInProgress, renderLanes) {
19250 var newProps = workInProgress.pendingProps; // Note: This intentionally doesn't check if we're hydrating because comparing
19251 // to the current tree provider fiber is just as fast and less error-prone.
19252 // Ideally we would have a special version of the work loop only
19253 // for hydration.
19254
19255 popTreeContext(workInProgress);
19256
19257 switch (workInProgress.tag) {
19258 case IndeterminateComponent:
19259 case LazyComponent:
19260 case SimpleMemoComponent:
19261 case FunctionComponent:
19262 case ForwardRef:
19263 case Fragment:
19264 case Mode:
19265 case Profiler:
19266 case ContextConsumer:
19267 case MemoComponent:
19268 bubbleProperties(workInProgress);
19269 return null;
19270
19271 case ClassComponent:
19272 {
19273 var Component = workInProgress.type;
19274
19275 if (isContextProvider(Component)) {
19276 popContext(workInProgress);
19277 }
19278
19279 bubbleProperties(workInProgress);
19280 return null;
19281 }
19282
19283 case HostRoot:
19284 {
19285 var fiberRoot = workInProgress.stateNode;
19286
19287 popHostContainer(workInProgress);
19288 popTopLevelContextObject(workInProgress);
19289 resetWorkInProgressVersions();
19290
19291 if (fiberRoot.pendingContext) {
19292 fiberRoot.context = fiberRoot.pendingContext;
19293 fiberRoot.pendingContext = null;
19294 }
19295
19296 if (current === null || current.child === null) {
19297 // If we hydrated, pop so that we can delete any remaining children
19298 // that weren't hydrated.
19299 var wasHydrated = popHydrationState(workInProgress);
19300
19301 if (wasHydrated) {
19302 // If we hydrated, then we'll need to schedule an update for
19303 // the commit side-effects on the root.
19304 markUpdate(workInProgress);
19305 } else {
19306 if (current !== null) {
19307 var prevState = current.memoizedState;
19308
19309 if ( // Check if this is a client root
19310 !prevState.isDehydrated || // Check if we reverted to client rendering (e.g. due to an error)
19311 (workInProgress.flags & ForceClientRender) !== NoFlags) {
19312 // Schedule an effect to clear this container at the start of the
19313 // next commit. This handles the case of React rendering into a
19314 // container with previous children. It's also safe to do for
19315 // updates too, because current.child would only be null if the
19316 // previous render was null (so the container would already
19317 // be empty).
19318 workInProgress.flags |= Snapshot; // If this was a forced client render, there may have been
19319 // recoverable errors during first hydration attempt. If so, add
19320 // them to a queue so we can log them in the commit phase.
19321
19322 upgradeHydrationErrorsToRecoverable();
19323 }
19324 }
19325 }
19326 }
19327
19328 updateHostContainer(current, workInProgress);
19329 bubbleProperties(workInProgress);
19330 return null;
19331 }
19332
19333 case HostComponent:
19334 {
19335 popHostContext(workInProgress);
19336 var rootContainerInstance = getRootHostContainer();
19337 var type = workInProgress.type;
19338
19339 if (current !== null && workInProgress.stateNode != null) {
19340 updateHostComponent(current, workInProgress, type, newProps, rootContainerInstance);
19341
19342 if (current.ref !== workInProgress.ref) {
19343 markRef(workInProgress);
19344 }
19345 } else {
19346 if (!newProps) {
19347 if (workInProgress.stateNode === null) {
19348 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.');
19349 } // This can happen when we abort work.
19350
19351
19352 bubbleProperties(workInProgress);
19353 return null;
19354 }
19355
19356 var currentHostContext = getHostContext(); // TODO: Move createInstance to beginWork and keep it on a context
19357 // "stack" as the parent. Then append children as we go in beginWork
19358 // or completeWork depending on whether we want to add them top->down or
19359 // bottom->up. Top->down is faster in IE11.
19360
19361 var _wasHydrated = popHydrationState(workInProgress);
19362
19363 if (_wasHydrated) {
19364 // TODO: Move this and createInstance step into the beginPhase
19365 // to consolidate.
19366 if (prepareToHydrateHostInstance(workInProgress, rootContainerInstance, currentHostContext)) {
19367 // If changes to the hydrated node need to be applied at the
19368 // commit-phase we mark this as such.
19369 markUpdate(workInProgress);
19370 }
19371 } else {
19372 var instance = createInstance(type, newProps, rootContainerInstance, currentHostContext, workInProgress);
19373 appendAllChildren(instance, workInProgress, false, false);
19374 workInProgress.stateNode = instance; // Certain renderers require commit-time effects for initial mount.
19375 // (eg DOM renderer supports auto-focus for certain elements).
19376 // Make sure such renderers get scheduled for later work.
19377
19378 if (finalizeInitialChildren(instance, type, newProps, rootContainerInstance)) {
19379 markUpdate(workInProgress);
19380 }
19381 }
19382
19383 if (workInProgress.ref !== null) {
19384 // If there is a ref on a host node we need to schedule a callback
19385 markRef(workInProgress);
19386 }
19387 }
19388
19389 bubbleProperties(workInProgress);
19390 return null;
19391 }
19392
19393 case HostText:
19394 {
19395 var newText = newProps;
19396
19397 if (current && workInProgress.stateNode != null) {
19398 var oldText = current.memoizedProps; // If we have an alternate, that means this is an update and we need
19399 // to schedule a side-effect to do the updates.
19400
19401 updateHostText(current, workInProgress, oldText, newText);
19402 } else {
19403 if (typeof newText !== 'string') {
19404 if (workInProgress.stateNode === null) {
19405 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.');
19406 } // This can happen when we abort work.
19407
19408 }
19409
19410 var _rootContainerInstance = getRootHostContainer();
19411
19412 var _currentHostContext = getHostContext();
19413
19414 var _wasHydrated2 = popHydrationState(workInProgress);
19415
19416 if (_wasHydrated2) {
19417 if (prepareToHydrateHostTextInstance(workInProgress)) {
19418 markUpdate(workInProgress);
19419 }
19420 } else {
19421 workInProgress.stateNode = createTextInstance(newText, _rootContainerInstance, _currentHostContext, workInProgress);
19422 }
19423 }
19424
19425 bubbleProperties(workInProgress);
19426 return null;
19427 }
19428
19429 case SuspenseComponent:
19430 {
19431 popSuspenseContext(workInProgress);
19432 var nextState = workInProgress.memoizedState;
19433
19434 {
19435 if ( hasUnhydratedTailNodes() && (workInProgress.mode & ConcurrentMode) !== NoMode && (workInProgress.flags & DidCapture) === NoFlags) {
19436 warnIfUnhydratedTailNodes(workInProgress);
19437 resetHydrationState();
19438 workInProgress.flags |= ForceClientRender | Incomplete | ShouldCapture;
19439 return workInProgress;
19440 }
19441
19442 if (nextState !== null && nextState.dehydrated !== null) {
19443 // We might be inside a hydration state the first time we're picking up this
19444 // Suspense boundary, and also after we've reentered it for further hydration.
19445 var _wasHydrated3 = popHydrationState(workInProgress);
19446
19447 if (current === null) {
19448 if (!_wasHydrated3) {
19449 throw new Error('A dehydrated suspense component was completed without a hydrated node. ' + 'This is probably a bug in React.');
19450 }
19451
19452 prepareToHydrateHostSuspenseInstance(workInProgress);
19453 bubbleProperties(workInProgress);
19454
19455 {
19456 if ((workInProgress.mode & ProfileMode) !== NoMode) {
19457 var isTimedOutSuspense = nextState !== null;
19458
19459 if (isTimedOutSuspense) {
19460 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
19461 var primaryChildFragment = workInProgress.child;
19462
19463 if (primaryChildFragment !== null) {
19464 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
19465 workInProgress.treeBaseDuration -= primaryChildFragment.treeBaseDuration;
19466 }
19467 }
19468 }
19469 }
19470
19471 return null;
19472 } else {
19473 // We might have reentered this boundary to hydrate it. If so, we need to reset the hydration
19474 // state since we're now exiting out of it. popHydrationState doesn't do that for us.
19475 resetHydrationState();
19476
19477 if ((workInProgress.flags & DidCapture) === NoFlags) {
19478 // This boundary did not suspend so it's now hydrated and unsuspended.
19479 workInProgress.memoizedState = null;
19480 } // If nothing suspended, we need to schedule an effect to mark this boundary
19481 // as having hydrated so events know that they're free to be invoked.
19482 // It's also a signal to replay events and the suspense callback.
19483 // If something suspended, schedule an effect to attach retry listeners.
19484 // So we might as well always mark this.
19485
19486
19487 workInProgress.flags |= Update;
19488 bubbleProperties(workInProgress);
19489
19490 {
19491 if ((workInProgress.mode & ProfileMode) !== NoMode) {
19492 var _isTimedOutSuspense = nextState !== null;
19493
19494 if (_isTimedOutSuspense) {
19495 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
19496 var _primaryChildFragment = workInProgress.child;
19497
19498 if (_primaryChildFragment !== null) {
19499 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
19500 workInProgress.treeBaseDuration -= _primaryChildFragment.treeBaseDuration;
19501 }
19502 }
19503 }
19504 }
19505
19506 return null;
19507 }
19508 } // Successfully completed this tree. If this was a forced client render,
19509 // there may have been recoverable errors during first hydration
19510 // attempt. If so, add them to a queue so we can log them in the
19511 // commit phase.
19512
19513
19514 upgradeHydrationErrorsToRecoverable();
19515 }
19516
19517 if ((workInProgress.flags & DidCapture) !== NoFlags) {
19518 // Something suspended. Re-render with the fallback children.
19519 workInProgress.lanes = renderLanes; // Do not reset the effect list.
19520
19521 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
19522 transferActualDuration(workInProgress);
19523 } // Don't bubble properties in this case.
19524
19525
19526 return workInProgress;
19527 }
19528
19529 var nextDidTimeout = nextState !== null;
19530 var prevDidTimeout = false;
19531
19532 if (current === null) {
19533 popHydrationState(workInProgress);
19534 } else {
19535 var _prevState = current.memoizedState;
19536 prevDidTimeout = _prevState !== null;
19537 }
19538 // an effect to toggle the subtree's visibility. When we switch from
19539 // fallback -> primary, the inner Offscreen fiber schedules this effect
19540 // as part of its normal complete phase. But when we switch from
19541 // primary -> fallback, the inner Offscreen fiber does not have a complete
19542 // phase. So we need to schedule its effect here.
19543 //
19544 // We also use this flag to connect/disconnect the effects, but the same
19545 // logic applies: when re-connecting, the Offscreen fiber's complete
19546 // phase will handle scheduling the effect. It's only when the fallback
19547 // is active that we have to do anything special.
19548
19549
19550 if (nextDidTimeout && !prevDidTimeout) {
19551 var _offscreenFiber = workInProgress.child;
19552 _offscreenFiber.flags |= Visibility; // TODO: This will still suspend a synchronous tree if anything
19553 // in the concurrent tree already suspended during this render.
19554 // This is a known bug.
19555
19556 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
19557 // TODO: Move this back to throwException because this is too late
19558 // if this is a large tree which is common for initial loads. We
19559 // don't know if we should restart a render or not until we get
19560 // this marker, and this is too late.
19561 // If this render already had a ping or lower pri updates,
19562 // and this is the first time we know we're going to suspend we
19563 // should be able to immediately restart from within throwException.
19564 var hasInvisibleChildContext = current === null && (workInProgress.memoizedProps.unstable_avoidThisFallback !== true || !enableSuspenseAvoidThisFallback);
19565
19566 if (hasInvisibleChildContext || hasSuspenseContext(suspenseStackCursor.current, InvisibleParentSuspenseContext)) {
19567 // If this was in an invisible tree or a new render, then showing
19568 // this boundary is ok.
19569 renderDidSuspend();
19570 } else {
19571 // Otherwise, we're going to have to hide content so we should
19572 // suspend for longer if possible.
19573 renderDidSuspendDelayIfPossible();
19574 }
19575 }
19576 }
19577
19578 var wakeables = workInProgress.updateQueue;
19579
19580 if (wakeables !== null) {
19581 // Schedule an effect to attach a retry listener to the promise.
19582 // TODO: Move to passive phase
19583 workInProgress.flags |= Update;
19584 }
19585
19586 bubbleProperties(workInProgress);
19587
19588 {
19589 if ((workInProgress.mode & ProfileMode) !== NoMode) {
19590 if (nextDidTimeout) {
19591 // Don't count time spent in a timed out Suspense subtree as part of the base duration.
19592 var _primaryChildFragment2 = workInProgress.child;
19593
19594 if (_primaryChildFragment2 !== null) {
19595 // $FlowFixMe Flow doesn't support type casting in combination with the -= operator
19596 workInProgress.treeBaseDuration -= _primaryChildFragment2.treeBaseDuration;
19597 }
19598 }
19599 }
19600 }
19601
19602 return null;
19603 }
19604
19605 case HostPortal:
19606 popHostContainer(workInProgress);
19607 updateHostContainer(current, workInProgress);
19608
19609 if (current === null) {
19610 preparePortalMount(workInProgress.stateNode.containerInfo);
19611 }
19612
19613 bubbleProperties(workInProgress);
19614 return null;
19615
19616 case ContextProvider:
19617 // Pop provider fiber
19618 var context = workInProgress.type._context;
19619 popProvider(context, workInProgress);
19620 bubbleProperties(workInProgress);
19621 return null;
19622
19623 case IncompleteClassComponent:
19624 {
19625 // Same as class component case. I put it down here so that the tags are
19626 // sequential to ensure this switch is compiled to a jump table.
19627 var _Component = workInProgress.type;
19628
19629 if (isContextProvider(_Component)) {
19630 popContext(workInProgress);
19631 }
19632
19633 bubbleProperties(workInProgress);
19634 return null;
19635 }
19636
19637 case SuspenseListComponent:
19638 {
19639 popSuspenseContext(workInProgress);
19640 var renderState = workInProgress.memoizedState;
19641
19642 if (renderState === null) {
19643 // We're running in the default, "independent" mode.
19644 // We don't do anything in this mode.
19645 bubbleProperties(workInProgress);
19646 return null;
19647 }
19648
19649 var didSuspendAlready = (workInProgress.flags & DidCapture) !== NoFlags;
19650 var renderedTail = renderState.rendering;
19651
19652 if (renderedTail === null) {
19653 // We just rendered the head.
19654 if (!didSuspendAlready) {
19655 // This is the first pass. We need to figure out if anything is still
19656 // suspended in the rendered set.
19657 // If new content unsuspended, but there's still some content that
19658 // didn't. Then we need to do a second pass that forces everything
19659 // to keep showing their fallbacks.
19660 // We might be suspended if something in this render pass suspended, or
19661 // something in the previous committed pass suspended. Otherwise,
19662 // there's no chance so we can skip the expensive call to
19663 // findFirstSuspended.
19664 var cannotBeSuspended = renderHasNotSuspendedYet() && (current === null || (current.flags & DidCapture) === NoFlags);
19665
19666 if (!cannotBeSuspended) {
19667 var row = workInProgress.child;
19668
19669 while (row !== null) {
19670 var suspended = findFirstSuspended(row);
19671
19672 if (suspended !== null) {
19673 didSuspendAlready = true;
19674 workInProgress.flags |= DidCapture;
19675 cutOffTailIfNeeded(renderState, false); // If this is a newly suspended tree, it might not get committed as
19676 // part of the second pass. In that case nothing will subscribe to
19677 // its thenables. Instead, we'll transfer its thenables to the
19678 // SuspenseList so that it can retry if they resolve.
19679 // There might be multiple of these in the list but since we're
19680 // going to wait for all of them anyway, it doesn't really matter
19681 // which ones gets to ping. In theory we could get clever and keep
19682 // track of how many dependencies remain but it gets tricky because
19683 // in the meantime, we can add/remove/change items and dependencies.
19684 // We might bail out of the loop before finding any but that
19685 // doesn't matter since that means that the other boundaries that
19686 // we did find already has their listeners attached.
19687
19688 var newThenables = suspended.updateQueue;
19689
19690 if (newThenables !== null) {
19691 workInProgress.updateQueue = newThenables;
19692 workInProgress.flags |= Update;
19693 } // Rerender the whole list, but this time, we'll force fallbacks
19694 // to stay in place.
19695 // Reset the effect flags before doing the second pass since that's now invalid.
19696 // Reset the child fibers to their original state.
19697
19698
19699 workInProgress.subtreeFlags = NoFlags;
19700 resetChildFibers(workInProgress, renderLanes); // Set up the Suspense Context to force suspense and immediately
19701 // rerender the children.
19702
19703 pushSuspenseContext(workInProgress, setShallowSuspenseContext(suspenseStackCursor.current, ForceSuspenseFallback)); // Don't bubble properties in this case.
19704
19705 return workInProgress.child;
19706 }
19707
19708 row = row.sibling;
19709 }
19710 }
19711
19712 if (renderState.tail !== null && now() > getRenderTargetTime()) {
19713 // We have already passed our CPU deadline but we still have rows
19714 // left in the tail. We'll just give up further attempts to render
19715 // the main content and only render fallbacks.
19716 workInProgress.flags |= DidCapture;
19717 didSuspendAlready = true;
19718 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19719 // to get it started back up to attempt the next item. While in terms
19720 // of priority this work has the same priority as this current render,
19721 // it's not part of the same transition once the transition has
19722 // committed. If it's sync, we still want to yield so that it can be
19723 // painted. Conceptually, this is really the same as pinging.
19724 // We can use any RetryLane even if it's the one currently rendering
19725 // since we're leaving it behind on this node.
19726
19727 workInProgress.lanes = SomeRetryLane;
19728 }
19729 } else {
19730 cutOffTailIfNeeded(renderState, false);
19731 } // Next we're going to render the tail.
19732
19733 } else {
19734 // Append the rendered row to the child list.
19735 if (!didSuspendAlready) {
19736 var _suspended = findFirstSuspended(renderedTail);
19737
19738 if (_suspended !== null) {
19739 workInProgress.flags |= DidCapture;
19740 didSuspendAlready = true; // Ensure we transfer the update queue to the parent so that it doesn't
19741 // get lost if this row ends up dropped during a second pass.
19742
19743 var _newThenables = _suspended.updateQueue;
19744
19745 if (_newThenables !== null) {
19746 workInProgress.updateQueue = _newThenables;
19747 workInProgress.flags |= Update;
19748 }
19749
19750 cutOffTailIfNeeded(renderState, true); // This might have been modified.
19751
19752 if (renderState.tail === null && renderState.tailMode === 'hidden' && !renderedTail.alternate && !getIsHydrating() // We don't cut it if we're hydrating.
19753 ) {
19754 // We're done.
19755 bubbleProperties(workInProgress);
19756 return null;
19757 }
19758 } else if ( // The time it took to render last row is greater than the remaining
19759 // time we have to render. So rendering one more row would likely
19760 // exceed it.
19761 now() * 2 - renderState.renderingStartTime > getRenderTargetTime() && renderLanes !== OffscreenLane) {
19762 // We have now passed our CPU deadline and we'll just give up further
19763 // attempts to render the main content and only render fallbacks.
19764 // The assumption is that this is usually faster.
19765 workInProgress.flags |= DidCapture;
19766 didSuspendAlready = true;
19767 cutOffTailIfNeeded(renderState, false); // Since nothing actually suspended, there will nothing to ping this
19768 // to get it started back up to attempt the next item. While in terms
19769 // of priority this work has the same priority as this current render,
19770 // it's not part of the same transition once the transition has
19771 // committed. If it's sync, we still want to yield so that it can be
19772 // painted. Conceptually, this is really the same as pinging.
19773 // We can use any RetryLane even if it's the one currently rendering
19774 // since we're leaving it behind on this node.
19775
19776 workInProgress.lanes = SomeRetryLane;
19777 }
19778 }
19779
19780 if (renderState.isBackwards) {
19781 // The effect list of the backwards tail will have been added
19782 // to the end. This breaks the guarantee that life-cycles fire in
19783 // sibling order but that isn't a strong guarantee promised by React.
19784 // Especially since these might also just pop in during future commits.
19785 // Append to the beginning of the list.
19786 renderedTail.sibling = workInProgress.child;
19787 workInProgress.child = renderedTail;
19788 } else {
19789 var previousSibling = renderState.last;
19790
19791 if (previousSibling !== null) {
19792 previousSibling.sibling = renderedTail;
19793 } else {
19794 workInProgress.child = renderedTail;
19795 }
19796
19797 renderState.last = renderedTail;
19798 }
19799 }
19800
19801 if (renderState.tail !== null) {
19802 // We still have tail rows to render.
19803 // Pop a row.
19804 var next = renderState.tail;
19805 renderState.rendering = next;
19806 renderState.tail = next.sibling;
19807 renderState.renderingStartTime = now();
19808 next.sibling = null; // Restore the context.
19809 // TODO: We can probably just avoid popping it instead and only
19810 // setting it the first time we go from not suspended to suspended.
19811
19812 var suspenseContext = suspenseStackCursor.current;
19813
19814 if (didSuspendAlready) {
19815 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
19816 } else {
19817 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
19818 }
19819
19820 pushSuspenseContext(workInProgress, suspenseContext); // Do a pass over the next row.
19821 // Don't bubble properties in this case.
19822
19823 return next;
19824 }
19825
19826 bubbleProperties(workInProgress);
19827 return null;
19828 }
19829
19830 case ScopeComponent:
19831 {
19832
19833 break;
19834 }
19835
19836 case OffscreenComponent:
19837 case LegacyHiddenComponent:
19838 {
19839 popRenderLanes(workInProgress);
19840 var _nextState = workInProgress.memoizedState;
19841 var nextIsHidden = _nextState !== null;
19842
19843 if (current !== null) {
19844 var _prevState2 = current.memoizedState;
19845 var prevIsHidden = _prevState2 !== null;
19846
19847 if (prevIsHidden !== nextIsHidden && ( // LegacyHidden doesn't do any hiding — it only pre-renders.
19848 !enableLegacyHidden )) {
19849 workInProgress.flags |= Visibility;
19850 }
19851 }
19852
19853 if (!nextIsHidden || (workInProgress.mode & ConcurrentMode) === NoMode) {
19854 bubbleProperties(workInProgress);
19855 } else {
19856 // Don't bubble properties for hidden children unless we're rendering
19857 // at offscreen priority.
19858 if (includesSomeLane(subtreeRenderLanes, OffscreenLane)) {
19859 bubbleProperties(workInProgress);
19860
19861 {
19862 // Check if there was an insertion or update in the hidden subtree.
19863 // If so, we need to hide those nodes in the commit phase, so
19864 // schedule a visibility effect.
19865 if ( workInProgress.subtreeFlags & (Placement | Update)) {
19866 workInProgress.flags |= Visibility;
19867 }
19868 }
19869 }
19870 }
19871
19872 return null;
19873 }
19874
19875 case CacheComponent:
19876 {
19877
19878 return null;
19879 }
19880
19881 case TracingMarkerComponent:
19882 {
19883
19884 return null;
19885 }
19886 }
19887
19888 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
19889 }
19890
19891 var ReactCurrentOwner$1 = ReactSharedInternals.ReactCurrentOwner;
19892 var didReceiveUpdate = false;
19893 var didWarnAboutBadClass;
19894 var didWarnAboutModulePatternComponent;
19895 var didWarnAboutContextTypeOnFunctionComponent;
19896 var didWarnAboutGetDerivedStateOnFunctionComponent;
19897 var didWarnAboutFunctionRefs;
19898 var didWarnAboutReassigningProps;
19899 var didWarnAboutRevealOrder;
19900 var didWarnAboutTailOptions;
19901
19902 {
19903 didWarnAboutBadClass = {};
19904 didWarnAboutModulePatternComponent = {};
19905 didWarnAboutContextTypeOnFunctionComponent = {};
19906 didWarnAboutGetDerivedStateOnFunctionComponent = {};
19907 didWarnAboutFunctionRefs = {};
19908 didWarnAboutReassigningProps = false;
19909 didWarnAboutRevealOrder = {};
19910 didWarnAboutTailOptions = {};
19911 }
19912
19913 function reconcileChildren(current, workInProgress, nextChildren, renderLanes) {
19914 if (current === null) {
19915 // If this is a fresh new component that hasn't been rendered yet, we
19916 // won't update its child set by applying minimal side-effects. Instead,
19917 // we will add them all to the child before it gets rendered. That means
19918 // we can optimize this reconciliation pass by not tracking side-effects.
19919 workInProgress.child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
19920 } else {
19921 // If the current child is the same as the work in progress, it means that
19922 // we haven't yet started any work on these children. Therefore, we use
19923 // the clone algorithm to create a copy of all the current children.
19924 // If we had any progressed work already, that is invalid at this point so
19925 // let's throw it out.
19926 workInProgress.child = reconcileChildFibers(workInProgress, current.child, nextChildren, renderLanes);
19927 }
19928 }
19929
19930 function forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes) {
19931 // This function is fork of reconcileChildren. It's used in cases where we
19932 // want to reconcile without matching against the existing set. This has the
19933 // effect of all current children being unmounted; even if the type and key
19934 // are the same, the old child is unmounted and a new child is created.
19935 //
19936 // To do this, we're going to go through the reconcile algorithm twice. In
19937 // the first pass, we schedule a deletion for all the current children by
19938 // passing null.
19939 workInProgress.child = reconcileChildFibers(workInProgress, current.child, null, renderLanes); // In the second pass, we mount the new children. The trick here is that we
19940 // pass null in place of where we usually pass the current child set. This has
19941 // the effect of remounting all children regardless of whether their
19942 // identities match.
19943
19944 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
19945 }
19946
19947 function updateForwardRef(current, workInProgress, Component, nextProps, renderLanes) {
19948 // TODO: current can be non-null here even if the component
19949 // hasn't yet mounted. This happens after the first render suspends.
19950 // We'll need to figure out if this is fine or can cause issues.
19951 {
19952 if (workInProgress.type !== workInProgress.elementType) {
19953 // Lazy component props can't be validated in createElement
19954 // because they're only guaranteed to be resolved here.
19955 var innerPropTypes = Component.propTypes;
19956
19957 if (innerPropTypes) {
19958 checkPropTypes(innerPropTypes, nextProps, // Resolved props
19959 'prop', getComponentNameFromType(Component));
19960 }
19961 }
19962 }
19963
19964 var render = Component.render;
19965 var ref = workInProgress.ref; // The rest is a fork of updateFunctionComponent
19966
19967 var nextChildren;
19968 var hasId;
19969 prepareToReadContext(workInProgress, renderLanes);
19970
19971 {
19972 markComponentRenderStarted(workInProgress);
19973 }
19974
19975 {
19976 ReactCurrentOwner$1.current = workInProgress;
19977 setIsRendering(true);
19978 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
19979 hasId = checkDidRenderIdHook();
19980
19981 if ( workInProgress.mode & StrictLegacyMode) {
19982 setIsStrictModeForDevtools(true);
19983
19984 try {
19985 nextChildren = renderWithHooks(current, workInProgress, render, nextProps, ref, renderLanes);
19986 hasId = checkDidRenderIdHook();
19987 } finally {
19988 setIsStrictModeForDevtools(false);
19989 }
19990 }
19991
19992 setIsRendering(false);
19993 }
19994
19995 {
19996 markComponentRenderStopped();
19997 }
19998
19999 if (current !== null && !didReceiveUpdate) {
20000 bailoutHooks(current, workInProgress, renderLanes);
20001 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
20002 }
20003
20004 if (getIsHydrating() && hasId) {
20005 pushMaterializedTreeId(workInProgress);
20006 } // React DevTools reads this flag.
20007
20008
20009 workInProgress.flags |= PerformedWork;
20010 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20011 return workInProgress.child;
20012 }
20013
20014 function updateMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
20015 if (current === null) {
20016 var type = Component.type;
20017
20018 if (isSimpleFunctionComponent(type) && Component.compare === null && // SimpleMemoComponent codepath doesn't resolve outer props either.
20019 Component.defaultProps === undefined) {
20020 var resolvedType = type;
20021
20022 {
20023 resolvedType = resolveFunctionForHotReloading(type);
20024 } // If this is a plain function component without default props,
20025 // and with only the default shallow comparison, we upgrade it
20026 // to a SimpleMemoComponent to allow fast path updates.
20027
20028
20029 workInProgress.tag = SimpleMemoComponent;
20030 workInProgress.type = resolvedType;
20031
20032 {
20033 validateFunctionComponentInDev(workInProgress, type);
20034 }
20035
20036 return updateSimpleMemoComponent(current, workInProgress, resolvedType, nextProps, renderLanes);
20037 }
20038
20039 {
20040 var innerPropTypes = type.propTypes;
20041
20042 if (innerPropTypes) {
20043 // Inner memo component props aren't currently validated in createElement.
20044 // We could move it there, but we'd still need this for lazy code path.
20045 checkPropTypes(innerPropTypes, nextProps, // Resolved props
20046 'prop', getComponentNameFromType(type));
20047 }
20048 }
20049
20050 var child = createFiberFromTypeAndProps(Component.type, null, nextProps, workInProgress, workInProgress.mode, renderLanes);
20051 child.ref = workInProgress.ref;
20052 child.return = workInProgress;
20053 workInProgress.child = child;
20054 return child;
20055 }
20056
20057 {
20058 var _type = Component.type;
20059 var _innerPropTypes = _type.propTypes;
20060
20061 if (_innerPropTypes) {
20062 // Inner memo component props aren't currently validated in createElement.
20063 // We could move it there, but we'd still need this for lazy code path.
20064 checkPropTypes(_innerPropTypes, nextProps, // Resolved props
20065 'prop', getComponentNameFromType(_type));
20066 }
20067 }
20068
20069 var currentChild = current.child; // This is always exactly one child
20070
20071 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
20072
20073 if (!hasScheduledUpdateOrContext) {
20074 // This will be the props with resolved defaultProps,
20075 // unlike current.memoizedProps which will be the unresolved ones.
20076 var prevProps = currentChild.memoizedProps; // Default to shallow comparison
20077
20078 var compare = Component.compare;
20079 compare = compare !== null ? compare : shallowEqual;
20080
20081 if (compare(prevProps, nextProps) && current.ref === workInProgress.ref) {
20082 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
20083 }
20084 } // React DevTools reads this flag.
20085
20086
20087 workInProgress.flags |= PerformedWork;
20088 var newChild = createWorkInProgress(currentChild, nextProps);
20089 newChild.ref = workInProgress.ref;
20090 newChild.return = workInProgress;
20091 workInProgress.child = newChild;
20092 return newChild;
20093 }
20094
20095 function updateSimpleMemoComponent(current, workInProgress, Component, nextProps, renderLanes) {
20096 // TODO: current can be non-null here even if the component
20097 // hasn't yet mounted. This happens when the inner render suspends.
20098 // We'll need to figure out if this is fine or can cause issues.
20099 {
20100 if (workInProgress.type !== workInProgress.elementType) {
20101 // Lazy component props can't be validated in createElement
20102 // because they're only guaranteed to be resolved here.
20103 var outerMemoType = workInProgress.elementType;
20104
20105 if (outerMemoType.$$typeof === REACT_LAZY_TYPE) {
20106 // We warn when you define propTypes on lazy()
20107 // so let's just skip over it to find memo() outer wrapper.
20108 // Inner props for memo are validated later.
20109 var lazyComponent = outerMemoType;
20110 var payload = lazyComponent._payload;
20111 var init = lazyComponent._init;
20112
20113 try {
20114 outerMemoType = init(payload);
20115 } catch (x) {
20116 outerMemoType = null;
20117 } // Inner propTypes will be validated in the function component path.
20118
20119
20120 var outerPropTypes = outerMemoType && outerMemoType.propTypes;
20121
20122 if (outerPropTypes) {
20123 checkPropTypes(outerPropTypes, nextProps, // Resolved (SimpleMemoComponent has no defaultProps)
20124 'prop', getComponentNameFromType(outerMemoType));
20125 }
20126 }
20127 }
20128 }
20129
20130 if (current !== null) {
20131 var prevProps = current.memoizedProps;
20132
20133 if (shallowEqual(prevProps, nextProps) && current.ref === workInProgress.ref && ( // Prevent bailout if the implementation changed due to hot reload.
20134 workInProgress.type === current.type )) {
20135 didReceiveUpdate = false;
20136
20137 if (!checkScheduledUpdateOrContext(current, renderLanes)) {
20138 // The pending lanes were cleared at the beginning of beginWork. We're
20139 // about to bail out, but there might be other lanes that weren't
20140 // included in the current render. Usually, the priority level of the
20141 // remaining updates is accumulated during the evaluation of the
20142 // component (i.e. when processing the update queue). But since since
20143 // we're bailing out early *without* evaluating the component, we need
20144 // to account for it here, too. Reset to the value of the current fiber.
20145 // NOTE: This only applies to SimpleMemoComponent, not MemoComponent,
20146 // because a MemoComponent fiber does not have hooks or an update queue;
20147 // rather, it wraps around an inner component, which may or may not
20148 // contains hooks.
20149 // TODO: Move the reset at in beginWork out of the common path so that
20150 // this is no longer necessary.
20151 workInProgress.lanes = current.lanes;
20152 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
20153 } else if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
20154 // This is a special case that only exists for legacy mode.
20155 // See https://github.com/facebook/react/pull/19216.
20156 didReceiveUpdate = true;
20157 }
20158 }
20159 }
20160
20161 return updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes);
20162 }
20163
20164 function updateOffscreenComponent(current, workInProgress, renderLanes) {
20165 var nextProps = workInProgress.pendingProps;
20166 var nextChildren = nextProps.children;
20167 var prevState = current !== null ? current.memoizedState : null;
20168
20169 if (nextProps.mode === 'hidden' || enableLegacyHidden ) {
20170 // Rendering a hidden tree.
20171 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
20172 // In legacy sync mode, don't defer the subtree. Render it now.
20173 var nextState = {
20174 baseLanes: NoLanes,
20175 cachePool: null
20176 };
20177 workInProgress.memoizedState = nextState;
20178
20179 pushRenderLanes(workInProgress, renderLanes);
20180 } else if (!includesSomeLane(renderLanes, OffscreenLane)) {
20181 var spawnedCachePool = null; // We're hidden, and we're not rendering at Offscreen. We will bail out
20182 // and resume this tree later.
20183
20184 var nextBaseLanes;
20185
20186 if (prevState !== null) {
20187 var prevBaseLanes = prevState.baseLanes;
20188 nextBaseLanes = mergeLanes(prevBaseLanes, renderLanes);
20189 } else {
20190 nextBaseLanes = renderLanes;
20191 } // Schedule this fiber to re-render at offscreen priority. Then bailout.
20192
20193
20194 workInProgress.lanes = workInProgress.childLanes = laneToLanes(OffscreenLane);
20195 var _nextState = {
20196 baseLanes: nextBaseLanes,
20197 cachePool: spawnedCachePool
20198 };
20199 workInProgress.memoizedState = _nextState;
20200 workInProgress.updateQueue = null;
20201 // to avoid a push/pop misalignment.
20202
20203
20204 pushRenderLanes(workInProgress, nextBaseLanes);
20205
20206 return null;
20207 } else {
20208 // This is the second render. The surrounding visible content has already
20209 // committed. Now we resume rendering the hidden tree.
20210 // Rendering at offscreen, so we can clear the base lanes.
20211 var _nextState2 = {
20212 baseLanes: NoLanes,
20213 cachePool: null
20214 };
20215 workInProgress.memoizedState = _nextState2; // Push the lanes that were skipped when we bailed out.
20216
20217 var subtreeRenderLanes = prevState !== null ? prevState.baseLanes : renderLanes;
20218
20219 pushRenderLanes(workInProgress, subtreeRenderLanes);
20220 }
20221 } else {
20222 // Rendering a visible tree.
20223 var _subtreeRenderLanes;
20224
20225 if (prevState !== null) {
20226 // We're going from hidden -> visible.
20227 _subtreeRenderLanes = mergeLanes(prevState.baseLanes, renderLanes);
20228
20229
20230 workInProgress.memoizedState = null;
20231 } else {
20232 // We weren't previously hidden, and we still aren't, so there's nothing
20233 // special to do. Need to push to the stack regardless, though, to avoid
20234 // a push/pop misalignment.
20235 _subtreeRenderLanes = renderLanes;
20236 }
20237
20238 pushRenderLanes(workInProgress, _subtreeRenderLanes);
20239 }
20240
20241 {
20242 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20243 return workInProgress.child;
20244 }
20245 }
20246
20247 function updateFragment(current, workInProgress, renderLanes) {
20248 var nextChildren = workInProgress.pendingProps;
20249 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20250 return workInProgress.child;
20251 }
20252
20253 function updateMode(current, workInProgress, renderLanes) {
20254 var nextChildren = workInProgress.pendingProps.children;
20255 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20256 return workInProgress.child;
20257 }
20258
20259 function updateProfiler(current, workInProgress, renderLanes) {
20260 {
20261 workInProgress.flags |= Update;
20262
20263 {
20264 // Reset effect durations for the next eventual effect phase.
20265 // These are reset during render to allow the DevTools commit hook a chance to read them,
20266 var stateNode = workInProgress.stateNode;
20267 stateNode.effectDuration = 0;
20268 stateNode.passiveEffectDuration = 0;
20269 }
20270 }
20271
20272 var nextProps = workInProgress.pendingProps;
20273 var nextChildren = nextProps.children;
20274 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20275 return workInProgress.child;
20276 }
20277
20278 function markRef$1(current, workInProgress) {
20279 var ref = workInProgress.ref;
20280
20281 if (current === null && ref !== null || current !== null && current.ref !== ref) {
20282 // Schedule a Ref effect
20283 workInProgress.flags |= Ref;
20284
20285 {
20286 workInProgress.flags |= RefStatic;
20287 }
20288 }
20289 }
20290
20291 function updateFunctionComponent(current, workInProgress, Component, nextProps, renderLanes) {
20292 {
20293 if (workInProgress.type !== workInProgress.elementType) {
20294 // Lazy component props can't be validated in createElement
20295 // because they're only guaranteed to be resolved here.
20296 var innerPropTypes = Component.propTypes;
20297
20298 if (innerPropTypes) {
20299 checkPropTypes(innerPropTypes, nextProps, // Resolved props
20300 'prop', getComponentNameFromType(Component));
20301 }
20302 }
20303 }
20304
20305 var context;
20306
20307 {
20308 var unmaskedContext = getUnmaskedContext(workInProgress, Component, true);
20309 context = getMaskedContext(workInProgress, unmaskedContext);
20310 }
20311
20312 var nextChildren;
20313 var hasId;
20314 prepareToReadContext(workInProgress, renderLanes);
20315
20316 {
20317 markComponentRenderStarted(workInProgress);
20318 }
20319
20320 {
20321 ReactCurrentOwner$1.current = workInProgress;
20322 setIsRendering(true);
20323 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
20324 hasId = checkDidRenderIdHook();
20325
20326 if ( workInProgress.mode & StrictLegacyMode) {
20327 setIsStrictModeForDevtools(true);
20328
20329 try {
20330 nextChildren = renderWithHooks(current, workInProgress, Component, nextProps, context, renderLanes);
20331 hasId = checkDidRenderIdHook();
20332 } finally {
20333 setIsStrictModeForDevtools(false);
20334 }
20335 }
20336
20337 setIsRendering(false);
20338 }
20339
20340 {
20341 markComponentRenderStopped();
20342 }
20343
20344 if (current !== null && !didReceiveUpdate) {
20345 bailoutHooks(current, workInProgress, renderLanes);
20346 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
20347 }
20348
20349 if (getIsHydrating() && hasId) {
20350 pushMaterializedTreeId(workInProgress);
20351 } // React DevTools reads this flag.
20352
20353
20354 workInProgress.flags |= PerformedWork;
20355 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20356 return workInProgress.child;
20357 }
20358
20359 function updateClassComponent(current, workInProgress, Component, nextProps, renderLanes) {
20360 {
20361 // This is used by DevTools to force a boundary to error.
20362 switch (shouldError(workInProgress)) {
20363 case false:
20364 {
20365 var _instance = workInProgress.stateNode;
20366 var ctor = workInProgress.type; // TODO This way of resetting the error boundary state is a hack.
20367 // Is there a better way to do this?
20368
20369 var tempInstance = new ctor(workInProgress.memoizedProps, _instance.context);
20370 var state = tempInstance.state;
20371
20372 _instance.updater.enqueueSetState(_instance, state, null);
20373
20374 break;
20375 }
20376
20377 case true:
20378 {
20379 workInProgress.flags |= DidCapture;
20380 workInProgress.flags |= ShouldCapture; // eslint-disable-next-line react-internal/prod-error-codes
20381
20382 var error$1 = new Error('Simulated error coming from DevTools');
20383 var lane = pickArbitraryLane(renderLanes);
20384 workInProgress.lanes = mergeLanes(workInProgress.lanes, lane); // Schedule the error boundary to re-render using updated state
20385
20386 var update = createClassErrorUpdate(workInProgress, createCapturedValue(error$1, workInProgress), lane);
20387 enqueueCapturedUpdate(workInProgress, update);
20388 break;
20389 }
20390 }
20391
20392 if (workInProgress.type !== workInProgress.elementType) {
20393 // Lazy component props can't be validated in createElement
20394 // because they're only guaranteed to be resolved here.
20395 var innerPropTypes = Component.propTypes;
20396
20397 if (innerPropTypes) {
20398 checkPropTypes(innerPropTypes, nextProps, // Resolved props
20399 'prop', getComponentNameFromType(Component));
20400 }
20401 }
20402 } // Push context providers early to prevent context stack mismatches.
20403 // During mounting we don't know the child context yet as the instance doesn't exist.
20404 // We will invalidate the child context in finishClassComponent() right after rendering.
20405
20406
20407 var hasContext;
20408
20409 if (isContextProvider(Component)) {
20410 hasContext = true;
20411 pushContextProvider(workInProgress);
20412 } else {
20413 hasContext = false;
20414 }
20415
20416 prepareToReadContext(workInProgress, renderLanes);
20417 var instance = workInProgress.stateNode;
20418 var shouldUpdate;
20419
20420 if (instance === null) {
20421 if (current !== null) {
20422 // A class component without an instance only mounts if it suspended
20423 // inside a non-concurrent tree, in an inconsistent state. We want to
20424 // treat it like a new mount, even though an empty version of it already
20425 // committed. Disconnect the alternate pointers.
20426 current.alternate = null;
20427 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
20428
20429 workInProgress.flags |= Placement;
20430 } // In the initial pass we might need to construct the instance.
20431
20432
20433 constructClassInstance(workInProgress, Component, nextProps);
20434 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
20435 shouldUpdate = true;
20436 } else if (current === null) {
20437 // In a resume, we'll already have an instance we can reuse.
20438 shouldUpdate = resumeMountClassInstance(workInProgress, Component, nextProps, renderLanes);
20439 } else {
20440 shouldUpdate = updateClassInstance(current, workInProgress, Component, nextProps, renderLanes);
20441 }
20442
20443 var nextUnitOfWork = finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes);
20444
20445 {
20446 var inst = workInProgress.stateNode;
20447
20448 if (shouldUpdate && inst.props !== nextProps) {
20449 if (!didWarnAboutReassigningProps) {
20450 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');
20451 }
20452
20453 didWarnAboutReassigningProps = true;
20454 }
20455 }
20456
20457 return nextUnitOfWork;
20458 }
20459
20460 function finishClassComponent(current, workInProgress, Component, shouldUpdate, hasContext, renderLanes) {
20461 // Refs should update even if shouldComponentUpdate returns false
20462 markRef$1(current, workInProgress);
20463 var didCaptureError = (workInProgress.flags & DidCapture) !== NoFlags;
20464
20465 if (!shouldUpdate && !didCaptureError) {
20466 // Context providers should defer to sCU for rendering
20467 if (hasContext) {
20468 invalidateContextProvider(workInProgress, Component, false);
20469 }
20470
20471 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
20472 }
20473
20474 var instance = workInProgress.stateNode; // Rerender
20475
20476 ReactCurrentOwner$1.current = workInProgress;
20477 var nextChildren;
20478
20479 if (didCaptureError && typeof Component.getDerivedStateFromError !== 'function') {
20480 // If we captured an error, but getDerivedStateFromError is not defined,
20481 // unmount all the children. componentDidCatch will schedule an update to
20482 // re-render a fallback. This is temporary until we migrate everyone to
20483 // the new API.
20484 // TODO: Warn in a future release.
20485 nextChildren = null;
20486
20487 {
20488 stopProfilerTimerIfRunning();
20489 }
20490 } else {
20491 {
20492 markComponentRenderStarted(workInProgress);
20493 }
20494
20495 {
20496 setIsRendering(true);
20497 nextChildren = instance.render();
20498
20499 if ( workInProgress.mode & StrictLegacyMode) {
20500 setIsStrictModeForDevtools(true);
20501
20502 try {
20503 instance.render();
20504 } finally {
20505 setIsStrictModeForDevtools(false);
20506 }
20507 }
20508
20509 setIsRendering(false);
20510 }
20511
20512 {
20513 markComponentRenderStopped();
20514 }
20515 } // React DevTools reads this flag.
20516
20517
20518 workInProgress.flags |= PerformedWork;
20519
20520 if (current !== null && didCaptureError) {
20521 // If we're recovering from an error, reconcile without reusing any of
20522 // the existing children. Conceptually, the normal children and the children
20523 // that are shown on error are two different sets, so we shouldn't reuse
20524 // normal children even if their identities match.
20525 forceUnmountCurrentAndReconcile(current, workInProgress, nextChildren, renderLanes);
20526 } else {
20527 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20528 } // Memoize state using the values we just used to render.
20529 // TODO: Restructure so we never read values from the instance.
20530
20531
20532 workInProgress.memoizedState = instance.state; // The context might have changed so we need to recalculate it.
20533
20534 if (hasContext) {
20535 invalidateContextProvider(workInProgress, Component, true);
20536 }
20537
20538 return workInProgress.child;
20539 }
20540
20541 function pushHostRootContext(workInProgress) {
20542 var root = workInProgress.stateNode;
20543
20544 if (root.pendingContext) {
20545 pushTopLevelContextObject(workInProgress, root.pendingContext, root.pendingContext !== root.context);
20546 } else if (root.context) {
20547 // Should always be set
20548 pushTopLevelContextObject(workInProgress, root.context, false);
20549 }
20550
20551 pushHostContainer(workInProgress, root.containerInfo);
20552 }
20553
20554 function updateHostRoot(current, workInProgress, renderLanes) {
20555 pushHostRootContext(workInProgress);
20556
20557 if (current === null) {
20558 throw new Error('Should have a current fiber. This is a bug in React.');
20559 }
20560
20561 var nextProps = workInProgress.pendingProps;
20562 var prevState = workInProgress.memoizedState;
20563 var prevChildren = prevState.element;
20564 cloneUpdateQueue(current, workInProgress);
20565 processUpdateQueue(workInProgress, nextProps, null, renderLanes);
20566 var nextState = workInProgress.memoizedState;
20567 var root = workInProgress.stateNode;
20568 // being called "element".
20569
20570
20571 var nextChildren = nextState.element;
20572
20573 if ( prevState.isDehydrated) {
20574 // This is a hydration root whose shell has not yet hydrated. We should
20575 // attempt to hydrate.
20576 // Flip isDehydrated to false to indicate that when this render
20577 // finishes, the root will no longer be dehydrated.
20578 var overrideState = {
20579 element: nextChildren,
20580 isDehydrated: false,
20581 cache: nextState.cache,
20582 transitions: nextState.transitions
20583 };
20584 var updateQueue = workInProgress.updateQueue; // `baseState` can always be the last state because the root doesn't
20585 // have reducer functions so it doesn't need rebasing.
20586
20587 updateQueue.baseState = overrideState;
20588 workInProgress.memoizedState = overrideState;
20589
20590 if (workInProgress.flags & ForceClientRender) {
20591 // Something errored during a previous attempt to hydrate the shell, so we
20592 // forced a client render.
20593 var recoverableError = 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.');
20594 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError);
20595 } else if (nextChildren !== prevChildren) {
20596 var _recoverableError = new Error('This root received an early update, before anything was able ' + 'hydrate. Switched the entire root to client rendering.');
20597
20598 return mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, _recoverableError);
20599 } else {
20600 // The outermost shell has not hydrated yet. Start hydrating.
20601 enterHydrationState(workInProgress);
20602
20603 var child = mountChildFibers(workInProgress, null, nextChildren, renderLanes);
20604 workInProgress.child = child;
20605 var node = child;
20606
20607 while (node) {
20608 // Mark each child as hydrating. This is a fast path to know whether this
20609 // tree is part of a hydrating tree. This is used to determine if a child
20610 // node has fully mounted yet, and for scheduling event replaying.
20611 // Conceptually this is similar to Placement in that a new subtree is
20612 // inserted into the React tree here. It just happens to not need DOM
20613 // mutations because it already exists.
20614 node.flags = node.flags & ~Placement | Hydrating;
20615 node = node.sibling;
20616 }
20617 }
20618 } else {
20619 // Root is not dehydrated. Either this is a client-only root, or it
20620 // already hydrated.
20621 resetHydrationState();
20622
20623 if (nextChildren === prevChildren) {
20624 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
20625 }
20626
20627 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20628 }
20629
20630 return workInProgress.child;
20631 }
20632
20633 function mountHostRootWithoutHydrating(current, workInProgress, nextChildren, renderLanes, recoverableError) {
20634 // Revert to client rendering.
20635 resetHydrationState();
20636 queueHydrationError(recoverableError);
20637 workInProgress.flags |= ForceClientRender;
20638 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20639 return workInProgress.child;
20640 }
20641
20642 function updateHostComponent$1(current, workInProgress, renderLanes) {
20643 pushHostContext(workInProgress);
20644
20645 if (current === null) {
20646 tryToClaimNextHydratableInstance(workInProgress);
20647 }
20648
20649 var type = workInProgress.type;
20650 var nextProps = workInProgress.pendingProps;
20651 var prevProps = current !== null ? current.memoizedProps : null;
20652 var nextChildren = nextProps.children;
20653 var isDirectTextChild = shouldSetTextContent(type, nextProps);
20654
20655 if (isDirectTextChild) {
20656 // We special case a direct text child of a host node. This is a common
20657 // case. We won't handle it as a reified child. We will instead handle
20658 // this in the host environment that also has access to this prop. That
20659 // avoids allocating another HostText fiber and traversing it.
20660 nextChildren = null;
20661 } else if (prevProps !== null && shouldSetTextContent(type, prevProps)) {
20662 // If we're switching from a direct text child to a normal child, or to
20663 // empty, we need to schedule the text content to be reset.
20664 workInProgress.flags |= ContentReset;
20665 }
20666
20667 markRef$1(current, workInProgress);
20668 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
20669 return workInProgress.child;
20670 }
20671
20672 function updateHostText$1(current, workInProgress) {
20673 if (current === null) {
20674 tryToClaimNextHydratableInstance(workInProgress);
20675 } // Nothing to do here. This is terminal. We'll do the completion step
20676 // immediately after.
20677
20678
20679 return null;
20680 }
20681
20682 function mountLazyComponent(_current, workInProgress, elementType, renderLanes) {
20683 if (_current !== null) {
20684 // A lazy component only mounts if it suspended inside a non-
20685 // concurrent tree, in an inconsistent state. We want to treat it like
20686 // a new mount, even though an empty version of it already committed.
20687 // Disconnect the alternate pointers.
20688 _current.alternate = null;
20689 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
20690
20691 workInProgress.flags |= Placement;
20692 }
20693
20694 var props = workInProgress.pendingProps;
20695 var lazyComponent = elementType;
20696 var payload = lazyComponent._payload;
20697 var init = lazyComponent._init;
20698 var Component = init(payload); // Store the unwrapped component in the type.
20699
20700 workInProgress.type = Component;
20701 var resolvedTag = workInProgress.tag = resolveLazyComponentTag(Component);
20702 var resolvedProps = resolveDefaultProps(Component, props);
20703 var child;
20704
20705 switch (resolvedTag) {
20706 case FunctionComponent:
20707 {
20708 {
20709 validateFunctionComponentInDev(workInProgress, Component);
20710 workInProgress.type = Component = resolveFunctionForHotReloading(Component);
20711 }
20712
20713 child = updateFunctionComponent(null, workInProgress, Component, resolvedProps, renderLanes);
20714 return child;
20715 }
20716
20717 case ClassComponent:
20718 {
20719 {
20720 workInProgress.type = Component = resolveClassForHotReloading(Component);
20721 }
20722
20723 child = updateClassComponent(null, workInProgress, Component, resolvedProps, renderLanes);
20724 return child;
20725 }
20726
20727 case ForwardRef:
20728 {
20729 {
20730 workInProgress.type = Component = resolveForwardRefForHotReloading(Component);
20731 }
20732
20733 child = updateForwardRef(null, workInProgress, Component, resolvedProps, renderLanes);
20734 return child;
20735 }
20736
20737 case MemoComponent:
20738 {
20739 {
20740 if (workInProgress.type !== workInProgress.elementType) {
20741 var outerPropTypes = Component.propTypes;
20742
20743 if (outerPropTypes) {
20744 checkPropTypes(outerPropTypes, resolvedProps, // Resolved for outer only
20745 'prop', getComponentNameFromType(Component));
20746 }
20747 }
20748 }
20749
20750 child = updateMemoComponent(null, workInProgress, Component, resolveDefaultProps(Component.type, resolvedProps), // The inner type can have defaults too
20751 renderLanes);
20752 return child;
20753 }
20754 }
20755
20756 var hint = '';
20757
20758 {
20759 if (Component !== null && typeof Component === 'object' && Component.$$typeof === REACT_LAZY_TYPE) {
20760 hint = ' Did you wrap a component in React.lazy() more than once?';
20761 }
20762 } // This message intentionally doesn't mention ForwardRef or MemoComponent
20763 // because the fact that it's a separate type of work is an
20764 // implementation detail.
20765
20766
20767 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));
20768 }
20769
20770 function mountIncompleteClassComponent(_current, workInProgress, Component, nextProps, renderLanes) {
20771 if (_current !== null) {
20772 // An incomplete component only mounts if it suspended inside a non-
20773 // concurrent tree, in an inconsistent state. We want to treat it like
20774 // a new mount, even though an empty version of it already committed.
20775 // Disconnect the alternate pointers.
20776 _current.alternate = null;
20777 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
20778
20779 workInProgress.flags |= Placement;
20780 } // Promote the fiber to a class and try rendering again.
20781
20782
20783 workInProgress.tag = ClassComponent; // The rest of this function is a fork of `updateClassComponent`
20784 // Push context providers early to prevent context stack mismatches.
20785 // During mounting we don't know the child context yet as the instance doesn't exist.
20786 // We will invalidate the child context in finishClassComponent() right after rendering.
20787
20788 var hasContext;
20789
20790 if (isContextProvider(Component)) {
20791 hasContext = true;
20792 pushContextProvider(workInProgress);
20793 } else {
20794 hasContext = false;
20795 }
20796
20797 prepareToReadContext(workInProgress, renderLanes);
20798 constructClassInstance(workInProgress, Component, nextProps);
20799 mountClassInstance(workInProgress, Component, nextProps, renderLanes);
20800 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
20801 }
20802
20803 function mountIndeterminateComponent(_current, workInProgress, Component, renderLanes) {
20804 if (_current !== null) {
20805 // An indeterminate component only mounts if it suspended inside a non-
20806 // concurrent tree, in an inconsistent state. We want to treat it like
20807 // a new mount, even though an empty version of it already committed.
20808 // Disconnect the alternate pointers.
20809 _current.alternate = null;
20810 workInProgress.alternate = null; // Since this is conceptually a new fiber, schedule a Placement effect
20811
20812 workInProgress.flags |= Placement;
20813 }
20814
20815 var props = workInProgress.pendingProps;
20816 var context;
20817
20818 {
20819 var unmaskedContext = getUnmaskedContext(workInProgress, Component, false);
20820 context = getMaskedContext(workInProgress, unmaskedContext);
20821 }
20822
20823 prepareToReadContext(workInProgress, renderLanes);
20824 var value;
20825 var hasId;
20826
20827 {
20828 markComponentRenderStarted(workInProgress);
20829 }
20830
20831 {
20832 if (Component.prototype && typeof Component.prototype.render === 'function') {
20833 var componentName = getComponentNameFromType(Component) || 'Unknown';
20834
20835 if (!didWarnAboutBadClass[componentName]) {
20836 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);
20837
20838 didWarnAboutBadClass[componentName] = true;
20839 }
20840 }
20841
20842 if (workInProgress.mode & StrictLegacyMode) {
20843 ReactStrictModeWarnings.recordLegacyContextWarning(workInProgress, null);
20844 }
20845
20846 setIsRendering(true);
20847 ReactCurrentOwner$1.current = workInProgress;
20848 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
20849 hasId = checkDidRenderIdHook();
20850 setIsRendering(false);
20851 }
20852
20853 {
20854 markComponentRenderStopped();
20855 } // React DevTools reads this flag.
20856
20857
20858 workInProgress.flags |= PerformedWork;
20859
20860 {
20861 // Support for module components is deprecated and is removed behind a flag.
20862 // Whether or not it would crash later, we want to show a good message in DEV first.
20863 if (typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
20864 var _componentName = getComponentNameFromType(Component) || 'Unknown';
20865
20866 if (!didWarnAboutModulePatternComponent[_componentName]) {
20867 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);
20868
20869 didWarnAboutModulePatternComponent[_componentName] = true;
20870 }
20871 }
20872 }
20873
20874 if ( // Run these checks in production only if the flag is off.
20875 // Eventually we'll delete this branch altogether.
20876 typeof value === 'object' && value !== null && typeof value.render === 'function' && value.$$typeof === undefined) {
20877 {
20878 var _componentName2 = getComponentNameFromType(Component) || 'Unknown';
20879
20880 if (!didWarnAboutModulePatternComponent[_componentName2]) {
20881 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);
20882
20883 didWarnAboutModulePatternComponent[_componentName2] = true;
20884 }
20885 } // Proceed under the assumption that this is a class instance
20886
20887
20888 workInProgress.tag = ClassComponent; // Throw out any hooks that were used.
20889
20890 workInProgress.memoizedState = null;
20891 workInProgress.updateQueue = null; // Push context providers early to prevent context stack mismatches.
20892 // During mounting we don't know the child context yet as the instance doesn't exist.
20893 // We will invalidate the child context in finishClassComponent() right after rendering.
20894
20895 var hasContext = false;
20896
20897 if (isContextProvider(Component)) {
20898 hasContext = true;
20899 pushContextProvider(workInProgress);
20900 } else {
20901 hasContext = false;
20902 }
20903
20904 workInProgress.memoizedState = value.state !== null && value.state !== undefined ? value.state : null;
20905 initializeUpdateQueue(workInProgress);
20906 adoptClassInstance(workInProgress, value);
20907 mountClassInstance(workInProgress, Component, props, renderLanes);
20908 return finishClassComponent(null, workInProgress, Component, true, hasContext, renderLanes);
20909 } else {
20910 // Proceed under the assumption that this is a function component
20911 workInProgress.tag = FunctionComponent;
20912
20913 {
20914
20915 if ( workInProgress.mode & StrictLegacyMode) {
20916 setIsStrictModeForDevtools(true);
20917
20918 try {
20919 value = renderWithHooks(null, workInProgress, Component, props, context, renderLanes);
20920 hasId = checkDidRenderIdHook();
20921 } finally {
20922 setIsStrictModeForDevtools(false);
20923 }
20924 }
20925 }
20926
20927 if (getIsHydrating() && hasId) {
20928 pushMaterializedTreeId(workInProgress);
20929 }
20930
20931 reconcileChildren(null, workInProgress, value, renderLanes);
20932
20933 {
20934 validateFunctionComponentInDev(workInProgress, Component);
20935 }
20936
20937 return workInProgress.child;
20938 }
20939 }
20940
20941 function validateFunctionComponentInDev(workInProgress, Component) {
20942 {
20943 if (Component) {
20944 if (Component.childContextTypes) {
20945 error('%s(...): childContextTypes cannot be defined on a function component.', Component.displayName || Component.name || 'Component');
20946 }
20947 }
20948
20949 if (workInProgress.ref !== null) {
20950 var info = '';
20951 var ownerName = getCurrentFiberOwnerNameInDevOrNull();
20952
20953 if (ownerName) {
20954 info += '\n\nCheck the render method of `' + ownerName + '`.';
20955 }
20956
20957 var warningKey = ownerName || '';
20958 var debugSource = workInProgress._debugSource;
20959
20960 if (debugSource) {
20961 warningKey = debugSource.fileName + ':' + debugSource.lineNumber;
20962 }
20963
20964 if (!didWarnAboutFunctionRefs[warningKey]) {
20965 didWarnAboutFunctionRefs[warningKey] = true;
20966
20967 error('Function components cannot be given refs. ' + 'Attempts to access this ref will fail. ' + 'Did you mean to use React.forwardRef()?%s', info);
20968 }
20969 }
20970
20971 if (typeof Component.getDerivedStateFromProps === 'function') {
20972 var _componentName3 = getComponentNameFromType(Component) || 'Unknown';
20973
20974 if (!didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3]) {
20975 error('%s: Function components do not support getDerivedStateFromProps.', _componentName3);
20976
20977 didWarnAboutGetDerivedStateOnFunctionComponent[_componentName3] = true;
20978 }
20979 }
20980
20981 if (typeof Component.contextType === 'object' && Component.contextType !== null) {
20982 var _componentName4 = getComponentNameFromType(Component) || 'Unknown';
20983
20984 if (!didWarnAboutContextTypeOnFunctionComponent[_componentName4]) {
20985 error('%s: Function components do not support contextType.', _componentName4);
20986
20987 didWarnAboutContextTypeOnFunctionComponent[_componentName4] = true;
20988 }
20989 }
20990 }
20991 }
20992
20993 var SUSPENDED_MARKER = {
20994 dehydrated: null,
20995 treeContext: null,
20996 retryLane: NoLane
20997 };
20998
20999 function mountSuspenseOffscreenState(renderLanes) {
21000 return {
21001 baseLanes: renderLanes,
21002 cachePool: getSuspendedCache()
21003 };
21004 }
21005
21006 function updateSuspenseOffscreenState(prevOffscreenState, renderLanes) {
21007 var cachePool = null;
21008
21009 return {
21010 baseLanes: mergeLanes(prevOffscreenState.baseLanes, renderLanes),
21011 cachePool: cachePool
21012 };
21013 } // TODO: Probably should inline this back
21014
21015
21016 function shouldRemainOnFallback(suspenseContext, current, workInProgress, renderLanes) {
21017 // If we're already showing a fallback, there are cases where we need to
21018 // remain on that fallback regardless of whether the content has resolved.
21019 // For example, SuspenseList coordinates when nested content appears.
21020 if (current !== null) {
21021 var suspenseState = current.memoizedState;
21022
21023 if (suspenseState === null) {
21024 // Currently showing content. Don't hide it, even if ForceSuspenseFallback
21025 // is true. More precise name might be "ForceRemainSuspenseFallback".
21026 // Note: This is a factoring smell. Can't remain on a fallback if there's
21027 // no fallback to remain on.
21028 return false;
21029 }
21030 } // Not currently showing content. Consult the Suspense context.
21031
21032
21033 return hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
21034 }
21035
21036 function getRemainingWorkInPrimaryTree(current, renderLanes) {
21037 // TODO: Should not remove render lanes that were pinged during this render
21038 return removeLanes(current.childLanes, renderLanes);
21039 }
21040
21041 function updateSuspenseComponent(current, workInProgress, renderLanes) {
21042 var nextProps = workInProgress.pendingProps; // This is used by DevTools to force a boundary to suspend.
21043
21044 {
21045 if (shouldSuspend(workInProgress)) {
21046 workInProgress.flags |= DidCapture;
21047 }
21048 }
21049
21050 var suspenseContext = suspenseStackCursor.current;
21051 var showFallback = false;
21052 var didSuspend = (workInProgress.flags & DidCapture) !== NoFlags;
21053
21054 if (didSuspend || shouldRemainOnFallback(suspenseContext, current)) {
21055 // Something in this boundary's subtree already suspended. Switch to
21056 // rendering the fallback children.
21057 showFallback = true;
21058 workInProgress.flags &= ~DidCapture;
21059 } else {
21060 // Attempting the main content
21061 if (current === null || current.memoizedState !== null) {
21062 // This is a new mount or this boundary is already showing a fallback state.
21063 // Mark this subtree context as having at least one invisible parent that could
21064 // handle the fallback state.
21065 // Avoided boundaries are not considered since they cannot handle preferred fallback states.
21066 {
21067 suspenseContext = addSubtreeSuspenseContext(suspenseContext, InvisibleParentSuspenseContext);
21068 }
21069 }
21070 }
21071
21072 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
21073 pushSuspenseContext(workInProgress, suspenseContext); // OK, the next part is confusing. We're about to reconcile the Suspense
21074 // boundary's children. This involves some custom reconciliation logic. Two
21075 // main reasons this is so complicated.
21076 //
21077 // First, Legacy Mode has different semantics for backwards compatibility. The
21078 // primary tree will commit in an inconsistent state, so when we do the
21079 // second pass to render the fallback, we do some exceedingly, uh, clever
21080 // hacks to make that not totally break. Like transferring effects and
21081 // deletions from hidden tree. In Concurrent Mode, it's much simpler,
21082 // because we bailout on the primary tree completely and leave it in its old
21083 // state, no effects. Same as what we do for Offscreen (except that
21084 // Offscreen doesn't have the first render pass).
21085 //
21086 // Second is hydration. During hydration, the Suspense fiber has a slightly
21087 // different layout, where the child points to a dehydrated fragment, which
21088 // contains the DOM rendered by the server.
21089 //
21090 // Third, even if you set all that aside, Suspense is like error boundaries in
21091 // that we first we try to render one tree, and if that fails, we render again
21092 // and switch to a different tree. Like a try/catch block. So we have to track
21093 // which branch we're currently rendering. Ideally we would model this using
21094 // a stack.
21095
21096 if (current === null) {
21097 // Initial mount
21098 // If we're currently hydrating, try to hydrate this boundary.
21099 tryToClaimNextHydratableInstance(workInProgress); // This could've been a dehydrated suspense component.
21100
21101 {
21102 var suspenseState = workInProgress.memoizedState;
21103
21104 if (suspenseState !== null) {
21105 var dehydrated = suspenseState.dehydrated;
21106
21107 if (dehydrated !== null) {
21108 return mountDehydratedSuspenseComponent(workInProgress, dehydrated);
21109 }
21110 }
21111 }
21112
21113 var nextPrimaryChildren = nextProps.children;
21114 var nextFallbackChildren = nextProps.fallback;
21115
21116 if (showFallback) {
21117 var fallbackFragment = mountSuspenseFallbackChildren(workInProgress, nextPrimaryChildren, nextFallbackChildren, renderLanes);
21118 var primaryChildFragment = workInProgress.child;
21119 primaryChildFragment.memoizedState = mountSuspenseOffscreenState(renderLanes);
21120 workInProgress.memoizedState = SUSPENDED_MARKER;
21121 return fallbackFragment;
21122 } else {
21123 return mountSuspensePrimaryChildren(workInProgress, nextPrimaryChildren);
21124 }
21125 } else {
21126 // This is an update.
21127 // If the current fiber has a SuspenseState, that means it's already showing
21128 // a fallback.
21129 var prevState = current.memoizedState;
21130
21131 if (prevState !== null) {
21132 // The current tree is already showing a fallback
21133 // Special path for hydration
21134 {
21135 var _dehydrated = prevState.dehydrated;
21136
21137 if (_dehydrated !== null) {
21138 if (!didSuspend) {
21139 return updateDehydratedSuspenseComponent(current, workInProgress, _dehydrated, prevState, renderLanes);
21140 } else if (workInProgress.flags & ForceClientRender) {
21141 // Something errored during hydration. Try again without hydrating.
21142 workInProgress.flags &= ~ForceClientRender;
21143 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, new Error('There was an error while hydrating this Suspense boundary. ' + 'Switched to client rendering.'));
21144 } else if (workInProgress.memoizedState !== null) {
21145 // Something suspended and we should still be in dehydrated mode.
21146 // Leave the existing child in place.
21147 workInProgress.child = current.child; // The dehydrated completion pass expects this flag to be there
21148 // but the normal suspense pass doesn't.
21149
21150 workInProgress.flags |= DidCapture;
21151 return null;
21152 } else {
21153 // Suspended but we should no longer be in dehydrated mode.
21154 // Therefore we now have to render the fallback.
21155 var _nextPrimaryChildren = nextProps.children;
21156 var _nextFallbackChildren = nextProps.fallback;
21157 var fallbackChildFragment = mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, _nextPrimaryChildren, _nextFallbackChildren, renderLanes);
21158 var _primaryChildFragment2 = workInProgress.child;
21159 _primaryChildFragment2.memoizedState = mountSuspenseOffscreenState(renderLanes);
21160 workInProgress.memoizedState = SUSPENDED_MARKER;
21161 return fallbackChildFragment;
21162 }
21163 }
21164 }
21165
21166 if (showFallback) {
21167 var _nextFallbackChildren2 = nextProps.fallback;
21168 var _nextPrimaryChildren2 = nextProps.children;
21169
21170 var _fallbackChildFragment = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren2, _nextFallbackChildren2, renderLanes);
21171
21172 var _primaryChildFragment3 = workInProgress.child;
21173 var prevOffscreenState = current.child.memoizedState;
21174 _primaryChildFragment3.memoizedState = prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(prevOffscreenState, renderLanes);
21175 _primaryChildFragment3.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes);
21176 workInProgress.memoizedState = SUSPENDED_MARKER;
21177 return _fallbackChildFragment;
21178 } else {
21179 var _nextPrimaryChildren3 = nextProps.children;
21180
21181 var _primaryChildFragment4 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren3, renderLanes);
21182
21183 workInProgress.memoizedState = null;
21184 return _primaryChildFragment4;
21185 }
21186 } else {
21187 // The current tree is not already showing a fallback.
21188 if (showFallback) {
21189 // Timed out.
21190 var _nextFallbackChildren3 = nextProps.fallback;
21191 var _nextPrimaryChildren4 = nextProps.children;
21192
21193 var _fallbackChildFragment2 = updateSuspenseFallbackChildren(current, workInProgress, _nextPrimaryChildren4, _nextFallbackChildren3, renderLanes);
21194
21195 var _primaryChildFragment5 = workInProgress.child;
21196 var _prevOffscreenState = current.child.memoizedState;
21197 _primaryChildFragment5.memoizedState = _prevOffscreenState === null ? mountSuspenseOffscreenState(renderLanes) : updateSuspenseOffscreenState(_prevOffscreenState, renderLanes);
21198 _primaryChildFragment5.childLanes = getRemainingWorkInPrimaryTree(current, renderLanes); // Skip the primary children, and continue working on the
21199 // fallback children.
21200
21201 workInProgress.memoizedState = SUSPENDED_MARKER;
21202 return _fallbackChildFragment2;
21203 } else {
21204 // Still haven't timed out. Continue rendering the children, like we
21205 // normally do.
21206 var _nextPrimaryChildren5 = nextProps.children;
21207
21208 var _primaryChildFragment6 = updateSuspensePrimaryChildren(current, workInProgress, _nextPrimaryChildren5, renderLanes);
21209
21210 workInProgress.memoizedState = null;
21211 return _primaryChildFragment6;
21212 }
21213 }
21214 }
21215 }
21216
21217 function mountSuspensePrimaryChildren(workInProgress, primaryChildren, renderLanes) {
21218 var mode = workInProgress.mode;
21219 var primaryChildProps = {
21220 mode: 'visible',
21221 children: primaryChildren
21222 };
21223 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
21224 primaryChildFragment.return = workInProgress;
21225 workInProgress.child = primaryChildFragment;
21226 return primaryChildFragment;
21227 }
21228
21229 function mountSuspenseFallbackChildren(workInProgress, primaryChildren, fallbackChildren, renderLanes) {
21230 var mode = workInProgress.mode;
21231 var progressedPrimaryFragment = workInProgress.child;
21232 var primaryChildProps = {
21233 mode: 'hidden',
21234 children: primaryChildren
21235 };
21236 var primaryChildFragment;
21237 var fallbackChildFragment;
21238
21239 if ((mode & ConcurrentMode) === NoMode && progressedPrimaryFragment !== null) {
21240 // In legacy mode, we commit the primary tree as if it successfully
21241 // completed, even though it's in an inconsistent state.
21242 primaryChildFragment = progressedPrimaryFragment;
21243 primaryChildFragment.childLanes = NoLanes;
21244 primaryChildFragment.pendingProps = primaryChildProps;
21245
21246 if ( workInProgress.mode & ProfileMode) {
21247 // Reset the durations from the first pass so they aren't included in the
21248 // final amounts. This seems counterintuitive, since we're intentionally
21249 // not measuring part of the render phase, but this makes it match what we
21250 // do in Concurrent Mode.
21251 primaryChildFragment.actualDuration = 0;
21252 primaryChildFragment.actualStartTime = -1;
21253 primaryChildFragment.selfBaseDuration = 0;
21254 primaryChildFragment.treeBaseDuration = 0;
21255 }
21256
21257 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
21258 } else {
21259 primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, mode);
21260 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null);
21261 }
21262
21263 primaryChildFragment.return = workInProgress;
21264 fallbackChildFragment.return = workInProgress;
21265 primaryChildFragment.sibling = fallbackChildFragment;
21266 workInProgress.child = primaryChildFragment;
21267 return fallbackChildFragment;
21268 }
21269
21270 function mountWorkInProgressOffscreenFiber(offscreenProps, mode, renderLanes) {
21271 // The props argument to `createFiberFromOffscreen` is `any` typed, so we use
21272 // this wrapper function to constrain it.
21273 return createFiberFromOffscreen(offscreenProps, mode, NoLanes, null);
21274 }
21275
21276 function updateWorkInProgressOffscreenFiber(current, offscreenProps) {
21277 // The props argument to `createWorkInProgress` is `any` typed, so we use this
21278 // wrapper function to constrain it.
21279 return createWorkInProgress(current, offscreenProps);
21280 }
21281
21282 function updateSuspensePrimaryChildren(current, workInProgress, primaryChildren, renderLanes) {
21283 var currentPrimaryChildFragment = current.child;
21284 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
21285 var primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, {
21286 mode: 'visible',
21287 children: primaryChildren
21288 });
21289
21290 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
21291 primaryChildFragment.lanes = renderLanes;
21292 }
21293
21294 primaryChildFragment.return = workInProgress;
21295 primaryChildFragment.sibling = null;
21296
21297 if (currentFallbackChildFragment !== null) {
21298 // Delete the fallback child fragment
21299 var deletions = workInProgress.deletions;
21300
21301 if (deletions === null) {
21302 workInProgress.deletions = [currentFallbackChildFragment];
21303 workInProgress.flags |= ChildDeletion;
21304 } else {
21305 deletions.push(currentFallbackChildFragment);
21306 }
21307 }
21308
21309 workInProgress.child = primaryChildFragment;
21310 return primaryChildFragment;
21311 }
21312
21313 function updateSuspenseFallbackChildren(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
21314 var mode = workInProgress.mode;
21315 var currentPrimaryChildFragment = current.child;
21316 var currentFallbackChildFragment = currentPrimaryChildFragment.sibling;
21317 var primaryChildProps = {
21318 mode: 'hidden',
21319 children: primaryChildren
21320 };
21321 var primaryChildFragment;
21322
21323 if ( // In legacy mode, we commit the primary tree as if it successfully
21324 // completed, even though it's in an inconsistent state.
21325 (mode & ConcurrentMode) === NoMode && // Make sure we're on the second pass, i.e. the primary child fragment was
21326 // already cloned. In legacy mode, the only case where this isn't true is
21327 // when DevTools forces us to display a fallback; we skip the first render
21328 // pass entirely and go straight to rendering the fallback. (In Concurrent
21329 // Mode, SuspenseList can also trigger this scenario, but this is a legacy-
21330 // only codepath.)
21331 workInProgress.child !== currentPrimaryChildFragment) {
21332 var progressedPrimaryFragment = workInProgress.child;
21333 primaryChildFragment = progressedPrimaryFragment;
21334 primaryChildFragment.childLanes = NoLanes;
21335 primaryChildFragment.pendingProps = primaryChildProps;
21336
21337 if ( workInProgress.mode & ProfileMode) {
21338 // Reset the durations from the first pass so they aren't included in the
21339 // final amounts. This seems counterintuitive, since we're intentionally
21340 // not measuring part of the render phase, but this makes it match what we
21341 // do in Concurrent Mode.
21342 primaryChildFragment.actualDuration = 0;
21343 primaryChildFragment.actualStartTime = -1;
21344 primaryChildFragment.selfBaseDuration = currentPrimaryChildFragment.selfBaseDuration;
21345 primaryChildFragment.treeBaseDuration = currentPrimaryChildFragment.treeBaseDuration;
21346 }
21347 // However, since we're going to remain on the fallback, we no longer want
21348 // to delete it.
21349
21350
21351 workInProgress.deletions = null;
21352 } else {
21353 primaryChildFragment = updateWorkInProgressOffscreenFiber(currentPrimaryChildFragment, primaryChildProps);
21354 // (We don't do this in legacy mode, because in legacy mode we don't re-use
21355 // the current tree; see previous branch.)
21356
21357
21358 primaryChildFragment.subtreeFlags = currentPrimaryChildFragment.subtreeFlags & StaticMask;
21359 }
21360
21361 var fallbackChildFragment;
21362
21363 if (currentFallbackChildFragment !== null) {
21364 fallbackChildFragment = createWorkInProgress(currentFallbackChildFragment, fallbackChildren);
21365 } else {
21366 fallbackChildFragment = createFiberFromFragment(fallbackChildren, mode, renderLanes, null); // Needs a placement effect because the parent (the Suspense boundary) already
21367 // mounted but this is a new fiber.
21368
21369 fallbackChildFragment.flags |= Placement;
21370 }
21371
21372 fallbackChildFragment.return = workInProgress;
21373 primaryChildFragment.return = workInProgress;
21374 primaryChildFragment.sibling = fallbackChildFragment;
21375 workInProgress.child = primaryChildFragment;
21376 return fallbackChildFragment;
21377 }
21378
21379 function retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, recoverableError) {
21380 // Falling back to client rendering. Because this has performance
21381 // implications, it's considered a recoverable error, even though the user
21382 // likely won't observe anything wrong with the UI.
21383 //
21384 // The error is passed in as an argument to enforce that every caller provide
21385 // a custom message, or explicitly opt out (currently the only path that opts
21386 // out is legacy mode; every concurrent path provides an error).
21387 if (recoverableError !== null) {
21388 queueHydrationError(recoverableError);
21389 } // This will add the old fiber to the deletion list
21390
21391
21392 reconcileChildFibers(workInProgress, current.child, null, renderLanes); // We're now not suspended nor dehydrated.
21393
21394 var nextProps = workInProgress.pendingProps;
21395 var primaryChildren = nextProps.children;
21396 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Needs a placement effect because the parent (the Suspense boundary) already
21397 // mounted but this is a new fiber.
21398
21399 primaryChildFragment.flags |= Placement;
21400 workInProgress.memoizedState = null;
21401 return primaryChildFragment;
21402 }
21403
21404 function mountSuspenseFallbackAfterRetryWithoutHydrating(current, workInProgress, primaryChildren, fallbackChildren, renderLanes) {
21405 var fiberMode = workInProgress.mode;
21406 var primaryChildProps = {
21407 mode: 'visible',
21408 children: primaryChildren
21409 };
21410 var primaryChildFragment = mountWorkInProgressOffscreenFiber(primaryChildProps, fiberMode);
21411 var fallbackChildFragment = createFiberFromFragment(fallbackChildren, fiberMode, renderLanes, null); // Needs a placement effect because the parent (the Suspense
21412 // boundary) already mounted but this is a new fiber.
21413
21414 fallbackChildFragment.flags |= Placement;
21415 primaryChildFragment.return = workInProgress;
21416 fallbackChildFragment.return = workInProgress;
21417 primaryChildFragment.sibling = fallbackChildFragment;
21418 workInProgress.child = primaryChildFragment;
21419
21420 if ((workInProgress.mode & ConcurrentMode) !== NoMode) {
21421 // We will have dropped the effect list which contains the
21422 // deletion. We need to reconcile to delete the current child.
21423 reconcileChildFibers(workInProgress, current.child, null, renderLanes);
21424 }
21425
21426 return fallbackChildFragment;
21427 }
21428
21429 function mountDehydratedSuspenseComponent(workInProgress, suspenseInstance, renderLanes) {
21430 // During the first pass, we'll bail out and not drill into the children.
21431 // Instead, we'll leave the content in place and try to hydrate it later.
21432 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
21433 {
21434 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.');
21435 }
21436
21437 workInProgress.lanes = laneToLanes(SyncLane);
21438 } else if (isSuspenseInstanceFallback(suspenseInstance)) {
21439 // This is a client-only boundary. Since we won't get any content from the server
21440 // for this, we need to schedule that at a higher priority based on when it would
21441 // have timed out. In theory we could render it in this pass but it would have the
21442 // wrong priority associated with it and will prevent hydration of parent path.
21443 // Instead, we'll leave work left on it to render it in a separate commit.
21444 // TODO This time should be the time at which the server rendered response that is
21445 // a parent to this boundary was displayed. However, since we currently don't have
21446 // a protocol to transfer that time, we'll just estimate it by using the current
21447 // time. This will mean that Suspense timeouts are slightly shifted to later than
21448 // they should be.
21449 // Schedule a normal pri update to render this content.
21450 workInProgress.lanes = laneToLanes(DefaultHydrationLane);
21451 } else {
21452 // We'll continue hydrating the rest at offscreen priority since we'll already
21453 // be showing the right content coming from the server, it is no rush.
21454 workInProgress.lanes = laneToLanes(OffscreenLane);
21455 }
21456
21457 return null;
21458 }
21459
21460 function updateDehydratedSuspenseComponent(current, workInProgress, suspenseInstance, suspenseState, renderLanes) {
21461 // We should never be hydrating at this point because it is the first pass,
21462 // but after we've already committed once.
21463 warnIfHydrating();
21464
21465 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
21466 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, // TODO: When we delete legacy mode, we should make this error argument
21467 // required — every concurrent mode path that causes hydration to
21468 // de-opt to client rendering should have an error message.
21469 null);
21470 }
21471
21472 if (isSuspenseInstanceFallback(suspenseInstance)) {
21473 // This boundary is in a permanent fallback state. In this case, we'll never
21474 // get an update and we'll never be able to hydrate the final content. Let's just try the
21475 // client side render instead.
21476 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, // TODO: The server should serialize the error message so we can log it
21477 // here on the client. Or, in production, a hash/id that corresponds to
21478 // the error.
21479 new Error('The server could not finish this Suspense boundary, likely ' + 'due to an error during server rendering. Switched to ' + 'client rendering.'));
21480 }
21481 // any context has changed, we need to treat is as if the input might have changed.
21482
21483
21484 var hasContextChanged = includesSomeLane(renderLanes, current.childLanes);
21485
21486 if (didReceiveUpdate || hasContextChanged) {
21487 // This boundary has changed since the first render. This means that we are now unable to
21488 // hydrate it. We might still be able to hydrate it using a higher priority lane.
21489 var root = getWorkInProgressRoot();
21490
21491 if (root !== null) {
21492 var attemptHydrationAtLane = getBumpedLaneForHydration(root, renderLanes);
21493
21494 if (attemptHydrationAtLane !== NoLane && attemptHydrationAtLane !== suspenseState.retryLane) {
21495 // Intentionally mutating since this render will get interrupted. This
21496 // is one of the very rare times where we mutate the current tree
21497 // during the render phase.
21498 suspenseState.retryLane = attemptHydrationAtLane; // TODO: Ideally this would inherit the event time of the current render
21499
21500 var eventTime = NoTimestamp;
21501 scheduleUpdateOnFiber(current, attemptHydrationAtLane, eventTime);
21502 }
21503 } // If we have scheduled higher pri work above, this will probably just abort the render
21504 // since we now have higher priority work, but in case it doesn't, we need to prepare to
21505 // render something, if we time out. Even if that requires us to delete everything and
21506 // skip hydration.
21507 // Delay having to do this as long as the suspense timeout allows us.
21508
21509
21510 renderDidSuspendDelayIfPossible();
21511 return retrySuspenseComponentWithoutHydrating(current, workInProgress, renderLanes, 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.'));
21512 } else if (isSuspenseInstancePending(suspenseInstance)) {
21513 // This component is still pending more data from the server, so we can't hydrate its
21514 // content. We treat it as if this component suspended itself. It might seem as if
21515 // we could just try to render it client-side instead. However, this will perform a
21516 // lot of unnecessary work and is unlikely to complete since it often will suspend
21517 // on missing data anyway. Additionally, the server might be able to render more
21518 // than we can on the client yet. In that case we'd end up with more fallback states
21519 // on the client than if we just leave it alone. If the server times out or errors
21520 // these should update this boundary to the permanent Fallback state instead.
21521 // Mark it as having captured (i.e. suspended).
21522 workInProgress.flags |= DidCapture; // Leave the child in place. I.e. the dehydrated fragment.
21523
21524 workInProgress.child = current.child; // Register a callback to retry this boundary once the server has sent the result.
21525
21526 var retry = retryDehydratedSuspenseBoundary.bind(null, current);
21527 registerSuspenseInstanceRetry(suspenseInstance, retry);
21528 return null;
21529 } else {
21530 // This is the first attempt.
21531 reenterHydrationStateFromDehydratedSuspenseInstance(workInProgress, suspenseInstance, suspenseState.treeContext);
21532 var nextProps = workInProgress.pendingProps;
21533 var primaryChildren = nextProps.children;
21534 var primaryChildFragment = mountSuspensePrimaryChildren(workInProgress, primaryChildren); // Mark the children as hydrating. This is a fast path to know whether this
21535 // tree is part of a hydrating tree. This is used to determine if a child
21536 // node has fully mounted yet, and for scheduling event replaying.
21537 // Conceptually this is similar to Placement in that a new subtree is
21538 // inserted into the React tree here. It just happens to not need DOM
21539 // mutations because it already exists.
21540
21541 primaryChildFragment.flags |= Hydrating;
21542 return primaryChildFragment;
21543 }
21544 }
21545
21546 function scheduleSuspenseWorkOnFiber(fiber, renderLanes, propagationRoot) {
21547 fiber.lanes = mergeLanes(fiber.lanes, renderLanes);
21548 var alternate = fiber.alternate;
21549
21550 if (alternate !== null) {
21551 alternate.lanes = mergeLanes(alternate.lanes, renderLanes);
21552 }
21553
21554 scheduleContextWorkOnParentPath(fiber.return, renderLanes, propagationRoot);
21555 }
21556
21557 function propagateSuspenseContextChange(workInProgress, firstChild, renderLanes) {
21558 // Mark any Suspense boundaries with fallbacks as having work to do.
21559 // If they were previously forced into fallbacks, they may now be able
21560 // to unblock.
21561 var node = firstChild;
21562
21563 while (node !== null) {
21564 if (node.tag === SuspenseComponent) {
21565 var state = node.memoizedState;
21566
21567 if (state !== null) {
21568 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
21569 }
21570 } else if (node.tag === SuspenseListComponent) {
21571 // If the tail is hidden there might not be an Suspense boundaries
21572 // to schedule work on. In this case we have to schedule it on the
21573 // list itself.
21574 // We don't have to traverse to the children of the list since
21575 // the list will propagate the change when it rerenders.
21576 scheduleSuspenseWorkOnFiber(node, renderLanes, workInProgress);
21577 } else if (node.child !== null) {
21578 node.child.return = node;
21579 node = node.child;
21580 continue;
21581 }
21582
21583 if (node === workInProgress) {
21584 return;
21585 }
21586
21587 while (node.sibling === null) {
21588 if (node.return === null || node.return === workInProgress) {
21589 return;
21590 }
21591
21592 node = node.return;
21593 }
21594
21595 node.sibling.return = node.return;
21596 node = node.sibling;
21597 }
21598 }
21599
21600 function findLastContentRow(firstChild) {
21601 // This is going to find the last row among these children that is already
21602 // showing content on the screen, as opposed to being in fallback state or
21603 // new. If a row has multiple Suspense boundaries, any of them being in the
21604 // fallback state, counts as the whole row being in a fallback state.
21605 // Note that the "rows" will be workInProgress, but any nested children
21606 // will still be current since we haven't rendered them yet. The mounted
21607 // order may not be the same as the new order. We use the new order.
21608 var row = firstChild;
21609 var lastContentRow = null;
21610
21611 while (row !== null) {
21612 var currentRow = row.alternate; // New rows can't be content rows.
21613
21614 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
21615 lastContentRow = row;
21616 }
21617
21618 row = row.sibling;
21619 }
21620
21621 return lastContentRow;
21622 }
21623
21624 function validateRevealOrder(revealOrder) {
21625 {
21626 if (revealOrder !== undefined && revealOrder !== 'forwards' && revealOrder !== 'backwards' && revealOrder !== 'together' && !didWarnAboutRevealOrder[revealOrder]) {
21627 didWarnAboutRevealOrder[revealOrder] = true;
21628
21629 if (typeof revealOrder === 'string') {
21630 switch (revealOrder.toLowerCase()) {
21631 case 'together':
21632 case 'forwards':
21633 case 'backwards':
21634 {
21635 error('"%s" is not a valid value for revealOrder on <SuspenseList />. ' + 'Use lowercase "%s" instead.', revealOrder, revealOrder.toLowerCase());
21636
21637 break;
21638 }
21639
21640 case 'forward':
21641 case 'backward':
21642 {
21643 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());
21644
21645 break;
21646 }
21647
21648 default:
21649 error('"%s" is not a supported revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
21650
21651 break;
21652 }
21653 } else {
21654 error('%s is not a supported value for revealOrder on <SuspenseList />. ' + 'Did you mean "together", "forwards" or "backwards"?', revealOrder);
21655 }
21656 }
21657 }
21658 }
21659
21660 function validateTailOptions(tailMode, revealOrder) {
21661 {
21662 if (tailMode !== undefined && !didWarnAboutTailOptions[tailMode]) {
21663 if (tailMode !== 'collapsed' && tailMode !== 'hidden') {
21664 didWarnAboutTailOptions[tailMode] = true;
21665
21666 error('"%s" is not a supported value for tail on <SuspenseList />. ' + 'Did you mean "collapsed" or "hidden"?', tailMode);
21667 } else if (revealOrder !== 'forwards' && revealOrder !== 'backwards') {
21668 didWarnAboutTailOptions[tailMode] = true;
21669
21670 error('<SuspenseList tail="%s" /> is only valid if revealOrder is ' + '"forwards" or "backwards". ' + 'Did you mean to specify revealOrder="forwards"?', tailMode);
21671 }
21672 }
21673 }
21674 }
21675
21676 function validateSuspenseListNestedChild(childSlot, index) {
21677 {
21678 var isAnArray = isArray(childSlot);
21679 var isIterable = !isAnArray && typeof getIteratorFn(childSlot) === 'function';
21680
21681 if (isAnArray || isIterable) {
21682 var type = isAnArray ? 'array' : 'iterable';
21683
21684 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);
21685
21686 return false;
21687 }
21688 }
21689
21690 return true;
21691 }
21692
21693 function validateSuspenseListChildren(children, revealOrder) {
21694 {
21695 if ((revealOrder === 'forwards' || revealOrder === 'backwards') && children !== undefined && children !== null && children !== false) {
21696 if (isArray(children)) {
21697 for (var i = 0; i < children.length; i++) {
21698 if (!validateSuspenseListNestedChild(children[i], i)) {
21699 return;
21700 }
21701 }
21702 } else {
21703 var iteratorFn = getIteratorFn(children);
21704
21705 if (typeof iteratorFn === 'function') {
21706 var childrenIterator = iteratorFn.call(children);
21707
21708 if (childrenIterator) {
21709 var step = childrenIterator.next();
21710 var _i = 0;
21711
21712 for (; !step.done; step = childrenIterator.next()) {
21713 if (!validateSuspenseListNestedChild(step.value, _i)) {
21714 return;
21715 }
21716
21717 _i++;
21718 }
21719 }
21720 } else {
21721 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);
21722 }
21723 }
21724 }
21725 }
21726 }
21727
21728 function initSuspenseListRenderState(workInProgress, isBackwards, tail, lastContentRow, tailMode) {
21729 var renderState = workInProgress.memoizedState;
21730
21731 if (renderState === null) {
21732 workInProgress.memoizedState = {
21733 isBackwards: isBackwards,
21734 rendering: null,
21735 renderingStartTime: 0,
21736 last: lastContentRow,
21737 tail: tail,
21738 tailMode: tailMode
21739 };
21740 } else {
21741 // We can reuse the existing object from previous renders.
21742 renderState.isBackwards = isBackwards;
21743 renderState.rendering = null;
21744 renderState.renderingStartTime = 0;
21745 renderState.last = lastContentRow;
21746 renderState.tail = tail;
21747 renderState.tailMode = tailMode;
21748 }
21749 } // This can end up rendering this component multiple passes.
21750 // The first pass splits the children fibers into two sets. A head and tail.
21751 // We first render the head. If anything is in fallback state, we do another
21752 // pass through beginWork to rerender all children (including the tail) with
21753 // the force suspend context. If the first render didn't have anything in
21754 // in fallback state. Then we render each row in the tail one-by-one.
21755 // That happens in the completeWork phase without going back to beginWork.
21756
21757
21758 function updateSuspenseListComponent(current, workInProgress, renderLanes) {
21759 var nextProps = workInProgress.pendingProps;
21760 var revealOrder = nextProps.revealOrder;
21761 var tailMode = nextProps.tail;
21762 var newChildren = nextProps.children;
21763 validateRevealOrder(revealOrder);
21764 validateTailOptions(tailMode, revealOrder);
21765 validateSuspenseListChildren(newChildren, revealOrder);
21766 reconcileChildren(current, workInProgress, newChildren, renderLanes);
21767 var suspenseContext = suspenseStackCursor.current;
21768 var shouldForceFallback = hasSuspenseContext(suspenseContext, ForceSuspenseFallback);
21769
21770 if (shouldForceFallback) {
21771 suspenseContext = setShallowSuspenseContext(suspenseContext, ForceSuspenseFallback);
21772 workInProgress.flags |= DidCapture;
21773 } else {
21774 var didSuspendBefore = current !== null && (current.flags & DidCapture) !== NoFlags;
21775
21776 if (didSuspendBefore) {
21777 // If we previously forced a fallback, we need to schedule work
21778 // on any nested boundaries to let them know to try to render
21779 // again. This is the same as context updating.
21780 propagateSuspenseContextChange(workInProgress, workInProgress.child, renderLanes);
21781 }
21782
21783 suspenseContext = setDefaultShallowSuspenseContext(suspenseContext);
21784 }
21785
21786 pushSuspenseContext(workInProgress, suspenseContext);
21787
21788 if ((workInProgress.mode & ConcurrentMode) === NoMode) {
21789 // In legacy mode, SuspenseList doesn't work so we just
21790 // use make it a noop by treating it as the default revealOrder.
21791 workInProgress.memoizedState = null;
21792 } else {
21793 switch (revealOrder) {
21794 case 'forwards':
21795 {
21796 var lastContentRow = findLastContentRow(workInProgress.child);
21797 var tail;
21798
21799 if (lastContentRow === null) {
21800 // The whole list is part of the tail.
21801 // TODO: We could fast path by just rendering the tail now.
21802 tail = workInProgress.child;
21803 workInProgress.child = null;
21804 } else {
21805 // Disconnect the tail rows after the content row.
21806 // We're going to render them separately later.
21807 tail = lastContentRow.sibling;
21808 lastContentRow.sibling = null;
21809 }
21810
21811 initSuspenseListRenderState(workInProgress, false, // isBackwards
21812 tail, lastContentRow, tailMode);
21813 break;
21814 }
21815
21816 case 'backwards':
21817 {
21818 // We're going to find the first row that has existing content.
21819 // At the same time we're going to reverse the list of everything
21820 // we pass in the meantime. That's going to be our tail in reverse
21821 // order.
21822 var _tail = null;
21823 var row = workInProgress.child;
21824 workInProgress.child = null;
21825
21826 while (row !== null) {
21827 var currentRow = row.alternate; // New rows can't be content rows.
21828
21829 if (currentRow !== null && findFirstSuspended(currentRow) === null) {
21830 // This is the beginning of the main content.
21831 workInProgress.child = row;
21832 break;
21833 }
21834
21835 var nextRow = row.sibling;
21836 row.sibling = _tail;
21837 _tail = row;
21838 row = nextRow;
21839 } // TODO: If workInProgress.child is null, we can continue on the tail immediately.
21840
21841
21842 initSuspenseListRenderState(workInProgress, true, // isBackwards
21843 _tail, null, // last
21844 tailMode);
21845 break;
21846 }
21847
21848 case 'together':
21849 {
21850 initSuspenseListRenderState(workInProgress, false, // isBackwards
21851 null, // tail
21852 null, // last
21853 undefined);
21854 break;
21855 }
21856
21857 default:
21858 {
21859 // The default reveal order is the same as not having
21860 // a boundary.
21861 workInProgress.memoizedState = null;
21862 }
21863 }
21864 }
21865
21866 return workInProgress.child;
21867 }
21868
21869 function updatePortalComponent(current, workInProgress, renderLanes) {
21870 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
21871 var nextChildren = workInProgress.pendingProps;
21872
21873 if (current === null) {
21874 // Portals are special because we don't append the children during mount
21875 // but at commit. Therefore we need to track insertions which the normal
21876 // flow doesn't do during mount. This doesn't happen at the root because
21877 // the root always starts with a "current" with a null child.
21878 // TODO: Consider unifying this with how the root works.
21879 workInProgress.child = reconcileChildFibers(workInProgress, null, nextChildren, renderLanes);
21880 } else {
21881 reconcileChildren(current, workInProgress, nextChildren, renderLanes);
21882 }
21883
21884 return workInProgress.child;
21885 }
21886
21887 var hasWarnedAboutUsingNoValuePropOnContextProvider = false;
21888
21889 function updateContextProvider(current, workInProgress, renderLanes) {
21890 var providerType = workInProgress.type;
21891 var context = providerType._context;
21892 var newProps = workInProgress.pendingProps;
21893 var oldProps = workInProgress.memoizedProps;
21894 var newValue = newProps.value;
21895
21896 {
21897 if (!('value' in newProps)) {
21898 if (!hasWarnedAboutUsingNoValuePropOnContextProvider) {
21899 hasWarnedAboutUsingNoValuePropOnContextProvider = true;
21900
21901 error('The `value` prop is required for the `<Context.Provider>`. Did you misspell it or forget to pass it?');
21902 }
21903 }
21904
21905 var providerPropTypes = workInProgress.type.propTypes;
21906
21907 if (providerPropTypes) {
21908 checkPropTypes(providerPropTypes, newProps, 'prop', 'Context.Provider');
21909 }
21910 }
21911
21912 pushProvider(workInProgress, context, newValue);
21913
21914 {
21915 if (oldProps !== null) {
21916 var oldValue = oldProps.value;
21917
21918 if (objectIs(oldValue, newValue)) {
21919 // No change. Bailout early if children are the same.
21920 if (oldProps.children === newProps.children && !hasContextChanged()) {
21921 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
21922 }
21923 } else {
21924 // The context value changed. Search for matching consumers and schedule
21925 // them to update.
21926 propagateContextChange(workInProgress, context, renderLanes);
21927 }
21928 }
21929 }
21930
21931 var newChildren = newProps.children;
21932 reconcileChildren(current, workInProgress, newChildren, renderLanes);
21933 return workInProgress.child;
21934 }
21935
21936 var hasWarnedAboutUsingContextAsConsumer = false;
21937
21938 function updateContextConsumer(current, workInProgress, renderLanes) {
21939 var context = workInProgress.type; // The logic below for Context differs depending on PROD or DEV mode. In
21940 // DEV mode, we create a separate object for Context.Consumer that acts
21941 // like a proxy to Context. This proxy object adds unnecessary code in PROD
21942 // so we use the old behaviour (Context.Consumer references Context) to
21943 // reduce size and overhead. The separate object references context via
21944 // a property called "_context", which also gives us the ability to check
21945 // in DEV mode if this property exists or not and warn if it does not.
21946
21947 {
21948 if (context._context === undefined) {
21949 // This may be because it's a Context (rather than a Consumer).
21950 // Or it may be because it's older React where they're the same thing.
21951 // We only want to warn if we're sure it's a new React.
21952 if (context !== context.Consumer) {
21953 if (!hasWarnedAboutUsingContextAsConsumer) {
21954 hasWarnedAboutUsingContextAsConsumer = true;
21955
21956 error('Rendering <Context> directly is not supported and will be removed in ' + 'a future major release. Did you mean to render <Context.Consumer> instead?');
21957 }
21958 }
21959 } else {
21960 context = context._context;
21961 }
21962 }
21963
21964 var newProps = workInProgress.pendingProps;
21965 var render = newProps.children;
21966
21967 {
21968 if (typeof render !== 'function') {
21969 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.');
21970 }
21971 }
21972
21973 prepareToReadContext(workInProgress, renderLanes);
21974 var newValue = readContext(context);
21975
21976 {
21977 markComponentRenderStarted(workInProgress);
21978 }
21979
21980 var newChildren;
21981
21982 {
21983 ReactCurrentOwner$1.current = workInProgress;
21984 setIsRendering(true);
21985 newChildren = render(newValue);
21986 setIsRendering(false);
21987 }
21988
21989 {
21990 markComponentRenderStopped();
21991 } // React DevTools reads this flag.
21992
21993
21994 workInProgress.flags |= PerformedWork;
21995 reconcileChildren(current, workInProgress, newChildren, renderLanes);
21996 return workInProgress.child;
21997 }
21998
21999 function markWorkInProgressReceivedUpdate() {
22000 didReceiveUpdate = true;
22001 }
22002
22003 function bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes) {
22004 if (current !== null) {
22005 // Reuse previous dependencies
22006 workInProgress.dependencies = current.dependencies;
22007 }
22008
22009 {
22010 // Don't update "base" render times for bailouts.
22011 stopProfilerTimerIfRunning();
22012 }
22013
22014 markSkippedUpdateLanes(workInProgress.lanes); // Check if the children have any pending work.
22015
22016 if (!includesSomeLane(renderLanes, workInProgress.childLanes)) {
22017 // The children don't have any work either. We can skip them.
22018 // TODO: Once we add back resuming, we should check if the children are
22019 // a work-in-progress set. If so, we need to transfer their effects.
22020 {
22021 return null;
22022 }
22023 } // This fiber doesn't have work, but its subtree does. Clone the child
22024 // fibers and continue.
22025
22026
22027 cloneChildFibers(current, workInProgress);
22028 return workInProgress.child;
22029 }
22030
22031 function remountFiber(current, oldWorkInProgress, newWorkInProgress) {
22032 {
22033 var returnFiber = oldWorkInProgress.return;
22034
22035 if (returnFiber === null) {
22036 // eslint-disable-next-line react-internal/prod-error-codes
22037 throw new Error('Cannot swap the root fiber.');
22038 } // Disconnect from the old current.
22039 // It will get deleted.
22040
22041
22042 current.alternate = null;
22043 oldWorkInProgress.alternate = null; // Connect to the new tree.
22044
22045 newWorkInProgress.index = oldWorkInProgress.index;
22046 newWorkInProgress.sibling = oldWorkInProgress.sibling;
22047 newWorkInProgress.return = oldWorkInProgress.return;
22048 newWorkInProgress.ref = oldWorkInProgress.ref; // Replace the child/sibling pointers above it.
22049
22050 if (oldWorkInProgress === returnFiber.child) {
22051 returnFiber.child = newWorkInProgress;
22052 } else {
22053 var prevSibling = returnFiber.child;
22054
22055 if (prevSibling === null) {
22056 // eslint-disable-next-line react-internal/prod-error-codes
22057 throw new Error('Expected parent to have a child.');
22058 }
22059
22060 while (prevSibling.sibling !== oldWorkInProgress) {
22061 prevSibling = prevSibling.sibling;
22062
22063 if (prevSibling === null) {
22064 // eslint-disable-next-line react-internal/prod-error-codes
22065 throw new Error('Expected to find the previous sibling.');
22066 }
22067 }
22068
22069 prevSibling.sibling = newWorkInProgress;
22070 } // Delete the old fiber and place the new one.
22071 // Since the old fiber is disconnected, we have to schedule it manually.
22072
22073
22074 var deletions = returnFiber.deletions;
22075
22076 if (deletions === null) {
22077 returnFiber.deletions = [current];
22078 returnFiber.flags |= ChildDeletion;
22079 } else {
22080 deletions.push(current);
22081 }
22082
22083 newWorkInProgress.flags |= Placement; // Restart work from the new fiber.
22084
22085 return newWorkInProgress;
22086 }
22087 }
22088
22089 function checkScheduledUpdateOrContext(current, renderLanes) {
22090 // Before performing an early bailout, we must check if there are pending
22091 // updates or context.
22092 var updateLanes = current.lanes;
22093
22094 if (includesSomeLane(updateLanes, renderLanes)) {
22095 return true;
22096 } // No pending update, but because context is propagated lazily, we need
22097
22098 return false;
22099 }
22100
22101 function attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes) {
22102 // This fiber does not have any pending work. Bailout without entering
22103 // the begin phase. There's still some bookkeeping we that needs to be done
22104 // in this optimized path, mostly pushing stuff onto the stack.
22105 switch (workInProgress.tag) {
22106 case HostRoot:
22107 pushHostRootContext(workInProgress);
22108 var root = workInProgress.stateNode;
22109
22110 resetHydrationState();
22111 break;
22112
22113 case HostComponent:
22114 pushHostContext(workInProgress);
22115 break;
22116
22117 case ClassComponent:
22118 {
22119 var Component = workInProgress.type;
22120
22121 if (isContextProvider(Component)) {
22122 pushContextProvider(workInProgress);
22123 }
22124
22125 break;
22126 }
22127
22128 case HostPortal:
22129 pushHostContainer(workInProgress, workInProgress.stateNode.containerInfo);
22130 break;
22131
22132 case ContextProvider:
22133 {
22134 var newValue = workInProgress.memoizedProps.value;
22135 var context = workInProgress.type._context;
22136 pushProvider(workInProgress, context, newValue);
22137 break;
22138 }
22139
22140 case Profiler:
22141 {
22142 // Profiler should only call onRender when one of its descendants actually rendered.
22143 var hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
22144
22145 if (hasChildWork) {
22146 workInProgress.flags |= Update;
22147 }
22148
22149 {
22150 // Reset effect durations for the next eventual effect phase.
22151 // These are reset during render to allow the DevTools commit hook a chance to read them,
22152 var stateNode = workInProgress.stateNode;
22153 stateNode.effectDuration = 0;
22154 stateNode.passiveEffectDuration = 0;
22155 }
22156 }
22157
22158 break;
22159
22160 case SuspenseComponent:
22161 {
22162 var state = workInProgress.memoizedState;
22163
22164 if (state !== null) {
22165 {
22166 if (state.dehydrated !== null) {
22167 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // We know that this component will suspend again because if it has
22168 // been unsuspended it has committed as a resolved Suspense component.
22169 // If it needs to be retried, it should have work scheduled on it.
22170
22171 workInProgress.flags |= DidCapture; // We should never render the children of a dehydrated boundary until we
22172 // upgrade it. We return null instead of bailoutOnAlreadyFinishedWork.
22173
22174 return null;
22175 }
22176 } // If this boundary is currently timed out, we need to decide
22177 // whether to retry the primary children, or to skip over it and
22178 // go straight to the fallback. Check the priority of the primary
22179 // child fragment.
22180
22181
22182 var primaryChildFragment = workInProgress.child;
22183 var primaryChildLanes = primaryChildFragment.childLanes;
22184
22185 if (includesSomeLane(renderLanes, primaryChildLanes)) {
22186 // The primary children have pending work. Use the normal path
22187 // to attempt to render the primary children again.
22188 return updateSuspenseComponent(current, workInProgress, renderLanes);
22189 } else {
22190 // The primary child fragment does not have pending work marked
22191 // on it
22192 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current)); // The primary children do not have pending work with sufficient
22193 // priority. Bailout.
22194
22195 var child = bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
22196
22197 if (child !== null) {
22198 // The fallback children have pending work. Skip over the
22199 // primary children and work on the fallback.
22200 return child.sibling;
22201 } else {
22202 // Note: We can return `null` here because we already checked
22203 // whether there were nested context consumers, via the call to
22204 // `bailoutOnAlreadyFinishedWork` above.
22205 return null;
22206 }
22207 }
22208 } else {
22209 pushSuspenseContext(workInProgress, setDefaultShallowSuspenseContext(suspenseStackCursor.current));
22210 }
22211
22212 break;
22213 }
22214
22215 case SuspenseListComponent:
22216 {
22217 var didSuspendBefore = (current.flags & DidCapture) !== NoFlags;
22218
22219 var _hasChildWork = includesSomeLane(renderLanes, workInProgress.childLanes);
22220
22221 if (didSuspendBefore) {
22222 if (_hasChildWork) {
22223 // If something was in fallback state last time, and we have all the
22224 // same children then we're still in progressive loading state.
22225 // Something might get unblocked by state updates or retries in the
22226 // tree which will affect the tail. So we need to use the normal
22227 // path to compute the correct tail.
22228 return updateSuspenseListComponent(current, workInProgress, renderLanes);
22229 } // If none of the children had any work, that means that none of
22230 // them got retried so they'll still be blocked in the same way
22231 // as before. We can fast bail out.
22232
22233
22234 workInProgress.flags |= DidCapture;
22235 } // If nothing suspended before and we're rendering the same children,
22236 // then the tail doesn't matter. Anything new that suspends will work
22237 // in the "together" mode, so we can continue from the state we had.
22238
22239
22240 var renderState = workInProgress.memoizedState;
22241
22242 if (renderState !== null) {
22243 // Reset to the "together" mode in case we've started a different
22244 // update in the past but didn't complete it.
22245 renderState.rendering = null;
22246 renderState.tail = null;
22247 renderState.lastEffect = null;
22248 }
22249
22250 pushSuspenseContext(workInProgress, suspenseStackCursor.current);
22251
22252 if (_hasChildWork) {
22253 break;
22254 } else {
22255 // If none of the children had any work, that means that none of
22256 // them got retried so they'll still be blocked in the same way
22257 // as before. We can fast bail out.
22258 return null;
22259 }
22260 }
22261
22262 case OffscreenComponent:
22263 case LegacyHiddenComponent:
22264 {
22265 // Need to check if the tree still needs to be deferred. This is
22266 // almost identical to the logic used in the normal update path,
22267 // so we'll just enter that. The only difference is we'll bail out
22268 // at the next level instead of this one, because the child props
22269 // have not changed. Which is fine.
22270 // TODO: Probably should refactor `beginWork` to split the bailout
22271 // path from the normal path. I'm tempted to do a labeled break here
22272 // but I won't :)
22273 workInProgress.lanes = NoLanes;
22274 return updateOffscreenComponent(current, workInProgress, renderLanes);
22275 }
22276 }
22277
22278 return bailoutOnAlreadyFinishedWork(current, workInProgress, renderLanes);
22279 }
22280
22281 function beginWork(current, workInProgress, renderLanes) {
22282 {
22283 if (workInProgress._debugNeedsRemount && current !== null) {
22284 // This will restart the begin phase with a new fiber.
22285 return remountFiber(current, workInProgress, createFiberFromTypeAndProps(workInProgress.type, workInProgress.key, workInProgress.pendingProps, workInProgress._debugOwner || null, workInProgress.mode, workInProgress.lanes));
22286 }
22287 }
22288
22289 if (current !== null) {
22290 var oldProps = current.memoizedProps;
22291 var newProps = workInProgress.pendingProps;
22292
22293 if (oldProps !== newProps || hasContextChanged() || ( // Force a re-render if the implementation changed due to hot reload:
22294 workInProgress.type !== current.type )) {
22295 // If props or context changed, mark the fiber as having performed work.
22296 // This may be unset if the props are determined to be equal later (memo).
22297 didReceiveUpdate = true;
22298 } else {
22299 // Neither props nor legacy context changes. Check if there's a pending
22300 // update or context change.
22301 var hasScheduledUpdateOrContext = checkScheduledUpdateOrContext(current, renderLanes);
22302
22303 if (!hasScheduledUpdateOrContext && // If this is the second pass of an error or suspense boundary, there
22304 // may not be work scheduled on `current`, so we check for this flag.
22305 (workInProgress.flags & DidCapture) === NoFlags) {
22306 // No pending updates or context. Bail out now.
22307 didReceiveUpdate = false;
22308 return attemptEarlyBailoutIfNoScheduledUpdate(current, workInProgress, renderLanes);
22309 }
22310
22311 if ((current.flags & ForceUpdateForLegacySuspense) !== NoFlags) {
22312 // This is a special case that only exists for legacy mode.
22313 // See https://github.com/facebook/react/pull/19216.
22314 didReceiveUpdate = true;
22315 } else {
22316 // An update was scheduled on this fiber, but there are no new props
22317 // nor legacy context. Set this to false. If an update queue or context
22318 // consumer produces a changed value, it will set this to true. Otherwise,
22319 // the component will assume the children have not changed and bail out.
22320 didReceiveUpdate = false;
22321 }
22322 }
22323 } else {
22324 didReceiveUpdate = false;
22325
22326 if (getIsHydrating() && isForkedChild(workInProgress)) {
22327 // Check if this child belongs to a list of muliple children in
22328 // its parent.
22329 //
22330 // In a true multi-threaded implementation, we would render children on
22331 // parallel threads. This would represent the beginning of a new render
22332 // thread for this subtree.
22333 //
22334 // We only use this for id generation during hydration, which is why the
22335 // logic is located in this special branch.
22336 var slotIndex = workInProgress.index;
22337 var numberOfForks = getForksAtLevel();
22338 pushTreeId(workInProgress, numberOfForks, slotIndex);
22339 }
22340 } // Before entering the begin phase, clear pending update priority.
22341 // TODO: This assumes that we're about to evaluate the component and process
22342 // the update queue. However, there's an exception: SimpleMemoComponent
22343 // sometimes bails out later in the begin phase. This indicates that we should
22344 // move this assignment out of the common path and into each branch.
22345
22346
22347 workInProgress.lanes = NoLanes;
22348
22349 switch (workInProgress.tag) {
22350 case IndeterminateComponent:
22351 {
22352 return mountIndeterminateComponent(current, workInProgress, workInProgress.type, renderLanes);
22353 }
22354
22355 case LazyComponent:
22356 {
22357 var elementType = workInProgress.elementType;
22358 return mountLazyComponent(current, workInProgress, elementType, renderLanes);
22359 }
22360
22361 case FunctionComponent:
22362 {
22363 var Component = workInProgress.type;
22364 var unresolvedProps = workInProgress.pendingProps;
22365 var resolvedProps = workInProgress.elementType === Component ? unresolvedProps : resolveDefaultProps(Component, unresolvedProps);
22366 return updateFunctionComponent(current, workInProgress, Component, resolvedProps, renderLanes);
22367 }
22368
22369 case ClassComponent:
22370 {
22371 var _Component = workInProgress.type;
22372 var _unresolvedProps = workInProgress.pendingProps;
22373
22374 var _resolvedProps = workInProgress.elementType === _Component ? _unresolvedProps : resolveDefaultProps(_Component, _unresolvedProps);
22375
22376 return updateClassComponent(current, workInProgress, _Component, _resolvedProps, renderLanes);
22377 }
22378
22379 case HostRoot:
22380 return updateHostRoot(current, workInProgress, renderLanes);
22381
22382 case HostComponent:
22383 return updateHostComponent$1(current, workInProgress, renderLanes);
22384
22385 case HostText:
22386 return updateHostText$1(current, workInProgress);
22387
22388 case SuspenseComponent:
22389 return updateSuspenseComponent(current, workInProgress, renderLanes);
22390
22391 case HostPortal:
22392 return updatePortalComponent(current, workInProgress, renderLanes);
22393
22394 case ForwardRef:
22395 {
22396 var type = workInProgress.type;
22397 var _unresolvedProps2 = workInProgress.pendingProps;
22398
22399 var _resolvedProps2 = workInProgress.elementType === type ? _unresolvedProps2 : resolveDefaultProps(type, _unresolvedProps2);
22400
22401 return updateForwardRef(current, workInProgress, type, _resolvedProps2, renderLanes);
22402 }
22403
22404 case Fragment:
22405 return updateFragment(current, workInProgress, renderLanes);
22406
22407 case Mode:
22408 return updateMode(current, workInProgress, renderLanes);
22409
22410 case Profiler:
22411 return updateProfiler(current, workInProgress, renderLanes);
22412
22413 case ContextProvider:
22414 return updateContextProvider(current, workInProgress, renderLanes);
22415
22416 case ContextConsumer:
22417 return updateContextConsumer(current, workInProgress, renderLanes);
22418
22419 case MemoComponent:
22420 {
22421 var _type2 = workInProgress.type;
22422 var _unresolvedProps3 = workInProgress.pendingProps; // Resolve outer props first, then resolve inner props.
22423
22424 var _resolvedProps3 = resolveDefaultProps(_type2, _unresolvedProps3);
22425
22426 {
22427 if (workInProgress.type !== workInProgress.elementType) {
22428 var outerPropTypes = _type2.propTypes;
22429
22430 if (outerPropTypes) {
22431 checkPropTypes(outerPropTypes, _resolvedProps3, // Resolved for outer only
22432 'prop', getComponentNameFromType(_type2));
22433 }
22434 }
22435 }
22436
22437 _resolvedProps3 = resolveDefaultProps(_type2.type, _resolvedProps3);
22438 return updateMemoComponent(current, workInProgress, _type2, _resolvedProps3, renderLanes);
22439 }
22440
22441 case SimpleMemoComponent:
22442 {
22443 return updateSimpleMemoComponent(current, workInProgress, workInProgress.type, workInProgress.pendingProps, renderLanes);
22444 }
22445
22446 case IncompleteClassComponent:
22447 {
22448 var _Component2 = workInProgress.type;
22449 var _unresolvedProps4 = workInProgress.pendingProps;
22450
22451 var _resolvedProps4 = workInProgress.elementType === _Component2 ? _unresolvedProps4 : resolveDefaultProps(_Component2, _unresolvedProps4);
22452
22453 return mountIncompleteClassComponent(current, workInProgress, _Component2, _resolvedProps4, renderLanes);
22454 }
22455
22456 case SuspenseListComponent:
22457 {
22458 return updateSuspenseListComponent(current, workInProgress, renderLanes);
22459 }
22460
22461 case ScopeComponent:
22462 {
22463
22464 break;
22465 }
22466
22467 case OffscreenComponent:
22468 {
22469 return updateOffscreenComponent(current, workInProgress, renderLanes);
22470 }
22471 }
22472
22473 throw new Error("Unknown unit of work tag (" + workInProgress.tag + "). This error is likely caused by a bug in " + 'React. Please file an issue.');
22474 }
22475
22476 function unwindWork(current, workInProgress, renderLanes) {
22477 // Note: This intentionally doesn't check if we're hydrating because comparing
22478 // to the current tree provider fiber is just as fast and less error-prone.
22479 // Ideally we would have a special version of the work loop only
22480 // for hydration.
22481 popTreeContext(workInProgress);
22482
22483 switch (workInProgress.tag) {
22484 case ClassComponent:
22485 {
22486 var Component = workInProgress.type;
22487
22488 if (isContextProvider(Component)) {
22489 popContext(workInProgress);
22490 }
22491
22492 var flags = workInProgress.flags;
22493
22494 if (flags & ShouldCapture) {
22495 workInProgress.flags = flags & ~ShouldCapture | DidCapture;
22496
22497 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22498 transferActualDuration(workInProgress);
22499 }
22500
22501 return workInProgress;
22502 }
22503
22504 return null;
22505 }
22506
22507 case HostRoot:
22508 {
22509
22510 popHostContainer(workInProgress);
22511 popTopLevelContextObject(workInProgress);
22512 resetWorkInProgressVersions();
22513 var _flags = workInProgress.flags;
22514
22515 if ((_flags & ShouldCapture) !== NoFlags && (_flags & DidCapture) === NoFlags) {
22516 // There was an error during render that wasn't captured by a suspense
22517 // boundary. Do a second pass on the root to unmount the children.
22518 workInProgress.flags = _flags & ~ShouldCapture | DidCapture;
22519 return workInProgress;
22520 } // We unwound to the root without completing it. Exit.
22521
22522
22523 return null;
22524 }
22525
22526 case HostComponent:
22527 {
22528 // TODO: popHydrationState
22529 popHostContext(workInProgress);
22530 return null;
22531 }
22532
22533 case SuspenseComponent:
22534 {
22535 popSuspenseContext(workInProgress);
22536
22537 {
22538 var suspenseState = workInProgress.memoizedState;
22539
22540 if (suspenseState !== null && suspenseState.dehydrated !== null) {
22541 if (workInProgress.alternate === null) {
22542 throw new Error('Threw in newly mounted dehydrated component. This is likely a bug in ' + 'React. Please file an issue.');
22543 }
22544
22545 resetHydrationState();
22546 }
22547 }
22548
22549 var _flags2 = workInProgress.flags;
22550
22551 if (_flags2 & ShouldCapture) {
22552 workInProgress.flags = _flags2 & ~ShouldCapture | DidCapture; // Captured a suspense effect. Re-render the boundary.
22553
22554 if ( (workInProgress.mode & ProfileMode) !== NoMode) {
22555 transferActualDuration(workInProgress);
22556 }
22557
22558 return workInProgress;
22559 }
22560
22561 return null;
22562 }
22563
22564 case SuspenseListComponent:
22565 {
22566 popSuspenseContext(workInProgress); // SuspenseList doesn't actually catch anything. It should've been
22567 // caught by a nested boundary. If not, it should bubble through.
22568
22569 return null;
22570 }
22571
22572 case HostPortal:
22573 popHostContainer(workInProgress);
22574 return null;
22575
22576 case ContextProvider:
22577 var context = workInProgress.type._context;
22578 popProvider(context, workInProgress);
22579 return null;
22580
22581 case OffscreenComponent:
22582 case LegacyHiddenComponent:
22583 popRenderLanes(workInProgress);
22584
22585 return null;
22586
22587 case CacheComponent:
22588
22589 return null;
22590
22591 default:
22592 return null;
22593 }
22594 }
22595
22596 function unwindInterruptedWork(current, interruptedWork, renderLanes) {
22597 // Note: This intentionally doesn't check if we're hydrating because comparing
22598 // to the current tree provider fiber is just as fast and less error-prone.
22599 // Ideally we would have a special version of the work loop only
22600 // for hydration.
22601 popTreeContext(interruptedWork);
22602
22603 switch (interruptedWork.tag) {
22604 case ClassComponent:
22605 {
22606 var childContextTypes = interruptedWork.type.childContextTypes;
22607
22608 if (childContextTypes !== null && childContextTypes !== undefined) {
22609 popContext(interruptedWork);
22610 }
22611
22612 break;
22613 }
22614
22615 case HostRoot:
22616 {
22617
22618 popHostContainer(interruptedWork);
22619 popTopLevelContextObject(interruptedWork);
22620 resetWorkInProgressVersions();
22621 break;
22622 }
22623
22624 case HostComponent:
22625 {
22626 popHostContext(interruptedWork);
22627 break;
22628 }
22629
22630 case HostPortal:
22631 popHostContainer(interruptedWork);
22632 break;
22633
22634 case SuspenseComponent:
22635 popSuspenseContext(interruptedWork);
22636 break;
22637
22638 case SuspenseListComponent:
22639 popSuspenseContext(interruptedWork);
22640 break;
22641
22642 case ContextProvider:
22643 var context = interruptedWork.type._context;
22644 popProvider(context, interruptedWork);
22645 break;
22646
22647 case OffscreenComponent:
22648 case LegacyHiddenComponent:
22649 popRenderLanes(interruptedWork);
22650
22651 break;
22652 }
22653 }
22654
22655 var didWarnAboutUndefinedSnapshotBeforeUpdate = null;
22656
22657 {
22658 didWarnAboutUndefinedSnapshotBeforeUpdate = new Set();
22659 } // Used during the commit phase to track the state of the Offscreen component stack.
22660 // Allows us to avoid traversing the return path to find the nearest Offscreen ancestor.
22661 // Only used when enableSuspenseLayoutEffectSemantics is enabled.
22662
22663
22664 var offscreenSubtreeIsHidden = false;
22665 var offscreenSubtreeWasHidden = false;
22666 var PossiblyWeakSet = typeof WeakSet === 'function' ? WeakSet : Set;
22667 var nextEffect = null; // Used for Profiling builds to track updaters.
22668
22669 var inProgressLanes = null;
22670 var inProgressRoot = null;
22671
22672 function reportUncaughtErrorInDEV(error) {
22673 // Wrapping each small part of the commit phase into a guarded
22674 // callback is a bit too slow (https://github.com/facebook/react/pull/21666).
22675 // But we rely on it to surface errors to DEV tools like overlays
22676 // (https://github.com/facebook/react/issues/21712).
22677 // As a compromise, rethrow only caught errors in a guard.
22678 {
22679 invokeGuardedCallback(null, function () {
22680 throw error;
22681 });
22682 clearCaughtError();
22683 }
22684 }
22685
22686 var callComponentWillUnmountWithTimer = function (current, instance) {
22687 instance.props = current.memoizedProps;
22688 instance.state = current.memoizedState;
22689
22690 if ( current.mode & ProfileMode) {
22691 try {
22692 startLayoutEffectTimer();
22693 instance.componentWillUnmount();
22694 } finally {
22695 recordLayoutEffectDuration(current);
22696 }
22697 } else {
22698 instance.componentWillUnmount();
22699 }
22700 }; // Capture errors so they don't interrupt mounting.
22701
22702
22703 function safelyCallCommitHookLayoutEffectListMount(current, nearestMountedAncestor) {
22704 try {
22705 commitHookEffectListMount(Layout, current);
22706 } catch (error) {
22707 reportUncaughtErrorInDEV(error);
22708 captureCommitPhaseError(current, nearestMountedAncestor, error);
22709 }
22710 } // Capture errors so they don't interrupt unmounting.
22711
22712
22713 function safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance) {
22714 try {
22715 callComponentWillUnmountWithTimer(current, instance);
22716 } catch (error) {
22717 reportUncaughtErrorInDEV(error);
22718 captureCommitPhaseError(current, nearestMountedAncestor, error);
22719 }
22720 } // Capture errors so they don't interrupt mounting.
22721
22722
22723 function safelyCallComponentDidMount(current, nearestMountedAncestor, instance) {
22724 try {
22725 instance.componentDidMount();
22726 } catch (error) {
22727 reportUncaughtErrorInDEV(error);
22728 captureCommitPhaseError(current, nearestMountedAncestor, error);
22729 }
22730 } // Capture errors so they don't interrupt mounting.
22731
22732
22733 function safelyAttachRef(current, nearestMountedAncestor) {
22734 try {
22735 commitAttachRef(current);
22736 } catch (error) {
22737 reportUncaughtErrorInDEV(error);
22738 captureCommitPhaseError(current, nearestMountedAncestor, error);
22739 }
22740 }
22741
22742 function safelyDetachRef(current, nearestMountedAncestor) {
22743 var ref = current.ref;
22744
22745 if (ref !== null) {
22746 if (typeof ref === 'function') {
22747 var retVal;
22748
22749 try {
22750 if (enableProfilerTimer && enableProfilerCommitHooks && current.mode & ProfileMode) {
22751 try {
22752 startLayoutEffectTimer();
22753 retVal = ref(null);
22754 } finally {
22755 recordLayoutEffectDuration(current);
22756 }
22757 } else {
22758 retVal = ref(null);
22759 }
22760 } catch (error) {
22761 reportUncaughtErrorInDEV(error);
22762 captureCommitPhaseError(current, nearestMountedAncestor, error);
22763 }
22764
22765 {
22766 if (typeof retVal === 'function') {
22767 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(current));
22768 }
22769 }
22770 } else {
22771 ref.current = null;
22772 }
22773 }
22774 }
22775
22776 function safelyCallDestroy(current, nearestMountedAncestor, destroy) {
22777 try {
22778 destroy();
22779 } catch (error) {
22780 reportUncaughtErrorInDEV(error);
22781 captureCommitPhaseError(current, nearestMountedAncestor, error);
22782 }
22783 }
22784
22785 var focusedInstanceHandle = null;
22786 var shouldFireAfterActiveInstanceBlur = false;
22787 function commitBeforeMutationEffects(root, firstChild) {
22788 focusedInstanceHandle = prepareForCommit(root.containerInfo);
22789 nextEffect = firstChild;
22790 commitBeforeMutationEffects_begin(); // We no longer need to track the active instance fiber
22791
22792 var shouldFire = shouldFireAfterActiveInstanceBlur;
22793 shouldFireAfterActiveInstanceBlur = false;
22794 focusedInstanceHandle = null;
22795 return shouldFire;
22796 }
22797
22798 function commitBeforeMutationEffects_begin() {
22799 while (nextEffect !== null) {
22800 var fiber = nextEffect; // This phase is only used for beforeActiveInstanceBlur.
22801
22802 var child = fiber.child;
22803
22804 if ((fiber.subtreeFlags & BeforeMutationMask) !== NoFlags && child !== null) {
22805 ensureCorrectReturnPointer(child, fiber);
22806 nextEffect = child;
22807 } else {
22808 commitBeforeMutationEffects_complete();
22809 }
22810 }
22811 }
22812
22813 function commitBeforeMutationEffects_complete() {
22814 while (nextEffect !== null) {
22815 var fiber = nextEffect;
22816 setCurrentFiber(fiber);
22817
22818 try {
22819 commitBeforeMutationEffectsOnFiber(fiber);
22820 } catch (error) {
22821 reportUncaughtErrorInDEV(error);
22822 captureCommitPhaseError(fiber, fiber.return, error);
22823 }
22824
22825 resetCurrentFiber();
22826 var sibling = fiber.sibling;
22827
22828 if (sibling !== null) {
22829 ensureCorrectReturnPointer(sibling, fiber.return);
22830 nextEffect = sibling;
22831 return;
22832 }
22833
22834 nextEffect = fiber.return;
22835 }
22836 }
22837
22838 function commitBeforeMutationEffectsOnFiber(finishedWork) {
22839 var current = finishedWork.alternate;
22840 var flags = finishedWork.flags;
22841
22842 if ((flags & Snapshot) !== NoFlags) {
22843 setCurrentFiber(finishedWork);
22844
22845 switch (finishedWork.tag) {
22846 case FunctionComponent:
22847 case ForwardRef:
22848 case SimpleMemoComponent:
22849 {
22850 break;
22851 }
22852
22853 case ClassComponent:
22854 {
22855 if (current !== null) {
22856 var prevProps = current.memoizedProps;
22857 var prevState = current.memoizedState;
22858 var instance = finishedWork.stateNode; // We could update instance props and state here,
22859 // but instead we rely on them being set during last render.
22860 // TODO: revisit this when we implement resuming.
22861
22862 {
22863 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
22864 if (instance.props !== finishedWork.memoizedProps) {
22865 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');
22866 }
22867
22868 if (instance.state !== finishedWork.memoizedState) {
22869 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');
22870 }
22871 }
22872 }
22873
22874 var snapshot = instance.getSnapshotBeforeUpdate(finishedWork.elementType === finishedWork.type ? prevProps : resolveDefaultProps(finishedWork.type, prevProps), prevState);
22875
22876 {
22877 var didWarnSet = didWarnAboutUndefinedSnapshotBeforeUpdate;
22878
22879 if (snapshot === undefined && !didWarnSet.has(finishedWork.type)) {
22880 didWarnSet.add(finishedWork.type);
22881
22882 error('%s.getSnapshotBeforeUpdate(): A snapshot value (or null) ' + 'must be returned. You have returned undefined.', getComponentNameFromFiber(finishedWork));
22883 }
22884 }
22885
22886 instance.__reactInternalSnapshotBeforeUpdate = snapshot;
22887 }
22888
22889 break;
22890 }
22891
22892 case HostRoot:
22893 {
22894 {
22895 var root = finishedWork.stateNode;
22896 clearContainer(root.containerInfo);
22897 }
22898
22899 break;
22900 }
22901
22902 case HostComponent:
22903 case HostText:
22904 case HostPortal:
22905 case IncompleteClassComponent:
22906 // Nothing to do for these component types
22907 break;
22908
22909 default:
22910 {
22911 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.');
22912 }
22913 }
22914
22915 resetCurrentFiber();
22916 }
22917 }
22918
22919 function commitHookEffectListUnmount(flags, finishedWork, nearestMountedAncestor) {
22920 var updateQueue = finishedWork.updateQueue;
22921 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
22922
22923 if (lastEffect !== null) {
22924 var firstEffect = lastEffect.next;
22925 var effect = firstEffect;
22926
22927 do {
22928 if ((effect.tag & flags) === flags) {
22929 // Unmount
22930 var destroy = effect.destroy;
22931 effect.destroy = undefined;
22932
22933 if (destroy !== undefined) {
22934 {
22935 if ((flags & Passive$1) !== NoFlags$1) {
22936 markComponentPassiveEffectUnmountStarted(finishedWork);
22937 } else if ((flags & Layout) !== NoFlags$1) {
22938 markComponentLayoutEffectUnmountStarted(finishedWork);
22939 }
22940 }
22941
22942 safelyCallDestroy(finishedWork, nearestMountedAncestor, destroy);
22943
22944 {
22945 if ((flags & Passive$1) !== NoFlags$1) {
22946 markComponentPassiveEffectUnmountStopped();
22947 } else if ((flags & Layout) !== NoFlags$1) {
22948 markComponentLayoutEffectUnmountStopped();
22949 }
22950 }
22951 }
22952 }
22953
22954 effect = effect.next;
22955 } while (effect !== firstEffect);
22956 }
22957 }
22958
22959 function commitHookEffectListMount(flags, finishedWork) {
22960 var updateQueue = finishedWork.updateQueue;
22961 var lastEffect = updateQueue !== null ? updateQueue.lastEffect : null;
22962
22963 if (lastEffect !== null) {
22964 var firstEffect = lastEffect.next;
22965 var effect = firstEffect;
22966
22967 do {
22968 if ((effect.tag & flags) === flags) {
22969 {
22970 if ((flags & Passive$1) !== NoFlags$1) {
22971 markComponentPassiveEffectMountStarted(finishedWork);
22972 } else if ((flags & Layout) !== NoFlags$1) {
22973 markComponentLayoutEffectMountStarted(finishedWork);
22974 }
22975 } // Mount
22976
22977
22978 var create = effect.create;
22979 effect.destroy = create();
22980
22981 {
22982 if ((flags & Passive$1) !== NoFlags$1) {
22983 markComponentPassiveEffectMountStopped();
22984 } else if ((flags & Layout) !== NoFlags$1) {
22985 markComponentLayoutEffectMountStopped();
22986 }
22987 }
22988
22989 {
22990 var destroy = effect.destroy;
22991
22992 if (destroy !== undefined && typeof destroy !== 'function') {
22993 var hookName = void 0;
22994
22995 if ((effect.tag & Layout) !== NoFlags) {
22996 hookName = 'useLayoutEffect';
22997 } else if ((effect.tag & Insertion) !== NoFlags) {
22998 hookName = 'useInsertionEffect';
22999 } else {
23000 hookName = 'useEffect';
23001 }
23002
23003 var addendum = void 0;
23004
23005 if (destroy === null) {
23006 addendum = ' You returned null. If your effect does not require clean ' + 'up, return undefined (or nothing).';
23007 } else if (typeof destroy.then === 'function') {
23008 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';
23009 } else {
23010 addendum = ' You returned: ' + destroy;
23011 }
23012
23013 error('%s must not return anything besides a function, ' + 'which is used for clean-up.%s', hookName, addendum);
23014 }
23015 }
23016 }
23017
23018 effect = effect.next;
23019 } while (effect !== firstEffect);
23020 }
23021 }
23022
23023 function commitPassiveEffectDurations(finishedRoot, finishedWork) {
23024 {
23025 // Only Profilers with work in their subtree will have an Update effect scheduled.
23026 if ((finishedWork.flags & Update) !== NoFlags) {
23027 switch (finishedWork.tag) {
23028 case Profiler:
23029 {
23030 var passiveEffectDuration = finishedWork.stateNode.passiveEffectDuration;
23031 var _finishedWork$memoize = finishedWork.memoizedProps,
23032 id = _finishedWork$memoize.id,
23033 onPostCommit = _finishedWork$memoize.onPostCommit; // This value will still reflect the previous commit phase.
23034 // It does not get reset until the start of the next commit phase.
23035
23036 var commitTime = getCommitTime();
23037 var phase = finishedWork.alternate === null ? 'mount' : 'update';
23038
23039 {
23040 if (isCurrentUpdateNested()) {
23041 phase = 'nested-update';
23042 }
23043 }
23044
23045 if (typeof onPostCommit === 'function') {
23046 onPostCommit(id, phase, passiveEffectDuration, commitTime);
23047 } // Bubble times to the next nearest ancestor Profiler.
23048 // After we process that Profiler, we'll bubble further up.
23049
23050
23051 var parentFiber = finishedWork.return;
23052
23053 outer: while (parentFiber !== null) {
23054 switch (parentFiber.tag) {
23055 case HostRoot:
23056 var root = parentFiber.stateNode;
23057 root.passiveEffectDuration += passiveEffectDuration;
23058 break outer;
23059
23060 case Profiler:
23061 var parentStateNode = parentFiber.stateNode;
23062 parentStateNode.passiveEffectDuration += passiveEffectDuration;
23063 break outer;
23064 }
23065
23066 parentFiber = parentFiber.return;
23067 }
23068
23069 break;
23070 }
23071 }
23072 }
23073 }
23074 }
23075
23076 function commitLayoutEffectOnFiber(finishedRoot, current, finishedWork, committedLanes) {
23077 if ((finishedWork.flags & LayoutMask) !== NoFlags) {
23078 switch (finishedWork.tag) {
23079 case FunctionComponent:
23080 case ForwardRef:
23081 case SimpleMemoComponent:
23082 {
23083 if ( !offscreenSubtreeWasHidden) {
23084 // At this point layout effects have already been destroyed (during mutation phase).
23085 // This is done to prevent sibling component effects from interfering with each other,
23086 // e.g. a destroy function in one component should never override a ref set
23087 // by a create function in another component during the same commit.
23088 if ( finishedWork.mode & ProfileMode) {
23089 try {
23090 startLayoutEffectTimer();
23091 commitHookEffectListMount(Layout | HasEffect, finishedWork);
23092 } finally {
23093 recordLayoutEffectDuration(finishedWork);
23094 }
23095 } else {
23096 commitHookEffectListMount(Layout | HasEffect, finishedWork);
23097 }
23098 }
23099
23100 break;
23101 }
23102
23103 case ClassComponent:
23104 {
23105 var instance = finishedWork.stateNode;
23106
23107 if (finishedWork.flags & Update) {
23108 if (!offscreenSubtreeWasHidden) {
23109 if (current === null) {
23110 // We could update instance props and state here,
23111 // but instead we rely on them being set during last render.
23112 // TODO: revisit this when we implement resuming.
23113 {
23114 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23115 if (instance.props !== finishedWork.memoizedProps) {
23116 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');
23117 }
23118
23119 if (instance.state !== finishedWork.memoizedState) {
23120 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');
23121 }
23122 }
23123 }
23124
23125 if ( finishedWork.mode & ProfileMode) {
23126 try {
23127 startLayoutEffectTimer();
23128 instance.componentDidMount();
23129 } finally {
23130 recordLayoutEffectDuration(finishedWork);
23131 }
23132 } else {
23133 instance.componentDidMount();
23134 }
23135 } else {
23136 var prevProps = finishedWork.elementType === finishedWork.type ? current.memoizedProps : resolveDefaultProps(finishedWork.type, current.memoizedProps);
23137 var prevState = current.memoizedState; // We could update instance props and state here,
23138 // but instead we rely on them being set during last render.
23139 // TODO: revisit this when we implement resuming.
23140
23141 {
23142 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23143 if (instance.props !== finishedWork.memoizedProps) {
23144 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');
23145 }
23146
23147 if (instance.state !== finishedWork.memoizedState) {
23148 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');
23149 }
23150 }
23151 }
23152
23153 if ( finishedWork.mode & ProfileMode) {
23154 try {
23155 startLayoutEffectTimer();
23156 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
23157 } finally {
23158 recordLayoutEffectDuration(finishedWork);
23159 }
23160 } else {
23161 instance.componentDidUpdate(prevProps, prevState, instance.__reactInternalSnapshotBeforeUpdate);
23162 }
23163 }
23164 }
23165 } // TODO: I think this is now always non-null by the time it reaches the
23166 // commit phase. Consider removing the type check.
23167
23168
23169 var updateQueue = finishedWork.updateQueue;
23170
23171 if (updateQueue !== null) {
23172 {
23173 if (finishedWork.type === finishedWork.elementType && !didWarnAboutReassigningProps) {
23174 if (instance.props !== finishedWork.memoizedProps) {
23175 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');
23176 }
23177
23178 if (instance.state !== finishedWork.memoizedState) {
23179 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');
23180 }
23181 }
23182 } // We could update instance props and state here,
23183 // but instead we rely on them being set during last render.
23184 // TODO: revisit this when we implement resuming.
23185
23186
23187 commitUpdateQueue(finishedWork, updateQueue, instance);
23188 }
23189
23190 break;
23191 }
23192
23193 case HostRoot:
23194 {
23195 // TODO: I think this is now always non-null by the time it reaches the
23196 // commit phase. Consider removing the type check.
23197 var _updateQueue = finishedWork.updateQueue;
23198
23199 if (_updateQueue !== null) {
23200 var _instance = null;
23201
23202 if (finishedWork.child !== null) {
23203 switch (finishedWork.child.tag) {
23204 case HostComponent:
23205 _instance = getPublicInstance(finishedWork.child.stateNode);
23206 break;
23207
23208 case ClassComponent:
23209 _instance = finishedWork.child.stateNode;
23210 break;
23211 }
23212 }
23213
23214 commitUpdateQueue(finishedWork, _updateQueue, _instance);
23215 }
23216
23217 break;
23218 }
23219
23220 case HostComponent:
23221 {
23222 var _instance2 = finishedWork.stateNode; // Renderers may schedule work to be done after host components are mounted
23223 // (eg DOM renderer may schedule auto-focus for inputs and form controls).
23224 // These effects should only be committed when components are first mounted,
23225 // aka when there is no current/alternate.
23226
23227 if (current === null && finishedWork.flags & Update) {
23228 var type = finishedWork.type;
23229 var props = finishedWork.memoizedProps;
23230 commitMount(_instance2, type, props);
23231 }
23232
23233 break;
23234 }
23235
23236 case HostText:
23237 {
23238 // We have no life-cycles associated with text.
23239 break;
23240 }
23241
23242 case HostPortal:
23243 {
23244 // We have no life-cycles associated with portals.
23245 break;
23246 }
23247
23248 case Profiler:
23249 {
23250 {
23251 var _finishedWork$memoize2 = finishedWork.memoizedProps,
23252 onCommit = _finishedWork$memoize2.onCommit,
23253 onRender = _finishedWork$memoize2.onRender;
23254 var effectDuration = finishedWork.stateNode.effectDuration;
23255 var commitTime = getCommitTime();
23256 var phase = current === null ? 'mount' : 'update';
23257
23258 {
23259 if (isCurrentUpdateNested()) {
23260 phase = 'nested-update';
23261 }
23262 }
23263
23264 if (typeof onRender === 'function') {
23265 onRender(finishedWork.memoizedProps.id, phase, finishedWork.actualDuration, finishedWork.treeBaseDuration, finishedWork.actualStartTime, commitTime);
23266 }
23267
23268 {
23269 if (typeof onCommit === 'function') {
23270 onCommit(finishedWork.memoizedProps.id, phase, effectDuration, commitTime);
23271 } // Schedule a passive effect for this Profiler to call onPostCommit hooks.
23272 // This effect should be scheduled even if there is no onPostCommit callback for this Profiler,
23273 // because the effect is also where times bubble to parent Profilers.
23274
23275
23276 enqueuePendingPassiveProfilerEffect(finishedWork); // Propagate layout effect durations to the next nearest Profiler ancestor.
23277 // Do not reset these values until the next render so DevTools has a chance to read them first.
23278
23279 var parentFiber = finishedWork.return;
23280
23281 outer: while (parentFiber !== null) {
23282 switch (parentFiber.tag) {
23283 case HostRoot:
23284 var root = parentFiber.stateNode;
23285 root.effectDuration += effectDuration;
23286 break outer;
23287
23288 case Profiler:
23289 var parentStateNode = parentFiber.stateNode;
23290 parentStateNode.effectDuration += effectDuration;
23291 break outer;
23292 }
23293
23294 parentFiber = parentFiber.return;
23295 }
23296 }
23297 }
23298
23299 break;
23300 }
23301
23302 case SuspenseComponent:
23303 {
23304 commitSuspenseHydrationCallbacks(finishedRoot, finishedWork);
23305 break;
23306 }
23307
23308 case SuspenseListComponent:
23309 case IncompleteClassComponent:
23310 case ScopeComponent:
23311 case OffscreenComponent:
23312 case LegacyHiddenComponent:
23313 {
23314 break;
23315 }
23316
23317 default:
23318 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.');
23319 }
23320 }
23321
23322 if ( !offscreenSubtreeWasHidden) {
23323 {
23324 if (finishedWork.flags & Ref) {
23325 commitAttachRef(finishedWork);
23326 }
23327 }
23328 }
23329 }
23330
23331 function reappearLayoutEffectsOnFiber(node) {
23332 // Turn on layout effects in a tree that previously disappeared.
23333 // TODO (Offscreen) Check: flags & LayoutStatic
23334 switch (node.tag) {
23335 case FunctionComponent:
23336 case ForwardRef:
23337 case SimpleMemoComponent:
23338 {
23339 if ( node.mode & ProfileMode) {
23340 try {
23341 startLayoutEffectTimer();
23342 safelyCallCommitHookLayoutEffectListMount(node, node.return);
23343 } finally {
23344 recordLayoutEffectDuration(node);
23345 }
23346 } else {
23347 safelyCallCommitHookLayoutEffectListMount(node, node.return);
23348 }
23349
23350 break;
23351 }
23352
23353 case ClassComponent:
23354 {
23355 var instance = node.stateNode;
23356
23357 if (typeof instance.componentDidMount === 'function') {
23358 safelyCallComponentDidMount(node, node.return, instance);
23359 }
23360
23361 safelyAttachRef(node, node.return);
23362 break;
23363 }
23364
23365 case HostComponent:
23366 {
23367 safelyAttachRef(node, node.return);
23368 break;
23369 }
23370 }
23371 }
23372
23373 function hideOrUnhideAllChildren(finishedWork, isHidden) {
23374 // Only hide or unhide the top-most host nodes.
23375 var hostSubtreeRoot = null;
23376
23377 {
23378 // We only have the top Fiber that was inserted but we need to recurse down its
23379 // children to find all the terminal nodes.
23380 var node = finishedWork;
23381
23382 while (true) {
23383 if (node.tag === HostComponent) {
23384 if (hostSubtreeRoot === null) {
23385 hostSubtreeRoot = node;
23386 var instance = node.stateNode;
23387
23388 if (isHidden) {
23389 hideInstance(instance);
23390 } else {
23391 unhideInstance(node.stateNode, node.memoizedProps);
23392 }
23393 }
23394 } else if (node.tag === HostText) {
23395 if (hostSubtreeRoot === null) {
23396 var _instance3 = node.stateNode;
23397
23398 if (isHidden) {
23399 hideTextInstance(_instance3);
23400 } else {
23401 unhideTextInstance(_instance3, node.memoizedProps);
23402 }
23403 }
23404 } else if ((node.tag === OffscreenComponent || node.tag === LegacyHiddenComponent) && node.memoizedState !== null && node !== finishedWork) ; else if (node.child !== null) {
23405 node.child.return = node;
23406 node = node.child;
23407 continue;
23408 }
23409
23410 if (node === finishedWork) {
23411 return;
23412 }
23413
23414 while (node.sibling === null) {
23415 if (node.return === null || node.return === finishedWork) {
23416 return;
23417 }
23418
23419 if (hostSubtreeRoot === node) {
23420 hostSubtreeRoot = null;
23421 }
23422
23423 node = node.return;
23424 }
23425
23426 if (hostSubtreeRoot === node) {
23427 hostSubtreeRoot = null;
23428 }
23429
23430 node.sibling.return = node.return;
23431 node = node.sibling;
23432 }
23433 }
23434 }
23435
23436 function commitAttachRef(finishedWork) {
23437 var ref = finishedWork.ref;
23438
23439 if (ref !== null) {
23440 var instance = finishedWork.stateNode;
23441 var instanceToUse;
23442
23443 switch (finishedWork.tag) {
23444 case HostComponent:
23445 instanceToUse = getPublicInstance(instance);
23446 break;
23447
23448 default:
23449 instanceToUse = instance;
23450 } // Moved outside to ensure DCE works with this flag
23451
23452 if (typeof ref === 'function') {
23453 var retVal;
23454
23455 if ( finishedWork.mode & ProfileMode) {
23456 try {
23457 startLayoutEffectTimer();
23458 retVal = ref(instanceToUse);
23459 } finally {
23460 recordLayoutEffectDuration(finishedWork);
23461 }
23462 } else {
23463 retVal = ref(instanceToUse);
23464 }
23465
23466 {
23467 if (typeof retVal === 'function') {
23468 error('Unexpected return value from a callback ref in %s. ' + 'A callback ref should not return a function.', getComponentNameFromFiber(finishedWork));
23469 }
23470 }
23471 } else {
23472 {
23473 if (!ref.hasOwnProperty('current')) {
23474 error('Unexpected ref object provided for %s. ' + 'Use either a ref-setter function or React.createRef().', getComponentNameFromFiber(finishedWork));
23475 }
23476 }
23477
23478 ref.current = instanceToUse;
23479 }
23480 }
23481 }
23482
23483 function commitDetachRef(current) {
23484 var currentRef = current.ref;
23485
23486 if (currentRef !== null) {
23487 if (typeof currentRef === 'function') {
23488 if ( current.mode & ProfileMode) {
23489 try {
23490 startLayoutEffectTimer();
23491 currentRef(null);
23492 } finally {
23493 recordLayoutEffectDuration(current);
23494 }
23495 } else {
23496 currentRef(null);
23497 }
23498 } else {
23499 currentRef.current = null;
23500 }
23501 }
23502 } // User-originating errors (lifecycles and refs) should not interrupt
23503 // deletion, so don't let them throw. Host-originating errors should
23504 // interrupt deletion, so it's okay
23505
23506
23507 function commitUnmount(finishedRoot, current, nearestMountedAncestor) {
23508 onCommitUnmount(current);
23509
23510 switch (current.tag) {
23511 case FunctionComponent:
23512 case ForwardRef:
23513 case MemoComponent:
23514 case SimpleMemoComponent:
23515 {
23516 var updateQueue = current.updateQueue;
23517
23518 if (updateQueue !== null) {
23519 var lastEffect = updateQueue.lastEffect;
23520
23521 if (lastEffect !== null) {
23522 var firstEffect = lastEffect.next;
23523 var effect = firstEffect;
23524
23525 do {
23526 var _effect = effect,
23527 destroy = _effect.destroy,
23528 tag = _effect.tag;
23529
23530 if (destroy !== undefined) {
23531 if ((tag & Insertion) !== NoFlags$1) {
23532 safelyCallDestroy(current, nearestMountedAncestor, destroy);
23533 } else if ((tag & Layout) !== NoFlags$1) {
23534 {
23535 markComponentLayoutEffectUnmountStarted(current);
23536 }
23537
23538 if ( current.mode & ProfileMode) {
23539 startLayoutEffectTimer();
23540 safelyCallDestroy(current, nearestMountedAncestor, destroy);
23541 recordLayoutEffectDuration(current);
23542 } else {
23543 safelyCallDestroy(current, nearestMountedAncestor, destroy);
23544 }
23545
23546 {
23547 markComponentLayoutEffectUnmountStopped();
23548 }
23549 }
23550 }
23551
23552 effect = effect.next;
23553 } while (effect !== firstEffect);
23554 }
23555 }
23556
23557 return;
23558 }
23559
23560 case ClassComponent:
23561 {
23562 safelyDetachRef(current, nearestMountedAncestor);
23563 var instance = current.stateNode;
23564
23565 if (typeof instance.componentWillUnmount === 'function') {
23566 safelyCallComponentWillUnmount(current, nearestMountedAncestor, instance);
23567 }
23568
23569 return;
23570 }
23571
23572 case HostComponent:
23573 {
23574 safelyDetachRef(current, nearestMountedAncestor);
23575 return;
23576 }
23577
23578 case HostPortal:
23579 {
23580 // TODO: this is recursive.
23581 // We are also not using this parent because
23582 // the portal will get pushed immediately.
23583 {
23584 unmountHostComponents(finishedRoot, current, nearestMountedAncestor);
23585 }
23586
23587 return;
23588 }
23589
23590 case DehydratedFragment:
23591 {
23592
23593 return;
23594 }
23595
23596 case ScopeComponent:
23597 {
23598
23599 return;
23600 }
23601 }
23602 }
23603
23604 function commitNestedUnmounts(finishedRoot, root, nearestMountedAncestor) {
23605 // While we're inside a removed host node we don't want to call
23606 // removeChild on the inner nodes because they're removed by the top
23607 // call anyway. We also want to call componentWillUnmount on all
23608 // composites before this host node is removed from the tree. Therefore
23609 // we do an inner loop while we're still inside the host node.
23610 var node = root;
23611
23612 while (true) {
23613 commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because they may contain more composite or host nodes.
23614 // Skip portals because commitUnmount() currently visits them recursively.
23615
23616 if (node.child !== null && ( // If we use mutation we drill down into portals using commitUnmount above.
23617 // If we don't use mutation we drill down into portals here instead.
23618 node.tag !== HostPortal)) {
23619 node.child.return = node;
23620 node = node.child;
23621 continue;
23622 }
23623
23624 if (node === root) {
23625 return;
23626 }
23627
23628 while (node.sibling === null) {
23629 if (node.return === null || node.return === root) {
23630 return;
23631 }
23632
23633 node = node.return;
23634 }
23635
23636 node.sibling.return = node.return;
23637 node = node.sibling;
23638 }
23639 }
23640
23641 function detachFiberMutation(fiber) {
23642 // Cut off the return pointer to disconnect it from the tree.
23643 // This enables us to detect and warn against state updates on an unmounted component.
23644 // It also prevents events from bubbling from within disconnected components.
23645 //
23646 // Ideally, we should also clear the child pointer of the parent alternate to let this
23647 // get GC:ed but we don't know which for sure which parent is the current
23648 // one so we'll settle for GC:ing the subtree of this child.
23649 // This child itself will be GC:ed when the parent updates the next time.
23650 //
23651 // Note that we can't clear child or sibling pointers yet.
23652 // They're needed for passive effects and for findDOMNode.
23653 // We defer those fields, and all other cleanup, to the passive phase (see detachFiberAfterEffects).
23654 //
23655 // Don't reset the alternate yet, either. We need that so we can detach the
23656 // alternate's fields in the passive phase. Clearing the return pointer is
23657 // sufficient for findDOMNode semantics.
23658 var alternate = fiber.alternate;
23659
23660 if (alternate !== null) {
23661 alternate.return = null;
23662 }
23663
23664 fiber.return = null;
23665 }
23666
23667 function detachFiberAfterEffects(fiber) {
23668 var alternate = fiber.alternate;
23669
23670 if (alternate !== null) {
23671 fiber.alternate = null;
23672 detachFiberAfterEffects(alternate);
23673 } // Note: Defensively using negation instead of < in case
23674 // `deletedTreeCleanUpLevel` is undefined.
23675
23676
23677 {
23678 // Clear cyclical Fiber fields. This level alone is designed to roughly
23679 // approximate the planned Fiber refactor. In that world, `setState` will be
23680 // bound to a special "instance" object instead of a Fiber. The Instance
23681 // object will not have any of these fields. It will only be connected to
23682 // the fiber tree via a single link at the root. So if this level alone is
23683 // sufficient to fix memory issues, that bodes well for our plans.
23684 fiber.child = null;
23685 fiber.deletions = null;
23686 fiber.sibling = null; // The `stateNode` is cyclical because on host nodes it points to the host
23687 // tree, which has its own pointers to children, parents, and siblings.
23688 // The other host nodes also point back to fibers, so we should detach that
23689 // one, too.
23690
23691 if (fiber.tag === HostComponent) {
23692 var hostInstance = fiber.stateNode;
23693
23694 if (hostInstance !== null) {
23695 detachDeletedInstance(hostInstance);
23696 }
23697 }
23698
23699 fiber.stateNode = null; // I'm intentionally not clearing the `return` field in this level. We
23700 // already disconnect the `return` pointer at the root of the deleted
23701 // subtree (in `detachFiberMutation`). Besides, `return` by itself is not
23702 // cyclical — it's only cyclical when combined with `child`, `sibling`, and
23703 // `alternate`. But we'll clear it in the next level anyway, just in case.
23704
23705 {
23706 fiber._debugOwner = null;
23707 }
23708
23709 {
23710 // Theoretically, nothing in here should be necessary, because we already
23711 // disconnected the fiber from the tree. So even if something leaks this
23712 // particular fiber, it won't leak anything else
23713 //
23714 // The purpose of this branch is to be super aggressive so we can measure
23715 // if there's any difference in memory impact. If there is, that could
23716 // indicate a React leak we don't know about.
23717 fiber.return = null;
23718 fiber.dependencies = null;
23719 fiber.memoizedProps = null;
23720 fiber.memoizedState = null;
23721 fiber.pendingProps = null;
23722 fiber.stateNode = null; // TODO: Move to `commitPassiveUnmountInsideDeletedTreeOnFiber` instead.
23723
23724 fiber.updateQueue = null;
23725 }
23726 }
23727 }
23728
23729 function getHostParentFiber(fiber) {
23730 var parent = fiber.return;
23731
23732 while (parent !== null) {
23733 if (isHostParent(parent)) {
23734 return parent;
23735 }
23736
23737 parent = parent.return;
23738 }
23739
23740 throw new Error('Expected to find a host parent. This error is likely caused by a bug ' + 'in React. Please file an issue.');
23741 }
23742
23743 function isHostParent(fiber) {
23744 return fiber.tag === HostComponent || fiber.tag === HostRoot || fiber.tag === HostPortal;
23745 }
23746
23747 function getHostSibling(fiber) {
23748 // We're going to search forward into the tree until we find a sibling host
23749 // node. Unfortunately, if multiple insertions are done in a row we have to
23750 // search past them. This leads to exponential search for the next sibling.
23751 // TODO: Find a more efficient way to do this.
23752 var node = fiber;
23753
23754 siblings: while (true) {
23755 // If we didn't find anything, let's try the next sibling.
23756 while (node.sibling === null) {
23757 if (node.return === null || isHostParent(node.return)) {
23758 // If we pop out of the root or hit the parent the fiber we are the
23759 // last sibling.
23760 return null;
23761 }
23762
23763 node = node.return;
23764 }
23765
23766 node.sibling.return = node.return;
23767 node = node.sibling;
23768
23769 while (node.tag !== HostComponent && node.tag !== HostText && node.tag !== DehydratedFragment) {
23770 // If it is not host node and, we might have a host node inside it.
23771 // Try to search down until we find one.
23772 if (node.flags & Placement) {
23773 // If we don't have a child, try the siblings instead.
23774 continue siblings;
23775 } // If we don't have a child, try the siblings instead.
23776 // We also skip portals because they are not part of this host tree.
23777
23778
23779 if (node.child === null || node.tag === HostPortal) {
23780 continue siblings;
23781 } else {
23782 node.child.return = node;
23783 node = node.child;
23784 }
23785 } // Check if this host node is stable or about to be placed.
23786
23787
23788 if (!(node.flags & Placement)) {
23789 // Found it!
23790 return node.stateNode;
23791 }
23792 }
23793 }
23794
23795 function commitPlacement(finishedWork) {
23796
23797
23798 var parentFiber = getHostParentFiber(finishedWork); // Note: these two variables *must* always be updated together.
23799
23800 switch (parentFiber.tag) {
23801 case HostComponent:
23802 {
23803 var parent = parentFiber.stateNode;
23804
23805 if (parentFiber.flags & ContentReset) {
23806 // Reset the text content of the parent before doing any insertions
23807 resetTextContent(parent); // Clear ContentReset from the effect tag
23808
23809 parentFiber.flags &= ~ContentReset;
23810 }
23811
23812 var before = getHostSibling(finishedWork); // We only have the top Fiber that was inserted but we need to recurse down its
23813 // children to find all the terminal nodes.
23814
23815 insertOrAppendPlacementNode(finishedWork, before, parent);
23816 break;
23817 }
23818
23819 case HostRoot:
23820 case HostPortal:
23821 {
23822 var _parent = parentFiber.stateNode.containerInfo;
23823
23824 var _before = getHostSibling(finishedWork);
23825
23826 insertOrAppendPlacementNodeIntoContainer(finishedWork, _before, _parent);
23827 break;
23828 }
23829 // eslint-disable-next-line-no-fallthrough
23830
23831 default:
23832 throw new Error('Invalid host parent fiber. This error is likely caused by a bug ' + 'in React. Please file an issue.');
23833 }
23834 }
23835
23836 function insertOrAppendPlacementNodeIntoContainer(node, before, parent) {
23837 var tag = node.tag;
23838 var isHost = tag === HostComponent || tag === HostText;
23839
23840 if (isHost) {
23841 var stateNode = node.stateNode;
23842
23843 if (before) {
23844 insertInContainerBefore(parent, stateNode, before);
23845 } else {
23846 appendChildToContainer(parent, stateNode);
23847 }
23848 } else if (tag === HostPortal) ; else {
23849 var child = node.child;
23850
23851 if (child !== null) {
23852 insertOrAppendPlacementNodeIntoContainer(child, before, parent);
23853 var sibling = child.sibling;
23854
23855 while (sibling !== null) {
23856 insertOrAppendPlacementNodeIntoContainer(sibling, before, parent);
23857 sibling = sibling.sibling;
23858 }
23859 }
23860 }
23861 }
23862
23863 function insertOrAppendPlacementNode(node, before, parent) {
23864 var tag = node.tag;
23865 var isHost = tag === HostComponent || tag === HostText;
23866
23867 if (isHost) {
23868 var stateNode = node.stateNode;
23869
23870 if (before) {
23871 insertBefore(parent, stateNode, before);
23872 } else {
23873 appendChild(parent, stateNode);
23874 }
23875 } else if (tag === HostPortal) ; else {
23876 var child = node.child;
23877
23878 if (child !== null) {
23879 insertOrAppendPlacementNode(child, before, parent);
23880 var sibling = child.sibling;
23881
23882 while (sibling !== null) {
23883 insertOrAppendPlacementNode(sibling, before, parent);
23884 sibling = sibling.sibling;
23885 }
23886 }
23887 }
23888 }
23889
23890 function unmountHostComponents(finishedRoot, current, nearestMountedAncestor) {
23891 // We only have the top Fiber that was deleted but we need to recurse down its
23892 // children to find all the terminal nodes.
23893 var node = current; // Each iteration, currentParent is populated with node's host parent if not
23894 // currentParentIsValid.
23895
23896 var currentParentIsValid = false; // Note: these two variables *must* always be updated together.
23897
23898 var currentParent;
23899 var currentParentIsContainer;
23900
23901 while (true) {
23902 if (!currentParentIsValid) {
23903 var parent = node.return;
23904
23905 findParent: while (true) {
23906 if (parent === null) {
23907 throw new Error('Expected to find a host parent. This error is likely caused by ' + 'a bug in React. Please file an issue.');
23908 }
23909
23910 var parentStateNode = parent.stateNode;
23911
23912 switch (parent.tag) {
23913 case HostComponent:
23914 currentParent = parentStateNode;
23915 currentParentIsContainer = false;
23916 break findParent;
23917
23918 case HostRoot:
23919 currentParent = parentStateNode.containerInfo;
23920 currentParentIsContainer = true;
23921 break findParent;
23922
23923 case HostPortal:
23924 currentParent = parentStateNode.containerInfo;
23925 currentParentIsContainer = true;
23926 break findParent;
23927 }
23928
23929 parent = parent.return;
23930 }
23931
23932 currentParentIsValid = true;
23933 }
23934
23935 if (node.tag === HostComponent || node.tag === HostText) {
23936 commitNestedUnmounts(finishedRoot, node, nearestMountedAncestor); // After all the children have unmounted, it is now safe to remove the
23937 // node from the tree.
23938
23939 if (currentParentIsContainer) {
23940 removeChildFromContainer(currentParent, node.stateNode);
23941 } else {
23942 removeChild(currentParent, node.stateNode);
23943 } // Don't visit children because we already visited them.
23944
23945 } else if ( node.tag === DehydratedFragment) {
23946
23947
23948 if (currentParentIsContainer) {
23949 clearSuspenseBoundaryFromContainer(currentParent, node.stateNode);
23950 } else {
23951 clearSuspenseBoundary(currentParent, node.stateNode);
23952 }
23953 } else if (node.tag === HostPortal) {
23954 if (node.child !== null) {
23955 // When we go into a portal, it becomes the parent to remove from.
23956 // We will reassign it back when we pop the portal on the way up.
23957 currentParent = node.stateNode.containerInfo;
23958 currentParentIsContainer = true; // Visit children because portals might contain host components.
23959
23960 node.child.return = node;
23961 node = node.child;
23962 continue;
23963 }
23964 } else {
23965 commitUnmount(finishedRoot, node, nearestMountedAncestor); // Visit children because we may find more host components below.
23966
23967 if (node.child !== null) {
23968 node.child.return = node;
23969 node = node.child;
23970 continue;
23971 }
23972 }
23973
23974 if (node === current) {
23975 return;
23976 }
23977
23978 while (node.sibling === null) {
23979 if (node.return === null || node.return === current) {
23980 return;
23981 }
23982
23983 node = node.return;
23984
23985 if (node.tag === HostPortal) {
23986 // When we go out of the portal, we need to restore the parent.
23987 // Since we don't keep a stack of them, we will search for it.
23988 currentParentIsValid = false;
23989 }
23990 }
23991
23992 node.sibling.return = node.return;
23993 node = node.sibling;
23994 }
23995 }
23996
23997 function commitDeletion(finishedRoot, current, nearestMountedAncestor) {
23998 {
23999 // Recursively delete all host nodes from the parent.
24000 // Detach refs and call componentWillUnmount() on the whole subtree.
24001 unmountHostComponents(finishedRoot, current, nearestMountedAncestor);
24002 }
24003
24004 detachFiberMutation(current);
24005 }
24006
24007 function commitWork(current, finishedWork) {
24008
24009 switch (finishedWork.tag) {
24010 case FunctionComponent:
24011 case ForwardRef:
24012 case MemoComponent:
24013 case SimpleMemoComponent:
24014 {
24015 commitHookEffectListUnmount(Insertion | HasEffect, finishedWork, finishedWork.return);
24016 commitHookEffectListMount(Insertion | HasEffect, finishedWork); // Layout effects are destroyed during the mutation phase so that all
24017 // destroy functions for all fibers are called before any create functions.
24018 // This prevents sibling component effects from interfering with each other,
24019 // e.g. a destroy function in one component should never override a ref set
24020 // by a create function in another component during the same commit.
24021
24022 if ( finishedWork.mode & ProfileMode) {
24023 try {
24024 startLayoutEffectTimer();
24025 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
24026 } finally {
24027 recordLayoutEffectDuration(finishedWork);
24028 }
24029 } else {
24030 commitHookEffectListUnmount(Layout | HasEffect, finishedWork, finishedWork.return);
24031 }
24032
24033 return;
24034 }
24035
24036 case ClassComponent:
24037 {
24038 return;
24039 }
24040
24041 case HostComponent:
24042 {
24043 var instance = finishedWork.stateNode;
24044
24045 if (instance != null) {
24046 // Commit the work prepared earlier.
24047 var newProps = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
24048 // as the newProps. The updatePayload will contain the real change in
24049 // this case.
24050
24051 var oldProps = current !== null ? current.memoizedProps : newProps;
24052 var type = finishedWork.type; // TODO: Type the updateQueue to be specific to host components.
24053
24054 var updatePayload = finishedWork.updateQueue;
24055 finishedWork.updateQueue = null;
24056
24057 if (updatePayload !== null) {
24058 commitUpdate(instance, updatePayload, type, oldProps, newProps);
24059 }
24060 }
24061
24062 return;
24063 }
24064
24065 case HostText:
24066 {
24067 if (finishedWork.stateNode === null) {
24068 throw new Error('This should have a text node initialized. This error is likely ' + 'caused by a bug in React. Please file an issue.');
24069 }
24070
24071 var textInstance = finishedWork.stateNode;
24072 var newText = finishedWork.memoizedProps; // For hydration we reuse the update path but we treat the oldProps
24073 // as the newProps. The updatePayload will contain the real change in
24074 // this case.
24075
24076 var oldText = current !== null ? current.memoizedProps : newText;
24077 commitTextUpdate(textInstance, oldText, newText);
24078 return;
24079 }
24080
24081 case HostRoot:
24082 {
24083 {
24084 if (current !== null) {
24085 var _prevRootState = current.memoizedState;
24086
24087 if (_prevRootState.isDehydrated) {
24088 var _root = finishedWork.stateNode;
24089 commitHydratedContainer(_root.containerInfo);
24090 }
24091 }
24092 }
24093
24094 return;
24095 }
24096
24097 case Profiler:
24098 {
24099 return;
24100 }
24101
24102 case SuspenseComponent:
24103 {
24104 commitSuspenseCallback(finishedWork);
24105 attachSuspenseRetryListeners(finishedWork);
24106 return;
24107 }
24108
24109 case SuspenseListComponent:
24110 {
24111 attachSuspenseRetryListeners(finishedWork);
24112 return;
24113 }
24114
24115 case IncompleteClassComponent:
24116 {
24117 return;
24118 }
24119 }
24120
24121 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.');
24122 }
24123
24124 function commitSuspenseCallback(finishedWork) {
24125 // TODO: Move this to passive phase
24126 var newState = finishedWork.memoizedState;
24127 }
24128
24129 function commitSuspenseHydrationCallbacks(finishedRoot, finishedWork) {
24130
24131 var newState = finishedWork.memoizedState;
24132
24133 if (newState === null) {
24134 var current = finishedWork.alternate;
24135
24136 if (current !== null) {
24137 var prevState = current.memoizedState;
24138
24139 if (prevState !== null) {
24140 var suspenseInstance = prevState.dehydrated;
24141
24142 if (suspenseInstance !== null) {
24143 commitHydratedSuspenseInstance(suspenseInstance);
24144 }
24145 }
24146 }
24147 }
24148 }
24149
24150 function attachSuspenseRetryListeners(finishedWork) {
24151 // If this boundary just timed out, then it will have a set of wakeables.
24152 // For each wakeable, attach a listener so that when it resolves, React
24153 // attempts to re-render the boundary in the primary (pre-timeout) state.
24154 var wakeables = finishedWork.updateQueue;
24155
24156 if (wakeables !== null) {
24157 finishedWork.updateQueue = null;
24158 var retryCache = finishedWork.stateNode;
24159
24160 if (retryCache === null) {
24161 retryCache = finishedWork.stateNode = new PossiblyWeakSet();
24162 }
24163
24164 wakeables.forEach(function (wakeable) {
24165 // Memoize using the boundary fiber to prevent redundant listeners.
24166 var retry = resolveRetryWakeable.bind(null, finishedWork, wakeable);
24167
24168 if (!retryCache.has(wakeable)) {
24169 retryCache.add(wakeable);
24170
24171 {
24172 if (isDevToolsPresent) {
24173 if (inProgressLanes !== null && inProgressRoot !== null) {
24174 // If we have pending work still, associate the original updaters with it.
24175 restorePendingUpdaters(inProgressRoot, inProgressLanes);
24176 } else {
24177 throw Error('Expected finished root and lanes to be set. This is a bug in React.');
24178 }
24179 }
24180 }
24181
24182 wakeable.then(retry, retry);
24183 }
24184 });
24185 }
24186 } // This function detects when a Suspense boundary goes from visible to hidden.
24187
24188 function commitResetTextContent(current) {
24189
24190 resetTextContent(current.stateNode);
24191 }
24192
24193 function commitMutationEffects(root, firstChild, committedLanes) {
24194 inProgressLanes = committedLanes;
24195 inProgressRoot = root;
24196 nextEffect = firstChild;
24197 commitMutationEffects_begin(root, committedLanes);
24198 inProgressLanes = null;
24199 inProgressRoot = null;
24200 }
24201
24202 function commitMutationEffects_begin(root, lanes) {
24203 while (nextEffect !== null) {
24204 var fiber = nextEffect; // TODO: Should wrap this in flags check, too, as optimization
24205
24206 var deletions = fiber.deletions;
24207
24208 if (deletions !== null) {
24209 for (var i = 0; i < deletions.length; i++) {
24210 var childToDelete = deletions[i];
24211
24212 try {
24213 commitDeletion(root, childToDelete, fiber);
24214 } catch (error) {
24215 reportUncaughtErrorInDEV(error);
24216 captureCommitPhaseError(childToDelete, fiber, error);
24217 }
24218 }
24219 }
24220
24221 var child = fiber.child;
24222
24223 if ((fiber.subtreeFlags & MutationMask) !== NoFlags && child !== null) {
24224 ensureCorrectReturnPointer(child, fiber);
24225 nextEffect = child;
24226 } else {
24227 commitMutationEffects_complete(root, lanes);
24228 }
24229 }
24230 }
24231
24232 function commitMutationEffects_complete(root, lanes) {
24233 while (nextEffect !== null) {
24234 var fiber = nextEffect;
24235 setCurrentFiber(fiber);
24236
24237 try {
24238 commitMutationEffectsOnFiber(fiber, root, lanes);
24239 } catch (error) {
24240 reportUncaughtErrorInDEV(error);
24241 captureCommitPhaseError(fiber, fiber.return, error);
24242 }
24243
24244 resetCurrentFiber();
24245 var sibling = fiber.sibling;
24246
24247 if (sibling !== null) {
24248 ensureCorrectReturnPointer(sibling, fiber.return);
24249 nextEffect = sibling;
24250 return;
24251 }
24252
24253 nextEffect = fiber.return;
24254 }
24255 }
24256
24257 function commitMutationEffectsOnFiber(finishedWork, root, lanes) {
24258 // TODO: The factoring of this phase could probably be improved. Consider
24259 // switching on the type of work before checking the flags. That's what
24260 // we do in all the other phases. I think this one is only different
24261 // because of the shared reconciliation logic below.
24262 var flags = finishedWork.flags;
24263
24264 if (flags & ContentReset) {
24265 commitResetTextContent(finishedWork);
24266 }
24267
24268 if (flags & Ref) {
24269 var current = finishedWork.alternate;
24270
24271 if (current !== null) {
24272 commitDetachRef(current);
24273 }
24274 }
24275
24276 if (flags & Visibility) {
24277 switch (finishedWork.tag) {
24278 case SuspenseComponent:
24279 {
24280 var newState = finishedWork.memoizedState;
24281 var isHidden = newState !== null;
24282
24283 if (isHidden) {
24284 var _current = finishedWork.alternate;
24285 var wasHidden = _current !== null && _current.memoizedState !== null;
24286
24287 if (!wasHidden) {
24288 // TODO: Move to passive phase
24289 markCommitTimeOfFallback();
24290 }
24291 }
24292
24293 break;
24294 }
24295
24296 case OffscreenComponent:
24297 {
24298 var _newState = finishedWork.memoizedState;
24299
24300 var _isHidden = _newState !== null;
24301
24302 var _current2 = finishedWork.alternate;
24303
24304 var _wasHidden = _current2 !== null && _current2.memoizedState !== null;
24305
24306 var offscreenBoundary = finishedWork;
24307
24308 {
24309 // TODO: This needs to run whenever there's an insertion or update
24310 // inside a hidden Offscreen tree.
24311 hideOrUnhideAllChildren(offscreenBoundary, _isHidden);
24312 }
24313
24314 {
24315 if (_isHidden) {
24316 if (!_wasHidden) {
24317 if ((offscreenBoundary.mode & ConcurrentMode) !== NoMode) {
24318 nextEffect = offscreenBoundary;
24319 var offscreenChild = offscreenBoundary.child;
24320
24321 while (offscreenChild !== null) {
24322 nextEffect = offscreenChild;
24323 disappearLayoutEffects_begin(offscreenChild);
24324 offscreenChild = offscreenChild.sibling;
24325 }
24326 }
24327 }
24328 }
24329
24330 break;
24331 }
24332 }
24333 }
24334 } // The following switch statement is only concerned about placement,
24335 // updates, and deletions. To avoid needing to add a case for every possible
24336 // bitmap value, we remove the secondary effects from the effect tag and
24337 // switch on that value.
24338
24339
24340 var primaryFlags = flags & (Placement | Update | Hydrating);
24341
24342 switch (primaryFlags) {
24343 case Placement:
24344 {
24345 commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is
24346 // inserted, before any life-cycles like componentDidMount gets called.
24347 // TODO: findDOMNode doesn't rely on this any more but isMounted does
24348 // and isMounted is deprecated anyway so we should be able to kill this.
24349
24350 finishedWork.flags &= ~Placement;
24351 break;
24352 }
24353
24354 case PlacementAndUpdate:
24355 {
24356 // Placement
24357 commitPlacement(finishedWork); // Clear the "placement" from effect tag so that we know that this is
24358 // inserted, before any life-cycles like componentDidMount gets called.
24359
24360 finishedWork.flags &= ~Placement; // Update
24361
24362 var _current3 = finishedWork.alternate;
24363 commitWork(_current3, finishedWork);
24364 break;
24365 }
24366
24367 case Hydrating:
24368 {
24369 finishedWork.flags &= ~Hydrating;
24370 break;
24371 }
24372
24373 case HydratingAndUpdate:
24374 {
24375 finishedWork.flags &= ~Hydrating; // Update
24376
24377 var _current4 = finishedWork.alternate;
24378 commitWork(_current4, finishedWork);
24379 break;
24380 }
24381
24382 case Update:
24383 {
24384 var _current5 = finishedWork.alternate;
24385 commitWork(_current5, finishedWork);
24386 break;
24387 }
24388 }
24389 }
24390
24391 function commitLayoutEffects(finishedWork, root, committedLanes) {
24392 inProgressLanes = committedLanes;
24393 inProgressRoot = root;
24394 nextEffect = finishedWork;
24395 commitLayoutEffects_begin(finishedWork, root, committedLanes);
24396 inProgressLanes = null;
24397 inProgressRoot = null;
24398 }
24399
24400 function commitLayoutEffects_begin(subtreeRoot, root, committedLanes) {
24401 // Suspense layout effects semantics don't change for legacy roots.
24402 var isModernRoot = (subtreeRoot.mode & ConcurrentMode) !== NoMode;
24403
24404 while (nextEffect !== null) {
24405 var fiber = nextEffect;
24406 var firstChild = fiber.child;
24407
24408 if ( fiber.tag === OffscreenComponent && isModernRoot) {
24409 // Keep track of the current Offscreen stack's state.
24410 var isHidden = fiber.memoizedState !== null;
24411 var newOffscreenSubtreeIsHidden = isHidden || offscreenSubtreeIsHidden;
24412
24413 if (newOffscreenSubtreeIsHidden) {
24414 // The Offscreen tree is hidden. Skip over its layout effects.
24415 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24416 continue;
24417 } else {
24418 // TODO (Offscreen) Also check: subtreeFlags & LayoutMask
24419 var current = fiber.alternate;
24420 var wasHidden = current !== null && current.memoizedState !== null;
24421 var newOffscreenSubtreeWasHidden = wasHidden || offscreenSubtreeWasHidden;
24422 var prevOffscreenSubtreeIsHidden = offscreenSubtreeIsHidden;
24423 var prevOffscreenSubtreeWasHidden = offscreenSubtreeWasHidden; // Traverse the Offscreen subtree with the current Offscreen as the root.
24424
24425 offscreenSubtreeIsHidden = newOffscreenSubtreeIsHidden;
24426 offscreenSubtreeWasHidden = newOffscreenSubtreeWasHidden;
24427
24428 if (offscreenSubtreeWasHidden && !prevOffscreenSubtreeWasHidden) {
24429 // This is the root of a reappearing boundary. Turn its layout effects
24430 // back on.
24431 nextEffect = fiber;
24432 reappearLayoutEffects_begin(fiber);
24433 }
24434
24435 var child = firstChild;
24436
24437 while (child !== null) {
24438 nextEffect = child;
24439 commitLayoutEffects_begin(child, // New root; bubble back up to here and stop.
24440 root, committedLanes);
24441 child = child.sibling;
24442 } // Restore Offscreen state and resume in our-progress traversal.
24443
24444
24445 nextEffect = fiber;
24446 offscreenSubtreeIsHidden = prevOffscreenSubtreeIsHidden;
24447 offscreenSubtreeWasHidden = prevOffscreenSubtreeWasHidden;
24448 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24449 continue;
24450 }
24451 }
24452
24453 if ((fiber.subtreeFlags & LayoutMask) !== NoFlags && firstChild !== null) {
24454 ensureCorrectReturnPointer(firstChild, fiber);
24455 nextEffect = firstChild;
24456 } else {
24457 commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes);
24458 }
24459 }
24460 }
24461
24462 function commitLayoutMountEffects_complete(subtreeRoot, root, committedLanes) {
24463 while (nextEffect !== null) {
24464 var fiber = nextEffect;
24465
24466 if ((fiber.flags & LayoutMask) !== NoFlags) {
24467 var current = fiber.alternate;
24468 setCurrentFiber(fiber);
24469
24470 try {
24471 commitLayoutEffectOnFiber(root, current, fiber, committedLanes);
24472 } catch (error) {
24473 reportUncaughtErrorInDEV(error);
24474 captureCommitPhaseError(fiber, fiber.return, error);
24475 }
24476
24477 resetCurrentFiber();
24478 }
24479
24480 if (fiber === subtreeRoot) {
24481 nextEffect = null;
24482 return;
24483 }
24484
24485 var sibling = fiber.sibling;
24486
24487 if (sibling !== null) {
24488 ensureCorrectReturnPointer(sibling, fiber.return);
24489 nextEffect = sibling;
24490 return;
24491 }
24492
24493 nextEffect = fiber.return;
24494 }
24495 }
24496
24497 function disappearLayoutEffects_begin(subtreeRoot) {
24498 while (nextEffect !== null) {
24499 var fiber = nextEffect;
24500 var firstChild = fiber.child; // TODO (Offscreen) Check: flags & (RefStatic | LayoutStatic)
24501
24502 switch (fiber.tag) {
24503 case FunctionComponent:
24504 case ForwardRef:
24505 case MemoComponent:
24506 case SimpleMemoComponent:
24507 {
24508 if ( fiber.mode & ProfileMode) {
24509 try {
24510 startLayoutEffectTimer();
24511 commitHookEffectListUnmount(Layout, fiber, fiber.return);
24512 } finally {
24513 recordLayoutEffectDuration(fiber);
24514 }
24515 } else {
24516 commitHookEffectListUnmount(Layout, fiber, fiber.return);
24517 }
24518
24519 break;
24520 }
24521
24522 case ClassComponent:
24523 {
24524 // TODO (Offscreen) Check: flags & RefStatic
24525 safelyDetachRef(fiber, fiber.return);
24526 var instance = fiber.stateNode;
24527
24528 if (typeof instance.componentWillUnmount === 'function') {
24529 safelyCallComponentWillUnmount(fiber, fiber.return, instance);
24530 }
24531
24532 break;
24533 }
24534
24535 case HostComponent:
24536 {
24537 safelyDetachRef(fiber, fiber.return);
24538 break;
24539 }
24540
24541 case OffscreenComponent:
24542 {
24543 // Check if this is a
24544 var isHidden = fiber.memoizedState !== null;
24545
24546 if (isHidden) {
24547 // Nested Offscreen tree is already hidden. Don't disappear
24548 // its effects.
24549 disappearLayoutEffects_complete(subtreeRoot);
24550 continue;
24551 }
24552
24553 break;
24554 }
24555 } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic
24556
24557
24558 if (firstChild !== null) {
24559 firstChild.return = fiber;
24560 nextEffect = firstChild;
24561 } else {
24562 disappearLayoutEffects_complete(subtreeRoot);
24563 }
24564 }
24565 }
24566
24567 function disappearLayoutEffects_complete(subtreeRoot) {
24568 while (nextEffect !== null) {
24569 var fiber = nextEffect;
24570
24571 if (fiber === subtreeRoot) {
24572 nextEffect = null;
24573 return;
24574 }
24575
24576 var sibling = fiber.sibling;
24577
24578 if (sibling !== null) {
24579 sibling.return = fiber.return;
24580 nextEffect = sibling;
24581 return;
24582 }
24583
24584 nextEffect = fiber.return;
24585 }
24586 }
24587
24588 function reappearLayoutEffects_begin(subtreeRoot) {
24589 while (nextEffect !== null) {
24590 var fiber = nextEffect;
24591 var firstChild = fiber.child;
24592
24593 if (fiber.tag === OffscreenComponent) {
24594 var isHidden = fiber.memoizedState !== null;
24595
24596 if (isHidden) {
24597 // Nested Offscreen tree is still hidden. Don't re-appear its effects.
24598 reappearLayoutEffects_complete(subtreeRoot);
24599 continue;
24600 }
24601 } // TODO (Offscreen) Check: subtreeFlags & LayoutStatic
24602
24603
24604 if (firstChild !== null) {
24605 // This node may have been reused from a previous render, so we can't
24606 // assume its return pointer is correct.
24607 firstChild.return = fiber;
24608 nextEffect = firstChild;
24609 } else {
24610 reappearLayoutEffects_complete(subtreeRoot);
24611 }
24612 }
24613 }
24614
24615 function reappearLayoutEffects_complete(subtreeRoot) {
24616 while (nextEffect !== null) {
24617 var fiber = nextEffect; // TODO (Offscreen) Check: flags & LayoutStatic
24618
24619 setCurrentFiber(fiber);
24620
24621 try {
24622 reappearLayoutEffectsOnFiber(fiber);
24623 } catch (error) {
24624 reportUncaughtErrorInDEV(error);
24625 captureCommitPhaseError(fiber, fiber.return, error);
24626 }
24627
24628 resetCurrentFiber();
24629
24630 if (fiber === subtreeRoot) {
24631 nextEffect = null;
24632 return;
24633 }
24634
24635 var sibling = fiber.sibling;
24636
24637 if (sibling !== null) {
24638 // This node may have been reused from a previous render, so we can't
24639 // assume its return pointer is correct.
24640 sibling.return = fiber.return;
24641 nextEffect = sibling;
24642 return;
24643 }
24644
24645 nextEffect = fiber.return;
24646 }
24647 }
24648
24649 function commitPassiveMountEffects(root, finishedWork) {
24650 nextEffect = finishedWork;
24651 commitPassiveMountEffects_begin(finishedWork, root);
24652 }
24653
24654 function commitPassiveMountEffects_begin(subtreeRoot, root) {
24655 while (nextEffect !== null) {
24656 var fiber = nextEffect;
24657 var firstChild = fiber.child;
24658
24659 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && firstChild !== null) {
24660 ensureCorrectReturnPointer(firstChild, fiber);
24661 nextEffect = firstChild;
24662 } else {
24663 commitPassiveMountEffects_complete(subtreeRoot, root);
24664 }
24665 }
24666 }
24667
24668 function commitPassiveMountEffects_complete(subtreeRoot, root) {
24669 while (nextEffect !== null) {
24670 var fiber = nextEffect;
24671
24672 if ((fiber.flags & Passive) !== NoFlags) {
24673 setCurrentFiber(fiber);
24674
24675 try {
24676 commitPassiveMountOnFiber(root, fiber);
24677 } catch (error) {
24678 reportUncaughtErrorInDEV(error);
24679 captureCommitPhaseError(fiber, fiber.return, error);
24680 }
24681
24682 resetCurrentFiber();
24683 }
24684
24685 if (fiber === subtreeRoot) {
24686 nextEffect = null;
24687 return;
24688 }
24689
24690 var sibling = fiber.sibling;
24691
24692 if (sibling !== null) {
24693 ensureCorrectReturnPointer(sibling, fiber.return);
24694 nextEffect = sibling;
24695 return;
24696 }
24697
24698 nextEffect = fiber.return;
24699 }
24700 }
24701
24702 function commitPassiveMountOnFiber(finishedRoot, finishedWork) {
24703 switch (finishedWork.tag) {
24704 case FunctionComponent:
24705 case ForwardRef:
24706 case SimpleMemoComponent:
24707 {
24708 if ( finishedWork.mode & ProfileMode) {
24709 startPassiveEffectTimer();
24710
24711 try {
24712 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
24713 } finally {
24714 recordPassiveEffectDuration(finishedWork);
24715 }
24716 } else {
24717 commitHookEffectListMount(Passive$1 | HasEffect, finishedWork);
24718 }
24719
24720 break;
24721 }
24722 }
24723 }
24724
24725 function commitPassiveUnmountEffects(firstChild) {
24726 nextEffect = firstChild;
24727 commitPassiveUnmountEffects_begin();
24728 }
24729
24730 function commitPassiveUnmountEffects_begin() {
24731 while (nextEffect !== null) {
24732 var fiber = nextEffect;
24733 var child = fiber.child;
24734
24735 if ((nextEffect.flags & ChildDeletion) !== NoFlags) {
24736 var deletions = fiber.deletions;
24737
24738 if (deletions !== null) {
24739 for (var i = 0; i < deletions.length; i++) {
24740 var fiberToDelete = deletions[i];
24741 nextEffect = fiberToDelete;
24742 commitPassiveUnmountEffectsInsideOfDeletedTree_begin(fiberToDelete, fiber);
24743 }
24744
24745 {
24746 // A fiber was deleted from this parent fiber, but it's still part of
24747 // the previous (alternate) parent fiber's list of children. Because
24748 // children are a linked list, an earlier sibling that's still alive
24749 // will be connected to the deleted fiber via its `alternate`:
24750 //
24751 // live fiber
24752 // --alternate--> previous live fiber
24753 // --sibling--> deleted fiber
24754 //
24755 // We can't disconnect `alternate` on nodes that haven't been deleted
24756 // yet, but we can disconnect the `sibling` and `child` pointers.
24757 var previousFiber = fiber.alternate;
24758
24759 if (previousFiber !== null) {
24760 var detachedChild = previousFiber.child;
24761
24762 if (detachedChild !== null) {
24763 previousFiber.child = null;
24764
24765 do {
24766 var detachedSibling = detachedChild.sibling;
24767 detachedChild.sibling = null;
24768 detachedChild = detachedSibling;
24769 } while (detachedChild !== null);
24770 }
24771 }
24772 }
24773
24774 nextEffect = fiber;
24775 }
24776 }
24777
24778 if ((fiber.subtreeFlags & PassiveMask) !== NoFlags && child !== null) {
24779 ensureCorrectReturnPointer(child, fiber);
24780 nextEffect = child;
24781 } else {
24782 commitPassiveUnmountEffects_complete();
24783 }
24784 }
24785 }
24786
24787 function commitPassiveUnmountEffects_complete() {
24788 while (nextEffect !== null) {
24789 var fiber = nextEffect;
24790
24791 if ((fiber.flags & Passive) !== NoFlags) {
24792 setCurrentFiber(fiber);
24793 commitPassiveUnmountOnFiber(fiber);
24794 resetCurrentFiber();
24795 }
24796
24797 var sibling = fiber.sibling;
24798
24799 if (sibling !== null) {
24800 ensureCorrectReturnPointer(sibling, fiber.return);
24801 nextEffect = sibling;
24802 return;
24803 }
24804
24805 nextEffect = fiber.return;
24806 }
24807 }
24808
24809 function commitPassiveUnmountOnFiber(finishedWork) {
24810 switch (finishedWork.tag) {
24811 case FunctionComponent:
24812 case ForwardRef:
24813 case SimpleMemoComponent:
24814 {
24815 if ( finishedWork.mode & ProfileMode) {
24816 startPassiveEffectTimer();
24817 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
24818 recordPassiveEffectDuration(finishedWork);
24819 } else {
24820 commitHookEffectListUnmount(Passive$1 | HasEffect, finishedWork, finishedWork.return);
24821 }
24822
24823 break;
24824 }
24825 }
24826 }
24827
24828 function commitPassiveUnmountEffectsInsideOfDeletedTree_begin(deletedSubtreeRoot, nearestMountedAncestor) {
24829 while (nextEffect !== null) {
24830 var fiber = nextEffect; // Deletion effects fire in parent -> child order
24831 // TODO: Check if fiber has a PassiveStatic flag
24832
24833 setCurrentFiber(fiber);
24834 commitPassiveUnmountInsideDeletedTreeOnFiber(fiber, nearestMountedAncestor);
24835 resetCurrentFiber();
24836 var child = fiber.child; // TODO: Only traverse subtree if it has a PassiveStatic flag. (But, if we
24837 // do this, still need to handle `deletedTreeCleanUpLevel` correctly.)
24838
24839 if (child !== null) {
24840 ensureCorrectReturnPointer(child, fiber);
24841 nextEffect = child;
24842 } else {
24843 commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot);
24844 }
24845 }
24846 }
24847
24848 function commitPassiveUnmountEffectsInsideOfDeletedTree_complete(deletedSubtreeRoot) {
24849 while (nextEffect !== null) {
24850 var fiber = nextEffect;
24851 var sibling = fiber.sibling;
24852 var returnFiber = fiber.return;
24853
24854 {
24855 // Recursively traverse the entire deleted tree and clean up fiber fields.
24856 // This is more aggressive than ideal, and the long term goal is to only
24857 // have to detach the deleted tree at the root.
24858 detachFiberAfterEffects(fiber);
24859
24860 if (fiber === deletedSubtreeRoot) {
24861 nextEffect = null;
24862 return;
24863 }
24864 }
24865
24866 if (sibling !== null) {
24867 ensureCorrectReturnPointer(sibling, returnFiber);
24868 nextEffect = sibling;
24869 return;
24870 }
24871
24872 nextEffect = returnFiber;
24873 }
24874 }
24875
24876 function commitPassiveUnmountInsideDeletedTreeOnFiber(current, nearestMountedAncestor) {
24877 switch (current.tag) {
24878 case FunctionComponent:
24879 case ForwardRef:
24880 case SimpleMemoComponent:
24881 {
24882 if ( current.mode & ProfileMode) {
24883 startPassiveEffectTimer();
24884 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
24885 recordPassiveEffectDuration(current);
24886 } else {
24887 commitHookEffectListUnmount(Passive$1, current, nearestMountedAncestor);
24888 }
24889
24890 break;
24891 }
24892 }
24893 }
24894
24895 var didWarnWrongReturnPointer = false;
24896
24897 function ensureCorrectReturnPointer(fiber, expectedReturnFiber) {
24898 {
24899 if (!didWarnWrongReturnPointer && fiber.return !== expectedReturnFiber) {
24900 didWarnWrongReturnPointer = true;
24901
24902 error('Internal React error: Return pointer is inconsistent ' + 'with parent.');
24903 }
24904 } // TODO: Remove this assignment once we're confident that it won't break
24905 // anything, by checking the warning logs for the above invariant
24906
24907
24908 fiber.return = expectedReturnFiber;
24909 } // TODO: Reuse reappearLayoutEffects traversal here?
24910
24911
24912 function invokeLayoutEffectMountInDEV(fiber) {
24913 {
24914 // We don't need to re-check StrictEffectsMode here.
24915 // This function is only called if that check has already passed.
24916 switch (fiber.tag) {
24917 case FunctionComponent:
24918 case ForwardRef:
24919 case SimpleMemoComponent:
24920 {
24921 try {
24922 commitHookEffectListMount(Layout | HasEffect, fiber);
24923 } catch (error) {
24924 reportUncaughtErrorInDEV(error);
24925 captureCommitPhaseError(fiber, fiber.return, error);
24926 }
24927
24928 break;
24929 }
24930
24931 case ClassComponent:
24932 {
24933 var instance = fiber.stateNode;
24934
24935 try {
24936 instance.componentDidMount();
24937 } catch (error) {
24938 reportUncaughtErrorInDEV(error);
24939 captureCommitPhaseError(fiber, fiber.return, error);
24940 }
24941
24942 break;
24943 }
24944 }
24945 }
24946 }
24947
24948 function invokePassiveEffectMountInDEV(fiber) {
24949 {
24950 // We don't need to re-check StrictEffectsMode here.
24951 // This function is only called if that check has already passed.
24952 switch (fiber.tag) {
24953 case FunctionComponent:
24954 case ForwardRef:
24955 case SimpleMemoComponent:
24956 {
24957 try {
24958 commitHookEffectListMount(Passive$1 | HasEffect, fiber);
24959 } catch (error) {
24960 reportUncaughtErrorInDEV(error);
24961 captureCommitPhaseError(fiber, fiber.return, error);
24962 }
24963
24964 break;
24965 }
24966 }
24967 }
24968 }
24969
24970 function invokeLayoutEffectUnmountInDEV(fiber) {
24971 {
24972 // We don't need to re-check StrictEffectsMode here.
24973 // This function is only called if that check has already passed.
24974 switch (fiber.tag) {
24975 case FunctionComponent:
24976 case ForwardRef:
24977 case SimpleMemoComponent:
24978 {
24979 try {
24980 commitHookEffectListUnmount(Layout | HasEffect, fiber, fiber.return);
24981 } catch (error) {
24982 reportUncaughtErrorInDEV(error);
24983 captureCommitPhaseError(fiber, fiber.return, error);
24984 }
24985
24986 break;
24987 }
24988
24989 case ClassComponent:
24990 {
24991 var instance = fiber.stateNode;
24992
24993 if (typeof instance.componentWillUnmount === 'function') {
24994 safelyCallComponentWillUnmount(fiber, fiber.return, instance);
24995 }
24996
24997 break;
24998 }
24999 }
25000 }
25001 }
25002
25003 function invokePassiveEffectUnmountInDEV(fiber) {
25004 {
25005 // We don't need to re-check StrictEffectsMode here.
25006 // This function is only called if that check has already passed.
25007 switch (fiber.tag) {
25008 case FunctionComponent:
25009 case ForwardRef:
25010 case SimpleMemoComponent:
25011 {
25012 try {
25013 commitHookEffectListUnmount(Passive$1 | HasEffect, fiber, fiber.return);
25014 } catch (error) {
25015 reportUncaughtErrorInDEV(error);
25016 captureCommitPhaseError(fiber, fiber.return, error);
25017 }
25018 }
25019 }
25020 }
25021 }
25022
25023 var COMPONENT_TYPE = 0;
25024 var HAS_PSEUDO_CLASS_TYPE = 1;
25025 var ROLE_TYPE = 2;
25026 var TEST_NAME_TYPE = 3;
25027 var TEXT_TYPE = 4;
25028
25029 if (typeof Symbol === 'function' && Symbol.for) {
25030 var symbolFor = Symbol.for;
25031 COMPONENT_TYPE = symbolFor('selector.component');
25032 HAS_PSEUDO_CLASS_TYPE = symbolFor('selector.has_pseudo_class');
25033 ROLE_TYPE = symbolFor('selector.role');
25034 TEST_NAME_TYPE = symbolFor('selector.test_id');
25035 TEXT_TYPE = symbolFor('selector.text');
25036 }
25037 var commitHooks = [];
25038 function onCommitRoot$1() {
25039 {
25040 commitHooks.forEach(function (commitHook) {
25041 return commitHook();
25042 });
25043 }
25044 }
25045
25046 var ReactCurrentActQueue = ReactSharedInternals.ReactCurrentActQueue;
25047 function isLegacyActEnvironment(fiber) {
25048 {
25049 // Legacy mode. We preserve the behavior of React 17's act. It assumes an
25050 // act environment whenever `jest` is defined, but you can still turn off
25051 // spurious warnings by setting IS_REACT_ACT_ENVIRONMENT explicitly
25052 // to false.
25053 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
25054 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined; // $FlowExpectedError - Flow doesn't know about jest
25055
25056 var jestIsDefined = typeof jest !== 'undefined';
25057 return jestIsDefined && isReactActEnvironmentGlobal !== false;
25058 }
25059 }
25060 function isConcurrentActEnvironment() {
25061 {
25062 var isReactActEnvironmentGlobal = // $FlowExpectedError – Flow doesn't know about IS_REACT_ACT_ENVIRONMENT global
25063 typeof IS_REACT_ACT_ENVIRONMENT !== 'undefined' ? IS_REACT_ACT_ENVIRONMENT : undefined;
25064
25065 if (!isReactActEnvironmentGlobal && ReactCurrentActQueue.current !== null) {
25066 // TODO: Include link to relevant documentation page.
25067 error('The current testing environment is not configured to support ' + 'act(...)');
25068 }
25069
25070 return isReactActEnvironmentGlobal;
25071 }
25072 }
25073
25074 var ceil = Math.ceil;
25075 var ReactCurrentDispatcher$2 = ReactSharedInternals.ReactCurrentDispatcher,
25076 ReactCurrentOwner$2 = ReactSharedInternals.ReactCurrentOwner,
25077 ReactCurrentBatchConfig$3 = ReactSharedInternals.ReactCurrentBatchConfig,
25078 ReactCurrentActQueue$1 = ReactSharedInternals.ReactCurrentActQueue;
25079 var NoContext =
25080 /* */
25081 0;
25082 var BatchedContext =
25083 /* */
25084 1;
25085 var RenderContext =
25086 /* */
25087 2;
25088 var CommitContext =
25089 /* */
25090 4;
25091 var RootInProgress = 0;
25092 var RootFatalErrored = 1;
25093 var RootErrored = 2;
25094 var RootSuspended = 3;
25095 var RootSuspendedWithDelay = 4;
25096 var RootCompleted = 5;
25097 var RootDidNotComplete = 6; // Describes where we are in the React execution stack
25098
25099 var executionContext = NoContext; // The root we're working on
25100
25101 var workInProgressRoot = null; // The fiber we're working on
25102
25103 var workInProgress = null; // The lanes we're rendering
25104
25105 var workInProgressRootRenderLanes = NoLanes; // Stack that allows components to change the render lanes for its subtree
25106 // This is a superset of the lanes we started working on at the root. The only
25107 // case where it's different from `workInProgressRootRenderLanes` is when we
25108 // enter a subtree that is hidden and needs to be unhidden: Suspense and
25109 // Offscreen component.
25110 //
25111 // Most things in the work loop should deal with workInProgressRootRenderLanes.
25112 // Most things in begin/complete phases should deal with subtreeRenderLanes.
25113
25114 var subtreeRenderLanes = NoLanes;
25115 var subtreeRenderLanesCursor = createCursor(NoLanes); // Whether to root completed, errored, suspended, etc.
25116
25117 var workInProgressRootExitStatus = RootInProgress; // A fatal error, if one is thrown
25118
25119 var workInProgressRootFatalError = null; // "Included" lanes refer to lanes that were worked on during this render. It's
25120 // slightly different than `renderLanes` because `renderLanes` can change as you
25121 // enter and exit an Offscreen tree. This value is the combination of all render
25122 // lanes for the entire render phase.
25123
25124 var workInProgressRootIncludedLanes = NoLanes; // The work left over by components that were visited during this render. Only
25125 // includes unprocessed updates, not work in bailed out children.
25126
25127 var workInProgressRootSkippedLanes = NoLanes; // Lanes that were updated (in an interleaved event) during this render.
25128
25129 var workInProgressRootInterleavedUpdatedLanes = NoLanes; // Lanes that were updated during the render phase (*not* an interleaved event).
25130
25131 var workInProgressRootPingedLanes = NoLanes; // Errors that are thrown during the render phase.
25132
25133 var workInProgressRootConcurrentErrors = null; // These are errors that we recovered from without surfacing them to the UI.
25134 // We will log them once the tree commits.
25135
25136 var workInProgressRootRecoverableErrors = null; // The most recent time we committed a fallback. This lets us ensure a train
25137 // model where we don't commit new loading states in too quick succession.
25138
25139 var globalMostRecentFallbackTime = 0;
25140 var FALLBACK_THROTTLE_MS = 500; // The absolute time for when we should start giving up on rendering
25141 // more and prefer CPU suspense heuristics instead.
25142
25143 var workInProgressRootRenderTargetTime = Infinity; // How long a render is supposed to take before we start following CPU
25144 // suspense heuristics and opt out of rendering more content.
25145
25146 var RENDER_TIMEOUT_MS = 500;
25147
25148 function resetRenderTimer() {
25149 workInProgressRootRenderTargetTime = now() + RENDER_TIMEOUT_MS;
25150 }
25151
25152 function getRenderTargetTime() {
25153 return workInProgressRootRenderTargetTime;
25154 }
25155 var hasUncaughtError = false;
25156 var firstUncaughtError = null;
25157 var legacyErrorBoundariesThatAlreadyFailed = null; // Only used when enableProfilerNestedUpdateScheduledHook is true;
25158 var rootDoesHavePassiveEffects = false;
25159 var rootWithPendingPassiveEffects = null;
25160 var pendingPassiveEffectsLanes = NoLanes;
25161 var pendingPassiveProfilerEffects = [];
25162
25163 var NESTED_UPDATE_LIMIT = 50;
25164 var nestedUpdateCount = 0;
25165 var rootWithNestedUpdates = null;
25166 var NESTED_PASSIVE_UPDATE_LIMIT = 50;
25167 var nestedPassiveUpdateCount = 0; // If two updates are scheduled within the same event, we should treat their
25168 // event times as simultaneous, even if the actual clock time has advanced
25169 // between the first and second call.
25170
25171 var currentEventTime = NoTimestamp;
25172 var currentEventTransitionLane = NoLanes;
25173 function getWorkInProgressRoot() {
25174 return workInProgressRoot;
25175 }
25176 function requestEventTime() {
25177 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
25178 // We're inside React, so it's fine to read the actual time.
25179 return now();
25180 } // We're not inside React, so we may be in the middle of a browser event.
25181
25182
25183 if (currentEventTime !== NoTimestamp) {
25184 // Use the same start time for all updates until we enter React again.
25185 return currentEventTime;
25186 } // This is the first update since React yielded. Compute a new start time.
25187
25188
25189 currentEventTime = now();
25190 return currentEventTime;
25191 }
25192 function requestUpdateLane(fiber) {
25193 // Special cases
25194 var mode = fiber.mode;
25195
25196 if ((mode & ConcurrentMode) === NoMode) {
25197 return SyncLane;
25198 } else if ( (executionContext & RenderContext) !== NoContext && workInProgressRootRenderLanes !== NoLanes) {
25199 // This is a render phase update. These are not officially supported. The
25200 // old behavior is to give this the same "thread" (lanes) as
25201 // whatever is currently rendering. So if you call `setState` on a component
25202 // that happens later in the same render, it will flush. Ideally, we want to
25203 // remove the special case and treat them as if they came from an
25204 // interleaved event. Regardless, this pattern is not officially supported.
25205 // This behavior is only a fallback. The flag only exists until we can roll
25206 // out the setState warning, since existing code might accidentally rely on
25207 // the current behavior.
25208 return pickArbitraryLane(workInProgressRootRenderLanes);
25209 }
25210
25211 var isTransition = requestCurrentTransition() !== NoTransition;
25212
25213 if (isTransition) {
25214 if ( ReactCurrentBatchConfig$3.transition !== null) {
25215 var transition = ReactCurrentBatchConfig$3.transition;
25216
25217 if (!transition._updatedFibers) {
25218 transition._updatedFibers = new Set();
25219 }
25220
25221 transition._updatedFibers.add(fiber);
25222 } // The algorithm for assigning an update to a lane should be stable for all
25223 // updates at the same priority within the same event. To do this, the
25224 // inputs to the algorithm must be the same.
25225 //
25226 // The trick we use is to cache the first of each of these inputs within an
25227 // event. Then reset the cached values once we can be sure the event is
25228 // over. Our heuristic for that is whenever we enter a concurrent work loop.
25229
25230
25231 if (currentEventTransitionLane === NoLane) {
25232 // All transitions within the same event are assigned the same lane.
25233 currentEventTransitionLane = claimNextTransitionLane();
25234 }
25235
25236 return currentEventTransitionLane;
25237 } // Updates originating inside certain React methods, like flushSync, have
25238 // their priority set by tracking it with a context variable.
25239 //
25240 // The opaque type returned by the host config is internally a lane, so we can
25241 // use that directly.
25242 // TODO: Move this type conversion to the event priority module.
25243
25244
25245 var updateLane = getCurrentUpdatePriority();
25246
25247 if (updateLane !== NoLane) {
25248 return updateLane;
25249 } // This update originated outside React. Ask the host environment for an
25250 // appropriate priority, based on the type of event.
25251 //
25252 // The opaque type returned by the host config is internally a lane, so we can
25253 // use that directly.
25254 // TODO: Move this type conversion to the event priority module.
25255
25256
25257 var eventLane = getCurrentEventPriority();
25258 return eventLane;
25259 }
25260
25261 function requestRetryLane(fiber) {
25262 // This is a fork of `requestUpdateLane` designed specifically for Suspense
25263 // "retries" — a special update that attempts to flip a Suspense boundary
25264 // from its placeholder state to its primary/resolved state.
25265 // Special cases
25266 var mode = fiber.mode;
25267
25268 if ((mode & ConcurrentMode) === NoMode) {
25269 return SyncLane;
25270 }
25271
25272 return claimNextRetryLane();
25273 }
25274
25275 function scheduleUpdateOnFiber(fiber, lane, eventTime) {
25276 checkForNestedUpdates();
25277 var root = markUpdateLaneFromFiberToRoot(fiber, lane);
25278
25279 if (root === null) {
25280 return null;
25281 } // Mark that the root has a pending update.
25282
25283
25284 markRootUpdated(root, lane, eventTime);
25285
25286 if ((executionContext & RenderContext) !== NoLanes && root === workInProgressRoot) {
25287 // This update was dispatched during the render phase. This is a mistake
25288 // if the update originates from user space (with the exception of local
25289 // hook updates, which are handled differently and don't reach this
25290 // function), but there are some internal React features that use this as
25291 // an implementation detail, like selective hydration.
25292 warnAboutRenderPhaseUpdatesInDEV(fiber); // Track lanes that were updated during the render phase
25293 } else {
25294 // This is a normal update, scheduled from outside the render phase. For
25295 // example, during an input event.
25296 {
25297 if (isDevToolsPresent) {
25298 addFiberToLanesMap(root, fiber, lane);
25299 }
25300 }
25301
25302 warnIfUpdatesNotWrappedWithActDEV(fiber);
25303
25304 if (root === workInProgressRoot) {
25305 // TODO: Consolidate with `isInterleavedUpdate` check
25306 // Received an update to a tree that's in the middle of rendering. Mark
25307 // that there was an interleaved update work on this root. Unless the
25308 // `deferRenderPhaseUpdateToNextBatch` flag is off and this is a render
25309 // phase update. In that case, we don't treat render phase updates as if
25310 // they were interleaved, for backwards compat reasons.
25311 if ( (executionContext & RenderContext) === NoContext) {
25312 workInProgressRootInterleavedUpdatedLanes = mergeLanes(workInProgressRootInterleavedUpdatedLanes, lane);
25313 }
25314
25315 if (workInProgressRootExitStatus === RootSuspendedWithDelay) {
25316 // The root already suspended with a delay, which means this render
25317 // definitely won't finish. Since we have a new update, let's mark it as
25318 // suspended now, right before marking the incoming update. This has the
25319 // effect of interrupting the current render and switching to the update.
25320 // TODO: Make sure this doesn't override pings that happen while we've
25321 // already started rendering.
25322 markRootSuspended$1(root, workInProgressRootRenderLanes);
25323 }
25324 }
25325
25326 ensureRootIsScheduled(root, eventTime);
25327
25328 if (lane === SyncLane && executionContext === NoContext && (fiber.mode & ConcurrentMode) === NoMode && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
25329 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
25330 // Flush the synchronous work now, unless we're already working or inside
25331 // a batch. This is intentionally inside scheduleUpdateOnFiber instead of
25332 // scheduleCallbackForFiber to preserve the ability to schedule a callback
25333 // without immediately flushing it. We only do this for user-initiated
25334 // updates, to preserve historical behavior of legacy mode.
25335 resetRenderTimer();
25336 flushSyncCallbacksOnlyInLegacyMode();
25337 }
25338 }
25339
25340 return root;
25341 }
25342 function scheduleInitialHydrationOnRoot(root, lane, eventTime) {
25343 // This is a special fork of scheduleUpdateOnFiber that is only used to
25344 // schedule the initial hydration of a root that has just been created. Most
25345 // of the stuff in scheduleUpdateOnFiber can be skipped.
25346 //
25347 // The main reason for this separate path, though, is to distinguish the
25348 // initial children from subsequent updates. In fully client-rendered roots
25349 // (createRoot instead of hydrateRoot), all top-level renders are modeled as
25350 // updates, but hydration roots are special because the initial render must
25351 // match what was rendered on the server.
25352 var current = root.current;
25353 current.lanes = lane;
25354 markRootUpdated(root, lane, eventTime);
25355 ensureRootIsScheduled(root, eventTime);
25356 } // This is split into a separate function so we can mark a fiber with pending
25357 // work without treating it as a typical update that originates from an event;
25358 // e.g. retrying a Suspense boundary isn't an update, but it does schedule work
25359 // on a fiber.
25360
25361 function markUpdateLaneFromFiberToRoot(sourceFiber, lane) {
25362 // Update the source fiber's lanes
25363 sourceFiber.lanes = mergeLanes(sourceFiber.lanes, lane);
25364 var alternate = sourceFiber.alternate;
25365
25366 if (alternate !== null) {
25367 alternate.lanes = mergeLanes(alternate.lanes, lane);
25368 }
25369
25370 {
25371 if (alternate === null && (sourceFiber.flags & (Placement | Hydrating)) !== NoFlags) {
25372 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
25373 }
25374 } // Walk the parent path to the root and update the child lanes.
25375
25376
25377 var node = sourceFiber;
25378 var parent = sourceFiber.return;
25379
25380 while (parent !== null) {
25381 parent.childLanes = mergeLanes(parent.childLanes, lane);
25382 alternate = parent.alternate;
25383
25384 if (alternate !== null) {
25385 alternate.childLanes = mergeLanes(alternate.childLanes, lane);
25386 } else {
25387 {
25388 if ((parent.flags & (Placement | Hydrating)) !== NoFlags) {
25389 warnAboutUpdateOnNotYetMountedFiberInDEV(sourceFiber);
25390 }
25391 }
25392 }
25393
25394 node = parent;
25395 parent = parent.return;
25396 }
25397
25398 if (node.tag === HostRoot) {
25399 var root = node.stateNode;
25400 return root;
25401 } else {
25402 return null;
25403 }
25404 }
25405
25406 function isInterleavedUpdate(fiber, lane) {
25407 return (// TODO: Optimize slightly by comparing to root that fiber belongs to.
25408 // Requires some refactoring. Not a big deal though since it's rare for
25409 // concurrent apps to have more than a single root.
25410 workInProgressRoot !== null && (fiber.mode & ConcurrentMode) !== NoMode && ( // If this is a render phase update (i.e. UNSAFE_componentWillReceiveProps),
25411 // then don't treat this as an interleaved update. This pattern is
25412 // accompanied by a warning but we haven't fully deprecated it yet. We can
25413 // remove once the deferRenderPhaseUpdateToNextBatch flag is enabled.
25414 (executionContext & RenderContext) === NoContext)
25415 );
25416 } // Use this function to schedule a task for a root. There's only one task per
25417 // root; if a task was already scheduled, we'll check to make sure the priority
25418 // of the existing task is the same as the priority of the next level that the
25419 // root has work on. This function is called on every update, and right before
25420 // exiting a task.
25421
25422 function ensureRootIsScheduled(root, currentTime) {
25423 var existingCallbackNode = root.callbackNode; // Check if any lanes are being starved by other work. If so, mark them as
25424 // expired so we know to work on those next.
25425
25426 markStarvedLanesAsExpired(root, currentTime); // Determine the next lanes to work on, and their priority.
25427
25428 var nextLanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
25429
25430 if (nextLanes === NoLanes) {
25431 // Special case: There's nothing to work on.
25432 if (existingCallbackNode !== null) {
25433 cancelCallback$1(existingCallbackNode);
25434 }
25435
25436 root.callbackNode = null;
25437 root.callbackPriority = NoLane;
25438 return;
25439 } // We use the highest priority lane to represent the priority of the callback.
25440
25441
25442 var newCallbackPriority = getHighestPriorityLane(nextLanes); // Check if there's an existing task. We may be able to reuse it.
25443
25444 var existingCallbackPriority = root.callbackPriority;
25445
25446 if (existingCallbackPriority === newCallbackPriority && // Special case related to `act`. If the currently scheduled task is a
25447 // Scheduler task, rather than an `act` task, cancel it and re-scheduled
25448 // on the `act` queue.
25449 !( ReactCurrentActQueue$1.current !== null && existingCallbackNode !== fakeActCallbackNode)) {
25450 {
25451 // If we're going to re-use an existing task, it needs to exist.
25452 // Assume that discrete update microtasks are non-cancellable and null.
25453 // TODO: Temporary until we confirm this warning is not fired.
25454 if (existingCallbackNode == null && existingCallbackPriority !== SyncLane) {
25455 error('Expected scheduled callback to exist. This error is likely caused by a bug in React. Please file an issue.');
25456 }
25457 } // The priority hasn't changed. We can reuse the existing task. Exit.
25458
25459
25460 return;
25461 }
25462
25463 if (existingCallbackNode != null) {
25464 // Cancel the existing callback. We'll schedule a new one below.
25465 cancelCallback$1(existingCallbackNode);
25466 } // Schedule a new callback.
25467
25468
25469 var newCallbackNode;
25470
25471 if (newCallbackPriority === SyncLane) {
25472 // Special case: Sync React callbacks are scheduled on a special
25473 // internal queue
25474 if (root.tag === LegacyRoot) {
25475 if ( ReactCurrentActQueue$1.isBatchingLegacy !== null) {
25476 ReactCurrentActQueue$1.didScheduleLegacyUpdate = true;
25477 }
25478
25479 scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));
25480 } else {
25481 scheduleSyncCallback(performSyncWorkOnRoot.bind(null, root));
25482 }
25483
25484 {
25485 // Flush the queue in a microtask.
25486 if ( ReactCurrentActQueue$1.current !== null) {
25487 // Inside `act`, use our internal `act` queue so that these get flushed
25488 // at the end of the current scope even when using the sync version
25489 // of `act`.
25490 ReactCurrentActQueue$1.current.push(flushSyncCallbacks);
25491 } else {
25492 scheduleMicrotask(function () {
25493 // In Safari, appending an iframe forces microtasks to run.
25494 // https://github.com/facebook/react/issues/22459
25495 // We don't support running callbacks in the middle of render
25496 // or commit so we need to check against that.
25497 if (executionContext === NoContext) {
25498 // It's only safe to do this conditionally because we always
25499 // check for pending work before we exit the task.
25500 flushSyncCallbacks();
25501 }
25502 });
25503 }
25504 }
25505
25506 newCallbackNode = null;
25507 } else {
25508 var schedulerPriorityLevel;
25509
25510 switch (lanesToEventPriority(nextLanes)) {
25511 case DiscreteEventPriority:
25512 schedulerPriorityLevel = ImmediatePriority;
25513 break;
25514
25515 case ContinuousEventPriority:
25516 schedulerPriorityLevel = UserBlockingPriority;
25517 break;
25518
25519 case DefaultEventPriority:
25520 schedulerPriorityLevel = NormalPriority;
25521 break;
25522
25523 case IdleEventPriority:
25524 schedulerPriorityLevel = IdlePriority;
25525 break;
25526
25527 default:
25528 schedulerPriorityLevel = NormalPriority;
25529 break;
25530 }
25531
25532 newCallbackNode = scheduleCallback$1(schedulerPriorityLevel, performConcurrentWorkOnRoot.bind(null, root));
25533 }
25534
25535 root.callbackPriority = newCallbackPriority;
25536 root.callbackNode = newCallbackNode;
25537 } // This is the entry point for every concurrent task, i.e. anything that
25538 // goes through Scheduler.
25539
25540
25541 function performConcurrentWorkOnRoot(root, didTimeout) {
25542 {
25543 resetNestedUpdateFlag();
25544 } // Since we know we're in a React event, we can clear the current
25545 // event time. The next update will compute a new event time.
25546
25547
25548 currentEventTime = NoTimestamp;
25549 currentEventTransitionLane = NoLanes;
25550
25551 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
25552 throw new Error('Should not already be working.');
25553 } // Flush any pending passive effects before deciding which lanes to work on,
25554 // in case they schedule additional work.
25555
25556
25557 var originalCallbackNode = root.callbackNode;
25558 var didFlushPassiveEffects = flushPassiveEffects();
25559
25560 if (didFlushPassiveEffects) {
25561 // Something in the passive effect phase may have canceled the current task.
25562 // Check if the task node for this root was changed.
25563 if (root.callbackNode !== originalCallbackNode) {
25564 // The current task was canceled. Exit. We don't need to call
25565 // `ensureRootIsScheduled` because the check above implies either that
25566 // there's a new task, or that there's no remaining work on this root.
25567 return null;
25568 }
25569 } // Determine the next lanes to work on, using the fields stored
25570 // on the root.
25571
25572
25573 var lanes = getNextLanes(root, root === workInProgressRoot ? workInProgressRootRenderLanes : NoLanes);
25574
25575 if (lanes === NoLanes) {
25576 // Defensive coding. This is never expected to happen.
25577 return null;
25578 } // We disable time-slicing in some cases: if the work has been CPU-bound
25579 // for too long ("expired" work, to prevent starvation), or we're in
25580 // sync-updates-by-default mode.
25581 // TODO: We only check `didTimeout` defensively, to account for a Scheduler
25582 // bug we're still investigating. Once the bug in Scheduler is fixed,
25583 // we can remove this, since we track expiration ourselves.
25584
25585
25586 var shouldTimeSlice = !includesBlockingLane(root, lanes) && !includesExpiredLane(root, lanes) && ( !didTimeout);
25587 var exitStatus = shouldTimeSlice ? renderRootConcurrent(root, lanes) : renderRootSync(root, lanes);
25588
25589 if (exitStatus !== RootInProgress) {
25590 if (exitStatus === RootErrored) {
25591 // If something threw an error, try rendering one more time. We'll
25592 // render synchronously to block concurrent data mutations, and we'll
25593 // includes all pending updates are included. If it still fails after
25594 // the second attempt, we'll give up and commit the resulting tree.
25595 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
25596
25597 if (errorRetryLanes !== NoLanes) {
25598 lanes = errorRetryLanes;
25599 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
25600 }
25601 }
25602
25603 if (exitStatus === RootFatalErrored) {
25604 var fatalError = workInProgressRootFatalError;
25605 prepareFreshStack(root, NoLanes);
25606 markRootSuspended$1(root, lanes);
25607 ensureRootIsScheduled(root, now());
25608 throw fatalError;
25609 }
25610
25611 if (exitStatus === RootDidNotComplete) {
25612 // The render unwound without completing the tree. This happens in special
25613 // cases where need to exit the current render without producing a
25614 // consistent tree or committing.
25615 //
25616 // This should only happen during a concurrent render, not a discrete or
25617 // synchronous update. We should have already checked for this when we
25618 // unwound the stack.
25619 markRootSuspended$1(root, lanes);
25620 } else {
25621 // The render completed.
25622 // Check if this render may have yielded to a concurrent event, and if so,
25623 // confirm that any newly rendered stores are consistent.
25624 // TODO: It's possible that even a concurrent render may never have yielded
25625 // to the main thread, if it was fast enough, or if it expired. We could
25626 // skip the consistency check in that case, too.
25627 var renderWasConcurrent = !includesBlockingLane(root, lanes);
25628 var finishedWork = root.current.alternate;
25629
25630 if (renderWasConcurrent && !isRenderConsistentWithExternalStores(finishedWork)) {
25631 // A store was mutated in an interleaved event. Render again,
25632 // synchronously, to block further mutations.
25633 exitStatus = renderRootSync(root, lanes); // We need to check again if something threw
25634
25635 if (exitStatus === RootErrored) {
25636 var _errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
25637
25638 if (_errorRetryLanes !== NoLanes) {
25639 lanes = _errorRetryLanes;
25640 exitStatus = recoverFromConcurrentError(root, _errorRetryLanes); // We assume the tree is now consistent because we didn't yield to any
25641 // concurrent events.
25642 }
25643 }
25644
25645 if (exitStatus === RootFatalErrored) {
25646 var _fatalError = workInProgressRootFatalError;
25647 prepareFreshStack(root, NoLanes);
25648 markRootSuspended$1(root, lanes);
25649 ensureRootIsScheduled(root, now());
25650 throw _fatalError;
25651 }
25652 } // We now have a consistent tree. The next step is either to commit it,
25653 // or, if something suspended, wait to commit it after a timeout.
25654
25655
25656 root.finishedWork = finishedWork;
25657 root.finishedLanes = lanes;
25658 finishConcurrentRender(root, exitStatus, lanes);
25659 }
25660 }
25661
25662 ensureRootIsScheduled(root, now());
25663
25664 if (root.callbackNode === originalCallbackNode) {
25665 // The task node scheduled for this root is the same one that's
25666 // currently executed. Need to return a continuation.
25667 return performConcurrentWorkOnRoot.bind(null, root);
25668 }
25669
25670 return null;
25671 }
25672
25673 function recoverFromConcurrentError(root, errorRetryLanes) {
25674 // If an error occurred during hydration, discard server response and fall
25675 // back to client side render.
25676 // Before rendering again, save the errors from the previous attempt.
25677 var errorsFromFirstAttempt = workInProgressRootConcurrentErrors;
25678
25679 if (isRootDehydrated(root)) {
25680 // The shell failed to hydrate. Set a flag to force a client rendering
25681 // during the next attempt. To do this, we call prepareFreshStack now
25682 // to create the root work-in-progress fiber. This is a bit weird in terms
25683 // of factoring, because it relies on renderRootSync not calling
25684 // prepareFreshStack again in the call below, which happens because the
25685 // root and lanes haven't changed.
25686 //
25687 // TODO: I think what we should do is set ForceClientRender inside
25688 // throwException, like we do for nested Suspense boundaries. The reason
25689 // it's here instead is so we can switch to the synchronous work loop, too.
25690 // Something to consider for a future refactor.
25691 var rootWorkInProgress = prepareFreshStack(root, errorRetryLanes);
25692 rootWorkInProgress.flags |= ForceClientRender;
25693
25694 {
25695 errorHydratingContainer(root.containerInfo);
25696 }
25697 }
25698
25699 var exitStatus = renderRootSync(root, errorRetryLanes);
25700
25701 if (exitStatus !== RootErrored) {
25702 // Successfully finished rendering on retry
25703 // The errors from the failed first attempt have been recovered. Add
25704 // them to the collection of recoverable errors. We'll log them in the
25705 // commit phase.
25706 var errorsFromSecondAttempt = workInProgressRootRecoverableErrors;
25707 workInProgressRootRecoverableErrors = errorsFromFirstAttempt; // The errors from the second attempt should be queued after the errors
25708 // from the first attempt, to preserve the causal sequence.
25709
25710 if (errorsFromSecondAttempt !== null) {
25711 queueRecoverableErrors(errorsFromSecondAttempt);
25712 }
25713 }
25714
25715 return exitStatus;
25716 }
25717
25718 function queueRecoverableErrors(errors) {
25719 if (workInProgressRootRecoverableErrors === null) {
25720 workInProgressRootRecoverableErrors = errors;
25721 } else {
25722 workInProgressRootRecoverableErrors.push.apply(workInProgressRootRecoverableErrors, errors);
25723 }
25724 }
25725
25726 function finishConcurrentRender(root, exitStatus, lanes) {
25727 switch (exitStatus) {
25728 case RootInProgress:
25729 case RootFatalErrored:
25730 {
25731 throw new Error('Root did not complete. This is a bug in React.');
25732 }
25733 // Flow knows about invariant, so it complains if I add a break
25734 // statement, but eslint doesn't know about invariant, so it complains
25735 // if I do. eslint-disable-next-line no-fallthrough
25736
25737 case RootErrored:
25738 {
25739 // We should have already attempted to retry this tree. If we reached
25740 // this point, it errored again. Commit it.
25741 commitRoot(root, workInProgressRootRecoverableErrors);
25742 break;
25743 }
25744
25745 case RootSuspended:
25746 {
25747 markRootSuspended$1(root, lanes); // We have an acceptable loading state. We need to figure out if we
25748 // should immediately commit it or wait a bit.
25749
25750 if (includesOnlyRetries(lanes) && // do not delay if we're inside an act() scope
25751 !shouldForceFlushFallbacksInDEV()) {
25752 // This render only included retries, no updates. Throttle committing
25753 // retries so that we don't show too many loading states too quickly.
25754 var msUntilTimeout = globalMostRecentFallbackTime + FALLBACK_THROTTLE_MS - now(); // Don't bother with a very short suspense time.
25755
25756 if (msUntilTimeout > 10) {
25757 var nextLanes = getNextLanes(root, NoLanes);
25758
25759 if (nextLanes !== NoLanes) {
25760 // There's additional work on this root.
25761 break;
25762 }
25763
25764 var suspendedLanes = root.suspendedLanes;
25765
25766 if (!isSubsetOfLanes(suspendedLanes, lanes)) {
25767 // We should prefer to render the fallback of at the last
25768 // suspended level. Ping the last suspended level to try
25769 // rendering it again.
25770 // FIXME: What if the suspended lanes are Idle? Should not restart.
25771 var eventTime = requestEventTime();
25772 markRootPinged(root, suspendedLanes);
25773 break;
25774 } // The render is suspended, it hasn't timed out, and there's no
25775 // lower priority work to do. Instead of committing the fallback
25776 // immediately, wait for more data to arrive.
25777
25778
25779 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors), msUntilTimeout);
25780 break;
25781 }
25782 } // The work expired. Commit immediately.
25783
25784
25785 commitRoot(root, workInProgressRootRecoverableErrors);
25786 break;
25787 }
25788
25789 case RootSuspendedWithDelay:
25790 {
25791 markRootSuspended$1(root, lanes);
25792
25793 if (includesOnlyTransitions(lanes)) {
25794 // This is a transition, so we should exit without committing a
25795 // placeholder and without scheduling a timeout. Delay indefinitely
25796 // until we receive more data.
25797 break;
25798 }
25799
25800 if (!shouldForceFlushFallbacksInDEV()) {
25801 // This is not a transition, but we did trigger an avoided state.
25802 // Schedule a placeholder to display after a short delay, using the Just
25803 // Noticeable Difference.
25804 // TODO: Is the JND optimization worth the added complexity? If this is
25805 // the only reason we track the event time, then probably not.
25806 // Consider removing.
25807 var mostRecentEventTime = getMostRecentEventTime(root, lanes);
25808 var eventTimeMs = mostRecentEventTime;
25809 var timeElapsedMs = now() - eventTimeMs;
25810
25811 var _msUntilTimeout = jnd(timeElapsedMs) - timeElapsedMs; // Don't bother with a very short suspense time.
25812
25813
25814 if (_msUntilTimeout > 10) {
25815 // Instead of committing the fallback immediately, wait for more data
25816 // to arrive.
25817 root.timeoutHandle = scheduleTimeout(commitRoot.bind(null, root, workInProgressRootRecoverableErrors), _msUntilTimeout);
25818 break;
25819 }
25820 } // Commit the placeholder.
25821
25822
25823 commitRoot(root, workInProgressRootRecoverableErrors);
25824 break;
25825 }
25826
25827 case RootCompleted:
25828 {
25829 // The work completed. Ready to commit.
25830 commitRoot(root, workInProgressRootRecoverableErrors);
25831 break;
25832 }
25833
25834 default:
25835 {
25836 throw new Error('Unknown root exit status.');
25837 }
25838 }
25839 }
25840
25841 function isRenderConsistentWithExternalStores(finishedWork) {
25842 // Search the rendered tree for external store reads, and check whether the
25843 // stores were mutated in a concurrent event. Intentionally using an iterative
25844 // loop instead of recursion so we can exit early.
25845 var node = finishedWork;
25846
25847 while (true) {
25848 if (node.flags & StoreConsistency) {
25849 var updateQueue = node.updateQueue;
25850
25851 if (updateQueue !== null) {
25852 var checks = updateQueue.stores;
25853
25854 if (checks !== null) {
25855 for (var i = 0; i < checks.length; i++) {
25856 var check = checks[i];
25857 var getSnapshot = check.getSnapshot;
25858 var renderedValue = check.value;
25859
25860 try {
25861 if (!objectIs(getSnapshot(), renderedValue)) {
25862 // Found an inconsistent store.
25863 return false;
25864 }
25865 } catch (error) {
25866 // If `getSnapshot` throws, return `false`. This will schedule
25867 // a re-render, and the error will be rethrown during render.
25868 return false;
25869 }
25870 }
25871 }
25872 }
25873 }
25874
25875 var child = node.child;
25876
25877 if (node.subtreeFlags & StoreConsistency && child !== null) {
25878 child.return = node;
25879 node = child;
25880 continue;
25881 }
25882
25883 if (node === finishedWork) {
25884 return true;
25885 }
25886
25887 while (node.sibling === null) {
25888 if (node.return === null || node.return === finishedWork) {
25889 return true;
25890 }
25891
25892 node = node.return;
25893 }
25894
25895 node.sibling.return = node.return;
25896 node = node.sibling;
25897 } // Flow doesn't know this is unreachable, but eslint does
25898 // eslint-disable-next-line no-unreachable
25899
25900
25901 return true;
25902 }
25903
25904 function markRootSuspended$1(root, suspendedLanes) {
25905 // When suspending, we should always exclude lanes that were pinged or (more
25906 // rarely, since we try to avoid it) updated during the render phase.
25907 // TODO: Lol maybe there's a better way to factor this besides this
25908 // obnoxiously named function :)
25909 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootPingedLanes);
25910 suspendedLanes = removeLanes(suspendedLanes, workInProgressRootInterleavedUpdatedLanes);
25911 markRootSuspended(root, suspendedLanes);
25912 } // This is the entry point for synchronous tasks that don't go
25913 // through Scheduler
25914
25915
25916 function performSyncWorkOnRoot(root) {
25917 {
25918 syncNestedUpdateFlag();
25919 }
25920
25921 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
25922 throw new Error('Should not already be working.');
25923 }
25924
25925 flushPassiveEffects();
25926 var lanes = getNextLanes(root, NoLanes);
25927
25928 if (!includesSomeLane(lanes, SyncLane)) {
25929 // There's no remaining sync work left.
25930 ensureRootIsScheduled(root, now());
25931 return null;
25932 }
25933
25934 var exitStatus = renderRootSync(root, lanes);
25935
25936 if (root.tag !== LegacyRoot && exitStatus === RootErrored) {
25937 // If something threw an error, try rendering one more time. We'll render
25938 // synchronously to block concurrent data mutations, and we'll includes
25939 // all pending updates are included. If it still fails after the second
25940 // attempt, we'll give up and commit the resulting tree.
25941 var errorRetryLanes = getLanesToRetrySynchronouslyOnError(root);
25942
25943 if (errorRetryLanes !== NoLanes) {
25944 lanes = errorRetryLanes;
25945 exitStatus = recoverFromConcurrentError(root, errorRetryLanes);
25946 }
25947 }
25948
25949 if (exitStatus === RootFatalErrored) {
25950 var fatalError = workInProgressRootFatalError;
25951 prepareFreshStack(root, NoLanes);
25952 markRootSuspended$1(root, lanes);
25953 ensureRootIsScheduled(root, now());
25954 throw fatalError;
25955 }
25956
25957 if (exitStatus === RootDidNotComplete) {
25958 throw new Error('Root did not complete. This is a bug in React.');
25959 } // We now have a consistent tree. Because this is a sync render, we
25960 // will commit it even if something suspended.
25961
25962
25963 var finishedWork = root.current.alternate;
25964 root.finishedWork = finishedWork;
25965 root.finishedLanes = lanes;
25966 commitRoot(root, workInProgressRootRecoverableErrors); // Before exiting, make sure there's a callback scheduled for the next
25967 // pending level.
25968
25969 ensureRootIsScheduled(root, now());
25970 return null;
25971 }
25972
25973 function flushRoot(root, lanes) {
25974 if (lanes !== NoLanes) {
25975 markRootEntangled(root, mergeLanes(lanes, SyncLane));
25976 ensureRootIsScheduled(root, now());
25977
25978 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
25979 resetRenderTimer();
25980 flushSyncCallbacks();
25981 }
25982 }
25983 }
25984 function batchedUpdates$1(fn, a) {
25985 var prevExecutionContext = executionContext;
25986 executionContext |= BatchedContext;
25987
25988 try {
25989 return fn(a);
25990 } finally {
25991 executionContext = prevExecutionContext; // If there were legacy sync updates, flush them at the end of the outer
25992 // most batchedUpdates-like method.
25993
25994 if (executionContext === NoContext && // Treat `act` as if it's inside `batchedUpdates`, even in legacy mode.
25995 !( ReactCurrentActQueue$1.isBatchingLegacy)) {
25996 resetRenderTimer();
25997 flushSyncCallbacksOnlyInLegacyMode();
25998 }
25999 }
26000 }
26001 function discreteUpdates(fn, a, b, c, d) {
26002 var previousPriority = getCurrentUpdatePriority();
26003 var prevTransition = ReactCurrentBatchConfig$3.transition;
26004
26005 try {
26006 ReactCurrentBatchConfig$3.transition = null;
26007 setCurrentUpdatePriority(DiscreteEventPriority);
26008 return fn(a, b, c, d);
26009 } finally {
26010 setCurrentUpdatePriority(previousPriority);
26011 ReactCurrentBatchConfig$3.transition = prevTransition;
26012
26013 if (executionContext === NoContext) {
26014 resetRenderTimer();
26015 }
26016 }
26017 } // Overload the definition to the two valid signatures.
26018 // Warning, this opts-out of checking the function body.
26019
26020 // eslint-disable-next-line no-redeclare
26021 function flushSync(fn) {
26022 // In legacy mode, we flush pending passive effects at the beginning of the
26023 // next event, not at the end of the previous one.
26024 if (rootWithPendingPassiveEffects !== null && rootWithPendingPassiveEffects.tag === LegacyRoot && (executionContext & (RenderContext | CommitContext)) === NoContext) {
26025 flushPassiveEffects();
26026 }
26027
26028 var prevExecutionContext = executionContext;
26029 executionContext |= BatchedContext;
26030 var prevTransition = ReactCurrentBatchConfig$3.transition;
26031 var previousPriority = getCurrentUpdatePriority();
26032
26033 try {
26034 ReactCurrentBatchConfig$3.transition = null;
26035 setCurrentUpdatePriority(DiscreteEventPriority);
26036
26037 if (fn) {
26038 return fn();
26039 } else {
26040 return undefined;
26041 }
26042 } finally {
26043 setCurrentUpdatePriority(previousPriority);
26044 ReactCurrentBatchConfig$3.transition = prevTransition;
26045 executionContext = prevExecutionContext; // Flush the immediate callbacks that were scheduled during this batch.
26046 // Note that this will happen even if batchedUpdates is higher up
26047 // the stack.
26048
26049 if ((executionContext & (RenderContext | CommitContext)) === NoContext) {
26050 flushSyncCallbacks();
26051 }
26052 }
26053 }
26054 function isAlreadyRendering() {
26055 // Used by the renderer to print a warning if certain APIs are called from
26056 // the wrong context.
26057 return (executionContext & (RenderContext | CommitContext)) !== NoContext;
26058 }
26059 function pushRenderLanes(fiber, lanes) {
26060 push(subtreeRenderLanesCursor, subtreeRenderLanes, fiber);
26061 subtreeRenderLanes = mergeLanes(subtreeRenderLanes, lanes);
26062 workInProgressRootIncludedLanes = mergeLanes(workInProgressRootIncludedLanes, lanes);
26063 }
26064 function popRenderLanes(fiber) {
26065 subtreeRenderLanes = subtreeRenderLanesCursor.current;
26066 pop(subtreeRenderLanesCursor, fiber);
26067 }
26068
26069 function prepareFreshStack(root, lanes) {
26070 root.finishedWork = null;
26071 root.finishedLanes = NoLanes;
26072 var timeoutHandle = root.timeoutHandle;
26073
26074 if (timeoutHandle !== noTimeout) {
26075 // The root previous suspended and scheduled a timeout to commit a fallback
26076 // state. Now that we have additional work, cancel the timeout.
26077 root.timeoutHandle = noTimeout; // $FlowFixMe Complains noTimeout is not a TimeoutID, despite the check above
26078
26079 cancelTimeout(timeoutHandle);
26080 }
26081
26082 if (workInProgress !== null) {
26083 var interruptedWork = workInProgress.return;
26084
26085 while (interruptedWork !== null) {
26086 var current = interruptedWork.alternate;
26087 unwindInterruptedWork(current, interruptedWork);
26088 interruptedWork = interruptedWork.return;
26089 }
26090 }
26091
26092 workInProgressRoot = root;
26093 var rootWorkInProgress = createWorkInProgress(root.current, null);
26094 workInProgress = rootWorkInProgress;
26095 workInProgressRootRenderLanes = subtreeRenderLanes = workInProgressRootIncludedLanes = lanes;
26096 workInProgressRootExitStatus = RootInProgress;
26097 workInProgressRootFatalError = null;
26098 workInProgressRootSkippedLanes = NoLanes;
26099 workInProgressRootInterleavedUpdatedLanes = NoLanes;
26100 workInProgressRootPingedLanes = NoLanes;
26101 workInProgressRootConcurrentErrors = null;
26102 workInProgressRootRecoverableErrors = null;
26103 enqueueInterleavedUpdates();
26104
26105 {
26106 ReactStrictModeWarnings.discardPendingWarnings();
26107 }
26108
26109 return rootWorkInProgress;
26110 }
26111
26112 function handleError(root, thrownValue) {
26113 do {
26114 var erroredWork = workInProgress;
26115
26116 try {
26117 // Reset module-level state that was set during the render phase.
26118 resetContextDependencies();
26119 resetHooksAfterThrow();
26120 resetCurrentFiber(); // TODO: I found and added this missing line while investigating a
26121 // separate issue. Write a regression test using string refs.
26122
26123 ReactCurrentOwner$2.current = null;
26124
26125 if (erroredWork === null || erroredWork.return === null) {
26126 // Expected to be working on a non-root fiber. This is a fatal error
26127 // because there's no ancestor that can handle it; the root is
26128 // supposed to capture all errors that weren't caught by an error
26129 // boundary.
26130 workInProgressRootExitStatus = RootFatalErrored;
26131 workInProgressRootFatalError = thrownValue; // Set `workInProgress` to null. This represents advancing to the next
26132 // sibling, or the parent if there are no siblings. But since the root
26133 // has no siblings nor a parent, we set it to null. Usually this is
26134 // handled by `completeUnitOfWork` or `unwindWork`, but since we're
26135 // intentionally not calling those, we need set it here.
26136 // TODO: Consider calling `unwindWork` to pop the contexts.
26137
26138 workInProgress = null;
26139 return;
26140 }
26141
26142 if (enableProfilerTimer && erroredWork.mode & ProfileMode) {
26143 // Record the time spent rendering before an error was thrown. This
26144 // avoids inaccurate Profiler durations in the case of a
26145 // suspended render.
26146 stopProfilerTimerIfRunningAndRecordDelta(erroredWork, true);
26147 }
26148
26149 if (enableSchedulingProfiler) {
26150 markComponentRenderStopped();
26151
26152 if (thrownValue !== null && typeof thrownValue === 'object' && typeof thrownValue.then === 'function') {
26153 var wakeable = thrownValue;
26154 markComponentSuspended(erroredWork, wakeable, workInProgressRootRenderLanes);
26155 } else {
26156 markComponentErrored(erroredWork, thrownValue, workInProgressRootRenderLanes);
26157 }
26158 }
26159
26160 throwException(root, erroredWork.return, erroredWork, thrownValue, workInProgressRootRenderLanes);
26161 completeUnitOfWork(erroredWork);
26162 } catch (yetAnotherThrownValue) {
26163 // Something in the return path also threw.
26164 thrownValue = yetAnotherThrownValue;
26165
26166 if (workInProgress === erroredWork && erroredWork !== null) {
26167 // If this boundary has already errored, then we had trouble processing
26168 // the error. Bubble it to the next boundary.
26169 erroredWork = erroredWork.return;
26170 workInProgress = erroredWork;
26171 } else {
26172 erroredWork = workInProgress;
26173 }
26174
26175 continue;
26176 } // Return to the normal work loop.
26177
26178
26179 return;
26180 } while (true);
26181 }
26182
26183 function pushDispatcher() {
26184 var prevDispatcher = ReactCurrentDispatcher$2.current;
26185 ReactCurrentDispatcher$2.current = ContextOnlyDispatcher;
26186
26187 if (prevDispatcher === null) {
26188 // The React isomorphic package does not include a default dispatcher.
26189 // Instead the first renderer will lazily attach one, in order to give
26190 // nicer error messages.
26191 return ContextOnlyDispatcher;
26192 } else {
26193 return prevDispatcher;
26194 }
26195 }
26196
26197 function popDispatcher(prevDispatcher) {
26198 ReactCurrentDispatcher$2.current = prevDispatcher;
26199 }
26200
26201 function markCommitTimeOfFallback() {
26202 globalMostRecentFallbackTime = now();
26203 }
26204 function markSkippedUpdateLanes(lane) {
26205 workInProgressRootSkippedLanes = mergeLanes(lane, workInProgressRootSkippedLanes);
26206 }
26207 function renderDidSuspend() {
26208 if (workInProgressRootExitStatus === RootInProgress) {
26209 workInProgressRootExitStatus = RootSuspended;
26210 }
26211 }
26212 function renderDidSuspendDelayIfPossible() {
26213 if (workInProgressRootExitStatus === RootInProgress || workInProgressRootExitStatus === RootSuspended || workInProgressRootExitStatus === RootErrored) {
26214 workInProgressRootExitStatus = RootSuspendedWithDelay;
26215 } // Check if there are updates that we skipped tree that might have unblocked
26216 // this render.
26217
26218
26219 if (workInProgressRoot !== null && (includesNonIdleWork(workInProgressRootSkippedLanes) || includesNonIdleWork(workInProgressRootInterleavedUpdatedLanes))) {
26220 // Mark the current render as suspended so that we switch to working on
26221 // the updates that were skipped. Usually we only suspend at the end of
26222 // the render phase.
26223 // TODO: We should probably always mark the root as suspended immediately
26224 // (inside this function), since by suspending at the end of the render
26225 // phase introduces a potential mistake where we suspend lanes that were
26226 // pinged or updated while we were rendering.
26227 markRootSuspended$1(workInProgressRoot, workInProgressRootRenderLanes);
26228 }
26229 }
26230 function renderDidError(error) {
26231 if (workInProgressRootExitStatus !== RootSuspendedWithDelay) {
26232 workInProgressRootExitStatus = RootErrored;
26233 }
26234
26235 if (workInProgressRootConcurrentErrors === null) {
26236 workInProgressRootConcurrentErrors = [error];
26237 } else {
26238 workInProgressRootConcurrentErrors.push(error);
26239 }
26240 } // Called during render to determine if anything has suspended.
26241 // Returns false if we're not sure.
26242
26243 function renderHasNotSuspendedYet() {
26244 // If something errored or completed, we can't really be sure,
26245 // so those are false.
26246 return workInProgressRootExitStatus === RootInProgress;
26247 }
26248
26249 function renderRootSync(root, lanes) {
26250 var prevExecutionContext = executionContext;
26251 executionContext |= RenderContext;
26252 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
26253 // and prepare a fresh one. Otherwise we'll continue where we left off.
26254
26255 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
26256 {
26257 if (isDevToolsPresent) {
26258 var memoizedUpdaters = root.memoizedUpdaters;
26259
26260 if (memoizedUpdaters.size > 0) {
26261 restorePendingUpdaters(root, workInProgressRootRenderLanes);
26262 memoizedUpdaters.clear();
26263 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
26264 // If we bailout on this work, we'll move them back (like above).
26265 // It's important to move them now in case the work spawns more work at the same priority with different updaters.
26266 // That way we can keep the current update and future updates separate.
26267
26268
26269 movePendingFibersToMemoized(root, lanes);
26270 }
26271 }
26272 prepareFreshStack(root, lanes);
26273 }
26274
26275 {
26276 markRenderStarted(lanes);
26277 }
26278
26279 do {
26280 try {
26281 workLoopSync();
26282 break;
26283 } catch (thrownValue) {
26284 handleError(root, thrownValue);
26285 }
26286 } while (true);
26287
26288 resetContextDependencies();
26289 executionContext = prevExecutionContext;
26290 popDispatcher(prevDispatcher);
26291
26292 if (workInProgress !== null) {
26293 // This is a sync render, so we should have finished the whole tree.
26294 throw new Error('Cannot commit an incomplete root. This error is likely caused by a ' + 'bug in React. Please file an issue.');
26295 }
26296
26297 {
26298 markRenderStopped();
26299 } // Set this to null to indicate there's no in-progress render.
26300
26301
26302 workInProgressRoot = null;
26303 workInProgressRootRenderLanes = NoLanes;
26304 return workInProgressRootExitStatus;
26305 } // The work loop is an extremely hot path. Tell Closure not to inline it.
26306
26307 /** @noinline */
26308
26309
26310 function workLoopSync() {
26311 // Already timed out, so perform work without checking if we need to yield.
26312 while (workInProgress !== null) {
26313 performUnitOfWork(workInProgress);
26314 }
26315 }
26316
26317 function renderRootConcurrent(root, lanes) {
26318 var prevExecutionContext = executionContext;
26319 executionContext |= RenderContext;
26320 var prevDispatcher = pushDispatcher(); // If the root or lanes have changed, throw out the existing stack
26321 // and prepare a fresh one. Otherwise we'll continue where we left off.
26322
26323 if (workInProgressRoot !== root || workInProgressRootRenderLanes !== lanes) {
26324 {
26325 if (isDevToolsPresent) {
26326 var memoizedUpdaters = root.memoizedUpdaters;
26327
26328 if (memoizedUpdaters.size > 0) {
26329 restorePendingUpdaters(root, workInProgressRootRenderLanes);
26330 memoizedUpdaters.clear();
26331 } // At this point, move Fibers that scheduled the upcoming work from the Map to the Set.
26332 // If we bailout on this work, we'll move them back (like above).
26333 // It's important to move them now in case the work spawns more work at the same priority with different updaters.
26334 // That way we can keep the current update and future updates separate.
26335
26336
26337 movePendingFibersToMemoized(root, lanes);
26338 }
26339 }
26340 resetRenderTimer();
26341 prepareFreshStack(root, lanes);
26342 }
26343
26344 {
26345 markRenderStarted(lanes);
26346 }
26347
26348 do {
26349 try {
26350 workLoopConcurrent();
26351 break;
26352 } catch (thrownValue) {
26353 handleError(root, thrownValue);
26354 }
26355 } while (true);
26356
26357 resetContextDependencies();
26358 popDispatcher(prevDispatcher);
26359 executionContext = prevExecutionContext;
26360
26361
26362 if (workInProgress !== null) {
26363 // Still work remaining.
26364 {
26365 markRenderYielded();
26366 }
26367
26368 return RootInProgress;
26369 } else {
26370 // Completed the tree.
26371 {
26372 markRenderStopped();
26373 } // Set this to null to indicate there's no in-progress render.
26374
26375
26376 workInProgressRoot = null;
26377 workInProgressRootRenderLanes = NoLanes; // Return the final exit status.
26378
26379 return workInProgressRootExitStatus;
26380 }
26381 }
26382 /** @noinline */
26383
26384
26385 function workLoopConcurrent() {
26386 // Perform work until Scheduler asks us to yield
26387 while (workInProgress !== null && !shouldYield()) {
26388 performUnitOfWork(workInProgress);
26389 }
26390 }
26391
26392 function performUnitOfWork(unitOfWork) {
26393 // The current, flushed, state of this fiber is the alternate. Ideally
26394 // nothing should rely on this, but relying on it here means that we don't
26395 // need an additional field on the work in progress.
26396 var current = unitOfWork.alternate;
26397 setCurrentFiber(unitOfWork);
26398 var next;
26399
26400 if ( (unitOfWork.mode & ProfileMode) !== NoMode) {
26401 startProfilerTimer(unitOfWork);
26402 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
26403 stopProfilerTimerIfRunningAndRecordDelta(unitOfWork, true);
26404 } else {
26405 next = beginWork$1(current, unitOfWork, subtreeRenderLanes);
26406 }
26407
26408 resetCurrentFiber();
26409 unitOfWork.memoizedProps = unitOfWork.pendingProps;
26410
26411 if (next === null) {
26412 // If this doesn't spawn new work, complete the current work.
26413 completeUnitOfWork(unitOfWork);
26414 } else {
26415 workInProgress = next;
26416 }
26417
26418 ReactCurrentOwner$2.current = null;
26419 }
26420
26421 function completeUnitOfWork(unitOfWork) {
26422 // Attempt to complete the current unit of work, then move to the next
26423 // sibling. If there are no more siblings, return to the parent fiber.
26424 var completedWork = unitOfWork;
26425
26426 do {
26427 // The current, flushed, state of this fiber is the alternate. Ideally
26428 // nothing should rely on this, but relying on it here means that we don't
26429 // need an additional field on the work in progress.
26430 var current = completedWork.alternate;
26431 var returnFiber = completedWork.return; // Check if the work completed or if something threw.
26432
26433 if ((completedWork.flags & Incomplete) === NoFlags) {
26434 setCurrentFiber(completedWork);
26435 var next = void 0;
26436
26437 if ( (completedWork.mode & ProfileMode) === NoMode) {
26438 next = completeWork(current, completedWork, subtreeRenderLanes);
26439 } else {
26440 startProfilerTimer(completedWork);
26441 next = completeWork(current, completedWork, subtreeRenderLanes); // Update render duration assuming we didn't error.
26442
26443 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false);
26444 }
26445
26446 resetCurrentFiber();
26447
26448 if (next !== null) {
26449 // Completing this fiber spawned new work. Work on that next.
26450 workInProgress = next;
26451 return;
26452 }
26453 } else {
26454 // This fiber did not complete because something threw. Pop values off
26455 // the stack without entering the complete phase. If this is a boundary,
26456 // capture values if possible.
26457 var _next = unwindWork(current, completedWork); // Because this fiber did not complete, don't reset its lanes.
26458
26459
26460 if (_next !== null) {
26461 // If completing this work spawned new work, do that next. We'll come
26462 // back here again.
26463 // Since we're restarting, remove anything that is not a host effect
26464 // from the effect tag.
26465 _next.flags &= HostEffectMask;
26466 workInProgress = _next;
26467 return;
26468 }
26469
26470 if ( (completedWork.mode & ProfileMode) !== NoMode) {
26471 // Record the render duration for the fiber that errored.
26472 stopProfilerTimerIfRunningAndRecordDelta(completedWork, false); // Include the time spent working on failed children before continuing.
26473
26474 var actualDuration = completedWork.actualDuration;
26475 var child = completedWork.child;
26476
26477 while (child !== null) {
26478 actualDuration += child.actualDuration;
26479 child = child.sibling;
26480 }
26481
26482 completedWork.actualDuration = actualDuration;
26483 }
26484
26485 if (returnFiber !== null) {
26486 // Mark the parent fiber as incomplete and clear its subtree flags.
26487 returnFiber.flags |= Incomplete;
26488 returnFiber.subtreeFlags = NoFlags;
26489 returnFiber.deletions = null;
26490 } else {
26491 // We've unwound all the way to the root.
26492 workInProgressRootExitStatus = RootDidNotComplete;
26493 workInProgress = null;
26494 return;
26495 }
26496 }
26497
26498 var siblingFiber = completedWork.sibling;
26499
26500 if (siblingFiber !== null) {
26501 // If there is more work to do in this returnFiber, do that next.
26502 workInProgress = siblingFiber;
26503 return;
26504 } // Otherwise, return to the parent
26505
26506
26507 completedWork = returnFiber; // Update the next thing we're working on in case something throws.
26508
26509 workInProgress = completedWork;
26510 } while (completedWork !== null); // We've reached the root.
26511
26512
26513 if (workInProgressRootExitStatus === RootInProgress) {
26514 workInProgressRootExitStatus = RootCompleted;
26515 }
26516 }
26517
26518 function commitRoot(root, recoverableErrors) {
26519 // TODO: This no longer makes any sense. We already wrap the mutation and
26520 // layout phases. Should be able to remove.
26521 var previousUpdateLanePriority = getCurrentUpdatePriority();
26522 var prevTransition = ReactCurrentBatchConfig$3.transition;
26523
26524 try {
26525 ReactCurrentBatchConfig$3.transition = null;
26526 setCurrentUpdatePriority(DiscreteEventPriority);
26527 commitRootImpl(root, recoverableErrors, previousUpdateLanePriority);
26528 } finally {
26529 ReactCurrentBatchConfig$3.transition = prevTransition;
26530 setCurrentUpdatePriority(previousUpdateLanePriority);
26531 }
26532
26533 return null;
26534 }
26535
26536 function commitRootImpl(root, recoverableErrors, renderPriorityLevel) {
26537 do {
26538 // `flushPassiveEffects` will call `flushSyncUpdateQueue` at the end, which
26539 // means `flushPassiveEffects` will sometimes result in additional
26540 // passive effects. So we need to keep flushing in a loop until there are
26541 // no more pending effects.
26542 // TODO: Might be better if `flushPassiveEffects` did not automatically
26543 // flush synchronous work at the end, to avoid factoring hazards like this.
26544 flushPassiveEffects();
26545 } while (rootWithPendingPassiveEffects !== null);
26546
26547 flushRenderPhaseStrictModeWarningsInDEV();
26548
26549 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
26550 throw new Error('Should not already be working.');
26551 }
26552
26553 var finishedWork = root.finishedWork;
26554 var lanes = root.finishedLanes;
26555
26556 {
26557 markCommitStarted(lanes);
26558 }
26559
26560 if (finishedWork === null) {
26561
26562 {
26563 markCommitStopped();
26564 }
26565
26566 return null;
26567 } else {
26568 {
26569 if (lanes === NoLanes) {
26570 error('root.finishedLanes should not be empty during a commit. This is a ' + 'bug in React.');
26571 }
26572 }
26573 }
26574
26575 root.finishedWork = null;
26576 root.finishedLanes = NoLanes;
26577
26578 if (finishedWork === root.current) {
26579 throw new Error('Cannot commit the same tree as before. This error is likely caused by ' + 'a bug in React. Please file an issue.');
26580 } // commitRoot never returns a continuation; it always finishes synchronously.
26581 // So we can clear these now to allow a new callback to be scheduled.
26582
26583
26584 root.callbackNode = null;
26585 root.callbackPriority = NoLane; // Update the first and last pending times on this root. The new first
26586 // pending time is whatever is left on the root fiber.
26587
26588 var remainingLanes = mergeLanes(finishedWork.lanes, finishedWork.childLanes);
26589 markRootFinished(root, remainingLanes);
26590
26591 if (root === workInProgressRoot) {
26592 // We can reset these now that they are finished.
26593 workInProgressRoot = null;
26594 workInProgress = null;
26595 workInProgressRootRenderLanes = NoLanes;
26596 } // If there are pending passive effects, schedule a callback to process them.
26597 // Do this as early as possible, so it is queued before anything else that
26598 // might get scheduled in the commit phase. (See #16714.)
26599 // TODO: Delete all other places that schedule the passive effect callback
26600 // They're redundant.
26601
26602
26603 if ((finishedWork.subtreeFlags & PassiveMask) !== NoFlags || (finishedWork.flags & PassiveMask) !== NoFlags) {
26604 if (!rootDoesHavePassiveEffects) {
26605 rootDoesHavePassiveEffects = true;
26606 scheduleCallback$1(NormalPriority, function () {
26607 flushPassiveEffects(); // This render triggered passive effects: release the root cache pool
26608 // *after* passive effects fire to avoid freeing a cache pool that may
26609 // be referenced by a node in the tree (HostRoot, Cache boundary etc)
26610
26611 return null;
26612 });
26613 }
26614 } // Check if there are any effects in the whole tree.
26615 // TODO: This is left over from the effect list implementation, where we had
26616 // to check for the existence of `firstEffect` to satisfy Flow. I think the
26617 // only other reason this optimization exists is because it affects profiling.
26618 // Reconsider whether this is necessary.
26619
26620
26621 var subtreeHasEffects = (finishedWork.subtreeFlags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
26622 var rootHasEffect = (finishedWork.flags & (BeforeMutationMask | MutationMask | LayoutMask | PassiveMask)) !== NoFlags;
26623
26624 if (subtreeHasEffects || rootHasEffect) {
26625 var prevTransition = ReactCurrentBatchConfig$3.transition;
26626 ReactCurrentBatchConfig$3.transition = null;
26627 var previousPriority = getCurrentUpdatePriority();
26628 setCurrentUpdatePriority(DiscreteEventPriority);
26629 var prevExecutionContext = executionContext;
26630 executionContext |= CommitContext; // Reset this to null before calling lifecycles
26631
26632 ReactCurrentOwner$2.current = null; // The commit phase is broken into several sub-phases. We do a separate pass
26633 // of the effect list for each phase: all mutation effects come before all
26634 // layout effects, and so on.
26635 // The first phase a "before mutation" phase. We use this phase to read the
26636 // state of the host tree right before we mutate it. This is where
26637 // getSnapshotBeforeUpdate is called.
26638
26639 var shouldFireAfterActiveInstanceBlur = commitBeforeMutationEffects(root, finishedWork);
26640
26641 {
26642 // Mark the current commit time to be shared by all Profilers in this
26643 // batch. This enables them to be grouped later.
26644 recordCommitTime();
26645 }
26646
26647
26648 commitMutationEffects(root, finishedWork, lanes);
26649
26650 resetAfterCommit(root.containerInfo); // The work-in-progress tree is now the current tree. This must come after
26651 // the mutation phase, so that the previous tree is still current during
26652 // componentWillUnmount, but before the layout phase, so that the finished
26653 // work is current during componentDidMount/Update.
26654
26655 root.current = finishedWork; // The next phase is the layout phase, where we call effects that read
26656
26657 {
26658 markLayoutEffectsStarted(lanes);
26659 }
26660
26661 commitLayoutEffects(finishedWork, root, lanes);
26662
26663 {
26664 markLayoutEffectsStopped();
26665 }
26666 // opportunity to paint.
26667
26668
26669 requestPaint();
26670 executionContext = prevExecutionContext; // Reset the priority to the previous non-sync value.
26671
26672 setCurrentUpdatePriority(previousPriority);
26673 ReactCurrentBatchConfig$3.transition = prevTransition;
26674 } else {
26675 // No effects.
26676 root.current = finishedWork; // Measure these anyway so the flamegraph explicitly shows that there were
26677 // no effects.
26678 // TODO: Maybe there's a better way to report this.
26679
26680 {
26681 recordCommitTime();
26682 }
26683 }
26684
26685 var rootDidHavePassiveEffects = rootDoesHavePassiveEffects;
26686
26687 if (rootDoesHavePassiveEffects) {
26688 // This commit has passive effects. Stash a reference to them. But don't
26689 // schedule a callback until after flushing layout work.
26690 rootDoesHavePassiveEffects = false;
26691 rootWithPendingPassiveEffects = root;
26692 pendingPassiveEffectsLanes = lanes;
26693 } // Read this again, since an effect might have updated it
26694
26695
26696 remainingLanes = root.pendingLanes; // Check if there's remaining work on this root
26697 // TODO: This is part of the `componentDidCatch` implementation. Its purpose
26698 // is to detect whether something might have called setState inside
26699 // `componentDidCatch`. The mechanism is known to be flawed because `setState`
26700 // inside `componentDidCatch` is itself flawed — that's why we recommend
26701 // `getDerivedStateFromError` instead. However, it could be improved by
26702 // checking if remainingLanes includes Sync work, instead of whether there's
26703 // any work remaining at all (which would also include stuff like Suspense
26704 // retries or transitions). It's been like this for a while, though, so fixing
26705 // it probably isn't that urgent.
26706
26707 if (remainingLanes === NoLanes) {
26708 // If there's no remaining work, we can clear the set of already failed
26709 // error boundaries.
26710 legacyErrorBoundariesThatAlreadyFailed = null;
26711 }
26712
26713 {
26714 if (!rootDidHavePassiveEffects) {
26715 commitDoubleInvokeEffectsInDEV(root.current, false);
26716 }
26717 }
26718
26719 onCommitRoot(finishedWork.stateNode, renderPriorityLevel);
26720
26721 {
26722 if (isDevToolsPresent) {
26723 root.memoizedUpdaters.clear();
26724 }
26725 }
26726
26727 {
26728 onCommitRoot$1();
26729 } // Always call this before exiting `commitRoot`, to ensure that any
26730 // additional work on this root is scheduled.
26731
26732
26733 ensureRootIsScheduled(root, now());
26734
26735 if (recoverableErrors !== null) {
26736 // There were errors during this render, but recovered from them without
26737 // needing to surface it to the UI. We log them here.
26738 var onRecoverableError = root.onRecoverableError;
26739
26740 for (var i = 0; i < recoverableErrors.length; i++) {
26741 var recoverableError = recoverableErrors[i];
26742 onRecoverableError(recoverableError);
26743 }
26744 }
26745
26746 if (hasUncaughtError) {
26747 hasUncaughtError = false;
26748 var error$1 = firstUncaughtError;
26749 firstUncaughtError = null;
26750 throw error$1;
26751 } // If the passive effects are the result of a discrete render, flush them
26752 // synchronously at the end of the current task so that the result is
26753 // immediately observable. Otherwise, we assume that they are not
26754 // order-dependent and do not need to be observed by external systems, so we
26755 // can wait until after paint.
26756 // TODO: We can optimize this by not scheduling the callback earlier. Since we
26757 // currently schedule the callback in multiple places, will wait until those
26758 // are consolidated.
26759
26760
26761 if (includesSomeLane(pendingPassiveEffectsLanes, SyncLane) && root.tag !== LegacyRoot) {
26762 flushPassiveEffects();
26763 } // Read this again, since a passive effect might have updated it
26764
26765
26766 remainingLanes = root.pendingLanes;
26767
26768 if (includesSomeLane(remainingLanes, SyncLane)) {
26769 {
26770 markNestedUpdateScheduled();
26771 } // Count the number of times the root synchronously re-renders without
26772 // finishing. If there are too many, it indicates an infinite update loop.
26773
26774
26775 if (root === rootWithNestedUpdates) {
26776 nestedUpdateCount++;
26777 } else {
26778 nestedUpdateCount = 0;
26779 rootWithNestedUpdates = root;
26780 }
26781 } else {
26782 nestedUpdateCount = 0;
26783 } // If layout work was scheduled, flush it now.
26784
26785
26786 flushSyncCallbacks();
26787
26788 {
26789 markCommitStopped();
26790 }
26791
26792 return null;
26793 }
26794
26795 function flushPassiveEffects() {
26796 // Returns whether passive effects were flushed.
26797 // TODO: Combine this check with the one in flushPassiveEFfectsImpl. We should
26798 // probably just combine the two functions. I believe they were only separate
26799 // in the first place because we used to wrap it with
26800 // `Scheduler.runWithPriority`, which accepts a function. But now we track the
26801 // priority within React itself, so we can mutate the variable directly.
26802 if (rootWithPendingPassiveEffects !== null) {
26803 var renderPriority = lanesToEventPriority(pendingPassiveEffectsLanes);
26804 var priority = lowerEventPriority(DefaultEventPriority, renderPriority);
26805 var prevTransition = ReactCurrentBatchConfig$3.transition;
26806 var previousPriority = getCurrentUpdatePriority();
26807
26808 try {
26809 ReactCurrentBatchConfig$3.transition = null;
26810 setCurrentUpdatePriority(priority);
26811 return flushPassiveEffectsImpl();
26812 } finally {
26813 setCurrentUpdatePriority(previousPriority);
26814 ReactCurrentBatchConfig$3.transition = prevTransition; // Once passive effects have run for the tree - giving components a
26815 }
26816 }
26817
26818 return false;
26819 }
26820 function enqueuePendingPassiveProfilerEffect(fiber) {
26821 {
26822 pendingPassiveProfilerEffects.push(fiber);
26823
26824 if (!rootDoesHavePassiveEffects) {
26825 rootDoesHavePassiveEffects = true;
26826 scheduleCallback$1(NormalPriority, function () {
26827 flushPassiveEffects();
26828 return null;
26829 });
26830 }
26831 }
26832 }
26833
26834 function flushPassiveEffectsImpl() {
26835 if (rootWithPendingPassiveEffects === null) {
26836 return false;
26837 }
26838
26839 var root = rootWithPendingPassiveEffects;
26840 var lanes = pendingPassiveEffectsLanes;
26841 rootWithPendingPassiveEffects = null; // TODO: This is sometimes out of sync with rootWithPendingPassiveEffects.
26842 // Figure out why and fix it. It's not causing any known issues (probably
26843 // because it's only used for profiling), but it's a refactor hazard.
26844
26845 pendingPassiveEffectsLanes = NoLanes;
26846
26847 if ((executionContext & (RenderContext | CommitContext)) !== NoContext) {
26848 throw new Error('Cannot flush passive effects while already rendering.');
26849 }
26850
26851 {
26852 markPassiveEffectsStarted(lanes);
26853 }
26854
26855 var prevExecutionContext = executionContext;
26856 executionContext |= CommitContext;
26857 commitPassiveUnmountEffects(root.current);
26858 commitPassiveMountEffects(root, root.current); // TODO: Move to commitPassiveMountEffects
26859
26860 {
26861 var profilerEffects = pendingPassiveProfilerEffects;
26862 pendingPassiveProfilerEffects = [];
26863
26864 for (var i = 0; i < profilerEffects.length; i++) {
26865 var _fiber = profilerEffects[i];
26866 commitPassiveEffectDurations(root, _fiber);
26867 }
26868 }
26869
26870 {
26871 markPassiveEffectsStopped();
26872 }
26873
26874 {
26875 commitDoubleInvokeEffectsInDEV(root.current, true);
26876 }
26877
26878 executionContext = prevExecutionContext;
26879 flushSyncCallbacks(); // If additional passive effects were scheduled, increment a counter. If this
26880 // exceeds the limit, we'll fire a warning.
26881
26882 nestedPassiveUpdateCount = rootWithPendingPassiveEffects === null ? 0 : nestedPassiveUpdateCount + 1; // TODO: Move to commitPassiveMountEffects
26883
26884 onPostCommitRoot(root);
26885
26886 {
26887 var stateNode = root.current.stateNode;
26888 stateNode.effectDuration = 0;
26889 stateNode.passiveEffectDuration = 0;
26890 }
26891
26892 return true;
26893 }
26894
26895 function isAlreadyFailedLegacyErrorBoundary(instance) {
26896 return legacyErrorBoundariesThatAlreadyFailed !== null && legacyErrorBoundariesThatAlreadyFailed.has(instance);
26897 }
26898 function markLegacyErrorBoundaryAsFailed(instance) {
26899 if (legacyErrorBoundariesThatAlreadyFailed === null) {
26900 legacyErrorBoundariesThatAlreadyFailed = new Set([instance]);
26901 } else {
26902 legacyErrorBoundariesThatAlreadyFailed.add(instance);
26903 }
26904 }
26905
26906 function prepareToThrowUncaughtError(error) {
26907 if (!hasUncaughtError) {
26908 hasUncaughtError = true;
26909 firstUncaughtError = error;
26910 }
26911 }
26912
26913 var onUncaughtError = prepareToThrowUncaughtError;
26914
26915 function captureCommitPhaseErrorOnRoot(rootFiber, sourceFiber, error) {
26916 var errorInfo = createCapturedValue(error, sourceFiber);
26917 var update = createRootErrorUpdate(rootFiber, errorInfo, SyncLane);
26918 enqueueUpdate(rootFiber, update);
26919 var eventTime = requestEventTime();
26920 var root = markUpdateLaneFromFiberToRoot(rootFiber, SyncLane);
26921
26922 if (root !== null) {
26923 markRootUpdated(root, SyncLane, eventTime);
26924 ensureRootIsScheduled(root, eventTime);
26925 }
26926 }
26927
26928 function captureCommitPhaseError(sourceFiber, nearestMountedAncestor, error$1) {
26929 if (sourceFiber.tag === HostRoot) {
26930 // Error was thrown at the root. There is no parent, so the root
26931 // itself should capture it.
26932 captureCommitPhaseErrorOnRoot(sourceFiber, sourceFiber, error$1);
26933 return;
26934 }
26935
26936 var fiber = null;
26937
26938 {
26939 fiber = nearestMountedAncestor;
26940 }
26941
26942 while (fiber !== null) {
26943 if (fiber.tag === HostRoot) {
26944 captureCommitPhaseErrorOnRoot(fiber, sourceFiber, error$1);
26945 return;
26946 } else if (fiber.tag === ClassComponent) {
26947 var ctor = fiber.type;
26948 var instance = fiber.stateNode;
26949
26950 if (typeof ctor.getDerivedStateFromError === 'function' || typeof instance.componentDidCatch === 'function' && !isAlreadyFailedLegacyErrorBoundary(instance)) {
26951 var errorInfo = createCapturedValue(error$1, sourceFiber);
26952 var update = createClassErrorUpdate(fiber, errorInfo, SyncLane);
26953 enqueueUpdate(fiber, update);
26954 var eventTime = requestEventTime();
26955 var root = markUpdateLaneFromFiberToRoot(fiber, SyncLane);
26956
26957 if (root !== null) {
26958 markRootUpdated(root, SyncLane, eventTime);
26959 ensureRootIsScheduled(root, eventTime);
26960 }
26961
26962 return;
26963 }
26964 }
26965
26966 fiber = fiber.return;
26967 }
26968
26969 {
26970 // TODO: Until we re-land skipUnmountedBoundaries (see #20147), this warning
26971 // will fire for errors that are thrown by destroy functions inside deleted
26972 // trees. What it should instead do is propagate the error to the parent of
26973 // the deleted tree. In the meantime, do not add this warning to the
26974 // allowlist; this is only for our internal use.
26975 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);
26976 }
26977 }
26978 function pingSuspendedRoot(root, wakeable, pingedLanes) {
26979 var pingCache = root.pingCache;
26980
26981 if (pingCache !== null) {
26982 // The wakeable resolved, so we no longer need to memoize, because it will
26983 // never be thrown again.
26984 pingCache.delete(wakeable);
26985 }
26986
26987 var eventTime = requestEventTime();
26988 markRootPinged(root, pingedLanes);
26989 warnIfSuspenseResolutionNotWrappedWithActDEV(root);
26990
26991 if (workInProgressRoot === root && isSubsetOfLanes(workInProgressRootRenderLanes, pingedLanes)) {
26992 // Received a ping at the same priority level at which we're currently
26993 // rendering. We might want to restart this render. This should mirror
26994 // the logic of whether or not a root suspends once it completes.
26995 // TODO: If we're rendering sync either due to Sync, Batched or expired,
26996 // we should probably never restart.
26997 // If we're suspended with delay, or if it's a retry, we'll always suspend
26998 // so we can always restart.
26999 if (workInProgressRootExitStatus === RootSuspendedWithDelay || workInProgressRootExitStatus === RootSuspended && includesOnlyRetries(workInProgressRootRenderLanes) && now() - globalMostRecentFallbackTime < FALLBACK_THROTTLE_MS) {
27000 // Restart from the root.
27001 prepareFreshStack(root, NoLanes);
27002 } else {
27003 // Even though we can't restart right now, we might get an
27004 // opportunity later. So we mark this render as having a ping.
27005 workInProgressRootPingedLanes = mergeLanes(workInProgressRootPingedLanes, pingedLanes);
27006 }
27007 }
27008
27009 ensureRootIsScheduled(root, eventTime);
27010 }
27011
27012 function retryTimedOutBoundary(boundaryFiber, retryLane) {
27013 // The boundary fiber (a Suspense component or SuspenseList component)
27014 // previously was rendered in its fallback state. One of the promises that
27015 // suspended it has resolved, which means at least part of the tree was
27016 // likely unblocked. Try rendering again, at a new lanes.
27017 if (retryLane === NoLane) {
27018 // TODO: Assign this to `suspenseState.retryLane`? to avoid
27019 // unnecessary entanglement?
27020 retryLane = requestRetryLane(boundaryFiber);
27021 } // TODO: Special case idle priority?
27022
27023
27024 var eventTime = requestEventTime();
27025 var root = markUpdateLaneFromFiberToRoot(boundaryFiber, retryLane);
27026
27027 if (root !== null) {
27028 markRootUpdated(root, retryLane, eventTime);
27029 ensureRootIsScheduled(root, eventTime);
27030 }
27031 }
27032
27033 function retryDehydratedSuspenseBoundary(boundaryFiber) {
27034 var suspenseState = boundaryFiber.memoizedState;
27035 var retryLane = NoLane;
27036
27037 if (suspenseState !== null) {
27038 retryLane = suspenseState.retryLane;
27039 }
27040
27041 retryTimedOutBoundary(boundaryFiber, retryLane);
27042 }
27043 function resolveRetryWakeable(boundaryFiber, wakeable) {
27044 var retryLane = NoLane; // Default
27045
27046 var retryCache;
27047
27048 {
27049 switch (boundaryFiber.tag) {
27050 case SuspenseComponent:
27051 retryCache = boundaryFiber.stateNode;
27052 var suspenseState = boundaryFiber.memoizedState;
27053
27054 if (suspenseState !== null) {
27055 retryLane = suspenseState.retryLane;
27056 }
27057
27058 break;
27059
27060 case SuspenseListComponent:
27061 retryCache = boundaryFiber.stateNode;
27062 break;
27063
27064 default:
27065 throw new Error('Pinged unknown suspense boundary type. ' + 'This is probably a bug in React.');
27066 }
27067 }
27068
27069 if (retryCache !== null) {
27070 // The wakeable resolved, so we no longer need to memoize, because it will
27071 // never be thrown again.
27072 retryCache.delete(wakeable);
27073 }
27074
27075 retryTimedOutBoundary(boundaryFiber, retryLane);
27076 } // Computes the next Just Noticeable Difference (JND) boundary.
27077 // The theory is that a person can't tell the difference between small differences in time.
27078 // Therefore, if we wait a bit longer than necessary that won't translate to a noticeable
27079 // difference in the experience. However, waiting for longer might mean that we can avoid
27080 // showing an intermediate loading state. The longer we have already waited, the harder it
27081 // is to tell small differences in time. Therefore, the longer we've already waited,
27082 // the longer we can wait additionally. At some point we have to give up though.
27083 // We pick a train model where the next boundary commits at a consistent schedule.
27084 // These particular numbers are vague estimates. We expect to adjust them based on research.
27085
27086 function jnd(timeElapsed) {
27087 return timeElapsed < 120 ? 120 : timeElapsed < 480 ? 480 : timeElapsed < 1080 ? 1080 : timeElapsed < 1920 ? 1920 : timeElapsed < 3000 ? 3000 : timeElapsed < 4320 ? 4320 : ceil(timeElapsed / 1960) * 1960;
27088 }
27089
27090 function checkForNestedUpdates() {
27091 if (nestedUpdateCount > NESTED_UPDATE_LIMIT) {
27092 nestedUpdateCount = 0;
27093 rootWithNestedUpdates = null;
27094 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.');
27095 }
27096
27097 {
27098 if (nestedPassiveUpdateCount > NESTED_PASSIVE_UPDATE_LIMIT) {
27099 nestedPassiveUpdateCount = 0;
27100
27101 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.');
27102 }
27103 }
27104 }
27105
27106 function flushRenderPhaseStrictModeWarningsInDEV() {
27107 {
27108 ReactStrictModeWarnings.flushLegacyContextWarning();
27109
27110 {
27111 ReactStrictModeWarnings.flushPendingUnsafeLifecycleWarnings();
27112 }
27113 }
27114 }
27115
27116 function commitDoubleInvokeEffectsInDEV(fiber, hasPassiveEffects) {
27117 {
27118 // TODO (StrictEffects) Should we set a marker on the root if it contains strict effects
27119 // so we don't traverse unnecessarily? similar to subtreeFlags but just at the root level.
27120 // Maybe not a big deal since this is DEV only behavior.
27121 setCurrentFiber(fiber);
27122 invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectUnmountInDEV);
27123
27124 if (hasPassiveEffects) {
27125 invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectUnmountInDEV);
27126 }
27127
27128 invokeEffectsInDev(fiber, MountLayoutDev, invokeLayoutEffectMountInDEV);
27129
27130 if (hasPassiveEffects) {
27131 invokeEffectsInDev(fiber, MountPassiveDev, invokePassiveEffectMountInDEV);
27132 }
27133
27134 resetCurrentFiber();
27135 }
27136 }
27137
27138 function invokeEffectsInDev(firstChild, fiberFlags, invokeEffectFn) {
27139 {
27140 // We don't need to re-check StrictEffectsMode here.
27141 // This function is only called if that check has already passed.
27142 var current = firstChild;
27143 var subtreeRoot = null;
27144
27145 while (current !== null) {
27146 var primarySubtreeFlag = current.subtreeFlags & fiberFlags;
27147
27148 if (current !== subtreeRoot && current.child !== null && primarySubtreeFlag !== NoFlags) {
27149 current = current.child;
27150 } else {
27151 if ((current.flags & fiberFlags) !== NoFlags) {
27152 invokeEffectFn(current);
27153 }
27154
27155 if (current.sibling !== null) {
27156 current = current.sibling;
27157 } else {
27158 current = subtreeRoot = current.return;
27159 }
27160 }
27161 }
27162 }
27163 }
27164
27165 var didWarnStateUpdateForNotYetMountedComponent = null;
27166
27167 function warnAboutUpdateOnNotYetMountedFiberInDEV(fiber) {
27168 {
27169 if ((executionContext & RenderContext) !== NoContext) {
27170 // We let the other warning about render phase updates deal with this one.
27171 return;
27172 }
27173
27174 if (!(fiber.mode & ConcurrentMode)) {
27175 return;
27176 }
27177
27178 var tag = fiber.tag;
27179
27180 if (tag !== IndeterminateComponent && tag !== HostRoot && tag !== ClassComponent && tag !== FunctionComponent && tag !== ForwardRef && tag !== MemoComponent && tag !== SimpleMemoComponent) {
27181 // Only warn for user-defined components, not internal ones like Suspense.
27182 return;
27183 } // We show the whole stack but dedupe on the top component's name because
27184 // the problematic code almost always lies inside that component.
27185
27186
27187 var componentName = getComponentNameFromFiber(fiber) || 'ReactComponent';
27188
27189 if (didWarnStateUpdateForNotYetMountedComponent !== null) {
27190 if (didWarnStateUpdateForNotYetMountedComponent.has(componentName)) {
27191 return;
27192 }
27193
27194 didWarnStateUpdateForNotYetMountedComponent.add(componentName);
27195 } else {
27196 didWarnStateUpdateForNotYetMountedComponent = new Set([componentName]);
27197 }
27198
27199 var previousFiber = current;
27200
27201 try {
27202 setCurrentFiber(fiber);
27203
27204 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.');
27205 } finally {
27206 if (previousFiber) {
27207 setCurrentFiber(fiber);
27208 } else {
27209 resetCurrentFiber();
27210 }
27211 }
27212 }
27213 }
27214
27215 var beginWork$1;
27216
27217 {
27218 var dummyFiber = null;
27219
27220 beginWork$1 = function (current, unitOfWork, lanes) {
27221 // If a component throws an error, we replay it again in a synchronously
27222 // dispatched event, so that the debugger will treat it as an uncaught
27223 // error See ReactErrorUtils for more information.
27224 // Before entering the begin phase, copy the work-in-progress onto a dummy
27225 // fiber. If beginWork throws, we'll use this to reset the state.
27226 var originalWorkInProgressCopy = assignFiberPropertiesInDEV(dummyFiber, unitOfWork);
27227
27228 try {
27229 return beginWork(current, unitOfWork, lanes);
27230 } catch (originalError) {
27231 if (originalError !== null && typeof originalError === 'object' && typeof originalError.then === 'function') {
27232 // Don't replay promises. Treat everything else like an error.
27233 throw originalError;
27234 } // Keep this code in sync with handleError; any changes here must have
27235 // corresponding changes there.
27236
27237
27238 resetContextDependencies();
27239 resetHooksAfterThrow(); // Don't reset current debug fiber, since we're about to work on the
27240 // same fiber again.
27241 // Unwind the failed stack frame
27242
27243 unwindInterruptedWork(current, unitOfWork); // Restore the original properties of the fiber.
27244
27245 assignFiberPropertiesInDEV(unitOfWork, originalWorkInProgressCopy);
27246
27247 if ( unitOfWork.mode & ProfileMode) {
27248 // Reset the profiler timer.
27249 startProfilerTimer(unitOfWork);
27250 } // Run beginWork again.
27251
27252
27253 invokeGuardedCallback(null, beginWork, null, current, unitOfWork, lanes);
27254
27255 if (hasCaughtError()) {
27256 var replayError = clearCaughtError();
27257
27258 if (typeof replayError === 'object' && replayError !== null && replayError._suppressLogging && typeof originalError === 'object' && originalError !== null && !originalError._suppressLogging) {
27259 // If suppressed, let the flag carry over to the original error which is the one we'll rethrow.
27260 originalError._suppressLogging = true;
27261 }
27262 } // We always throw the original error in case the second render pass is not idempotent.
27263 // This can happen if a memoized function or CommonJS module doesn't throw after first invocation.
27264
27265
27266 throw originalError;
27267 }
27268 };
27269 }
27270
27271 var didWarnAboutUpdateInRender = false;
27272 var didWarnAboutUpdateInRenderForAnotherComponent;
27273
27274 {
27275 didWarnAboutUpdateInRenderForAnotherComponent = new Set();
27276 }
27277
27278 function warnAboutRenderPhaseUpdatesInDEV(fiber) {
27279 {
27280 if (isRendering && !getIsUpdatingOpaqueValueInRenderPhaseInDEV()) {
27281 switch (fiber.tag) {
27282 case FunctionComponent:
27283 case ForwardRef:
27284 case SimpleMemoComponent:
27285 {
27286 var renderingComponentName = workInProgress && getComponentNameFromFiber(workInProgress) || 'Unknown'; // Dedupe by the rendering component because it's the one that needs to be fixed.
27287
27288 var dedupeKey = renderingComponentName;
27289
27290 if (!didWarnAboutUpdateInRenderForAnotherComponent.has(dedupeKey)) {
27291 didWarnAboutUpdateInRenderForAnotherComponent.add(dedupeKey);
27292 var setStateComponentName = getComponentNameFromFiber(fiber) || 'Unknown';
27293
27294 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);
27295 }
27296
27297 break;
27298 }
27299
27300 case ClassComponent:
27301 {
27302 if (!didWarnAboutUpdateInRender) {
27303 error('Cannot update during an existing state transition (such as ' + 'within `render`). Render methods should be a pure ' + 'function of props and state.');
27304
27305 didWarnAboutUpdateInRender = true;
27306 }
27307
27308 break;
27309 }
27310 }
27311 }
27312 }
27313 }
27314
27315 function restorePendingUpdaters(root, lanes) {
27316 {
27317 if (isDevToolsPresent) {
27318 var memoizedUpdaters = root.memoizedUpdaters;
27319 memoizedUpdaters.forEach(function (schedulingFiber) {
27320 addFiberToLanesMap(root, schedulingFiber, lanes);
27321 }); // This function intentionally does not clear memoized updaters.
27322 // Those may still be relevant to the current commit
27323 // and a future one (e.g. Suspense).
27324 }
27325 }
27326 }
27327 var fakeActCallbackNode = {};
27328
27329 function scheduleCallback$1(priorityLevel, callback) {
27330 {
27331 // If we're currently inside an `act` scope, bypass Scheduler and push to
27332 // the `act` queue instead.
27333 var actQueue = ReactCurrentActQueue$1.current;
27334
27335 if (actQueue !== null) {
27336 actQueue.push(callback);
27337 return fakeActCallbackNode;
27338 } else {
27339 return scheduleCallback(priorityLevel, callback);
27340 }
27341 }
27342 }
27343
27344 function cancelCallback$1(callbackNode) {
27345 if ( callbackNode === fakeActCallbackNode) {
27346 return;
27347 } // In production, always call Scheduler. This function will be stripped out.
27348
27349
27350 return cancelCallback(callbackNode);
27351 }
27352
27353 function shouldForceFlushFallbacksInDEV() {
27354 // Never force flush in production. This function should get stripped out.
27355 return ReactCurrentActQueue$1.current !== null;
27356 }
27357
27358 function warnIfUpdatesNotWrappedWithActDEV(fiber) {
27359 {
27360 if (fiber.mode & ConcurrentMode) {
27361 if (!isConcurrentActEnvironment()) {
27362 // Not in an act environment. No need to warn.
27363 return;
27364 }
27365 } else {
27366 // Legacy mode has additional cases where we suppress a warning.
27367 if (!isLegacyActEnvironment()) {
27368 // Not in an act environment. No need to warn.
27369 return;
27370 }
27371
27372 if (executionContext !== NoContext) {
27373 // Legacy mode doesn't warn if the update is batched, i.e.
27374 // batchedUpdates or flushSync.
27375 return;
27376 }
27377
27378 if (fiber.tag !== FunctionComponent && fiber.tag !== ForwardRef && fiber.tag !== SimpleMemoComponent) {
27379 // For backwards compatibility with pre-hooks code, legacy mode only
27380 // warns for updates that originate from a hook.
27381 return;
27382 }
27383 }
27384
27385 if (ReactCurrentActQueue$1.current === null) {
27386 var previousFiber = current;
27387
27388 try {
27389 setCurrentFiber(fiber);
27390
27391 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));
27392 } finally {
27393 if (previousFiber) {
27394 setCurrentFiber(fiber);
27395 } else {
27396 resetCurrentFiber();
27397 }
27398 }
27399 }
27400 }
27401 }
27402
27403 function warnIfSuspenseResolutionNotWrappedWithActDEV(root) {
27404 {
27405 if (root.tag !== LegacyRoot && isConcurrentActEnvironment() && ReactCurrentActQueue$1.current === null) {
27406 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');
27407 }
27408 }
27409 }
27410
27411 /* eslint-disable react-internal/prod-error-codes */
27412 var resolveFamily = null; // $FlowFixMe Flow gets confused by a WeakSet feature check below.
27413
27414 var failedBoundaries = null;
27415 var setRefreshHandler = function (handler) {
27416 {
27417 resolveFamily = handler;
27418 }
27419 };
27420 function resolveFunctionForHotReloading(type) {
27421 {
27422 if (resolveFamily === null) {
27423 // Hot reloading is disabled.
27424 return type;
27425 }
27426
27427 var family = resolveFamily(type);
27428
27429 if (family === undefined) {
27430 return type;
27431 } // Use the latest known implementation.
27432
27433
27434 return family.current;
27435 }
27436 }
27437 function resolveClassForHotReloading(type) {
27438 // No implementation differences.
27439 return resolveFunctionForHotReloading(type);
27440 }
27441 function resolveForwardRefForHotReloading(type) {
27442 {
27443 if (resolveFamily === null) {
27444 // Hot reloading is disabled.
27445 return type;
27446 }
27447
27448 var family = resolveFamily(type);
27449
27450 if (family === undefined) {
27451 // Check if we're dealing with a real forwardRef. Don't want to crash early.
27452 if (type !== null && type !== undefined && typeof type.render === 'function') {
27453 // ForwardRef is special because its resolved .type is an object,
27454 // but it's possible that we only have its inner render function in the map.
27455 // If that inner render function is different, we'll build a new forwardRef type.
27456 var currentRender = resolveFunctionForHotReloading(type.render);
27457
27458 if (type.render !== currentRender) {
27459 var syntheticType = {
27460 $$typeof: REACT_FORWARD_REF_TYPE,
27461 render: currentRender
27462 };
27463
27464 if (type.displayName !== undefined) {
27465 syntheticType.displayName = type.displayName;
27466 }
27467
27468 return syntheticType;
27469 }
27470 }
27471
27472 return type;
27473 } // Use the latest known implementation.
27474
27475
27476 return family.current;
27477 }
27478 }
27479 function isCompatibleFamilyForHotReloading(fiber, element) {
27480 {
27481 if (resolveFamily === null) {
27482 // Hot reloading is disabled.
27483 return false;
27484 }
27485
27486 var prevType = fiber.elementType;
27487 var nextType = element.type; // If we got here, we know types aren't === equal.
27488
27489 var needsCompareFamilies = false;
27490 var $$typeofNextType = typeof nextType === 'object' && nextType !== null ? nextType.$$typeof : null;
27491
27492 switch (fiber.tag) {
27493 case ClassComponent:
27494 {
27495 if (typeof nextType === 'function') {
27496 needsCompareFamilies = true;
27497 }
27498
27499 break;
27500 }
27501
27502 case FunctionComponent:
27503 {
27504 if (typeof nextType === 'function') {
27505 needsCompareFamilies = true;
27506 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27507 // We don't know the inner type yet.
27508 // We're going to assume that the lazy inner type is stable,
27509 // and so it is sufficient to avoid reconciling it away.
27510 // We're not going to unwrap or actually use the new lazy type.
27511 needsCompareFamilies = true;
27512 }
27513
27514 break;
27515 }
27516
27517 case ForwardRef:
27518 {
27519 if ($$typeofNextType === REACT_FORWARD_REF_TYPE) {
27520 needsCompareFamilies = true;
27521 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27522 needsCompareFamilies = true;
27523 }
27524
27525 break;
27526 }
27527
27528 case MemoComponent:
27529 case SimpleMemoComponent:
27530 {
27531 if ($$typeofNextType === REACT_MEMO_TYPE) {
27532 // TODO: if it was but can no longer be simple,
27533 // we shouldn't set this.
27534 needsCompareFamilies = true;
27535 } else if ($$typeofNextType === REACT_LAZY_TYPE) {
27536 needsCompareFamilies = true;
27537 }
27538
27539 break;
27540 }
27541
27542 default:
27543 return false;
27544 } // Check if both types have a family and it's the same one.
27545
27546
27547 if (needsCompareFamilies) {
27548 // Note: memo() and forwardRef() we'll compare outer rather than inner type.
27549 // This means both of them need to be registered to preserve state.
27550 // If we unwrapped and compared the inner types for wrappers instead,
27551 // then we would risk falsely saying two separate memo(Foo)
27552 // calls are equivalent because they wrap the same Foo function.
27553 var prevFamily = resolveFamily(prevType);
27554
27555 if (prevFamily !== undefined && prevFamily === resolveFamily(nextType)) {
27556 return true;
27557 }
27558 }
27559
27560 return false;
27561 }
27562 }
27563 function markFailedErrorBoundaryForHotReloading(fiber) {
27564 {
27565 if (resolveFamily === null) {
27566 // Hot reloading is disabled.
27567 return;
27568 }
27569
27570 if (typeof WeakSet !== 'function') {
27571 return;
27572 }
27573
27574 if (failedBoundaries === null) {
27575 failedBoundaries = new WeakSet();
27576 }
27577
27578 failedBoundaries.add(fiber);
27579 }
27580 }
27581 var scheduleRefresh = function (root, update) {
27582 {
27583 if (resolveFamily === null) {
27584 // Hot reloading is disabled.
27585 return;
27586 }
27587
27588 var staleFamilies = update.staleFamilies,
27589 updatedFamilies = update.updatedFamilies;
27590 flushPassiveEffects();
27591 flushSync(function () {
27592 scheduleFibersWithFamiliesRecursively(root.current, updatedFamilies, staleFamilies);
27593 });
27594 }
27595 };
27596 var scheduleRoot = function (root, element) {
27597 {
27598 if (root.context !== emptyContextObject) {
27599 // Super edge case: root has a legacy _renderSubtree context
27600 // but we don't know the parentComponent so we can't pass it.
27601 // Just ignore. We'll delete this with _renderSubtree code path later.
27602 return;
27603 }
27604
27605 flushPassiveEffects();
27606 flushSync(function () {
27607 updateContainer(element, root, null, null);
27608 });
27609 }
27610 };
27611
27612 function scheduleFibersWithFamiliesRecursively(fiber, updatedFamilies, staleFamilies) {
27613 {
27614 var alternate = fiber.alternate,
27615 child = fiber.child,
27616 sibling = fiber.sibling,
27617 tag = fiber.tag,
27618 type = fiber.type;
27619 var candidateType = null;
27620
27621 switch (tag) {
27622 case FunctionComponent:
27623 case SimpleMemoComponent:
27624 case ClassComponent:
27625 candidateType = type;
27626 break;
27627
27628 case ForwardRef:
27629 candidateType = type.render;
27630 break;
27631 }
27632
27633 if (resolveFamily === null) {
27634 throw new Error('Expected resolveFamily to be set during hot reload.');
27635 }
27636
27637 var needsRender = false;
27638 var needsRemount = false;
27639
27640 if (candidateType !== null) {
27641 var family = resolveFamily(candidateType);
27642
27643 if (family !== undefined) {
27644 if (staleFamilies.has(family)) {
27645 needsRemount = true;
27646 } else if (updatedFamilies.has(family)) {
27647 if (tag === ClassComponent) {
27648 needsRemount = true;
27649 } else {
27650 needsRender = true;
27651 }
27652 }
27653 }
27654 }
27655
27656 if (failedBoundaries !== null) {
27657 if (failedBoundaries.has(fiber) || alternate !== null && failedBoundaries.has(alternate)) {
27658 needsRemount = true;
27659 }
27660 }
27661
27662 if (needsRemount) {
27663 fiber._debugNeedsRemount = true;
27664 }
27665
27666 if (needsRemount || needsRender) {
27667 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
27668 }
27669
27670 if (child !== null && !needsRemount) {
27671 scheduleFibersWithFamiliesRecursively(child, updatedFamilies, staleFamilies);
27672 }
27673
27674 if (sibling !== null) {
27675 scheduleFibersWithFamiliesRecursively(sibling, updatedFamilies, staleFamilies);
27676 }
27677 }
27678 }
27679
27680 var findHostInstancesForRefresh = function (root, families) {
27681 {
27682 var hostInstances = new Set();
27683 var types = new Set(families.map(function (family) {
27684 return family.current;
27685 }));
27686 findHostInstancesForMatchingFibersRecursively(root.current, types, hostInstances);
27687 return hostInstances;
27688 }
27689 };
27690
27691 function findHostInstancesForMatchingFibersRecursively(fiber, types, hostInstances) {
27692 {
27693 var child = fiber.child,
27694 sibling = fiber.sibling,
27695 tag = fiber.tag,
27696 type = fiber.type;
27697 var candidateType = null;
27698
27699 switch (tag) {
27700 case FunctionComponent:
27701 case SimpleMemoComponent:
27702 case ClassComponent:
27703 candidateType = type;
27704 break;
27705
27706 case ForwardRef:
27707 candidateType = type.render;
27708 break;
27709 }
27710
27711 var didMatch = false;
27712
27713 if (candidateType !== null) {
27714 if (types.has(candidateType)) {
27715 didMatch = true;
27716 }
27717 }
27718
27719 if (didMatch) {
27720 // We have a match. This only drills down to the closest host components.
27721 // There's no need to search deeper because for the purpose of giving
27722 // visual feedback, "flashing" outermost parent rectangles is sufficient.
27723 findHostInstancesForFiberShallowly(fiber, hostInstances);
27724 } else {
27725 // If there's no match, maybe there will be one further down in the child tree.
27726 if (child !== null) {
27727 findHostInstancesForMatchingFibersRecursively(child, types, hostInstances);
27728 }
27729 }
27730
27731 if (sibling !== null) {
27732 findHostInstancesForMatchingFibersRecursively(sibling, types, hostInstances);
27733 }
27734 }
27735 }
27736
27737 function findHostInstancesForFiberShallowly(fiber, hostInstances) {
27738 {
27739 var foundHostInstances = findChildHostInstancesForFiberShallowly(fiber, hostInstances);
27740
27741 if (foundHostInstances) {
27742 return;
27743 } // If we didn't find any host children, fallback to closest host parent.
27744
27745
27746 var node = fiber;
27747
27748 while (true) {
27749 switch (node.tag) {
27750 case HostComponent:
27751 hostInstances.add(node.stateNode);
27752 return;
27753
27754 case HostPortal:
27755 hostInstances.add(node.stateNode.containerInfo);
27756 return;
27757
27758 case HostRoot:
27759 hostInstances.add(node.stateNode.containerInfo);
27760 return;
27761 }
27762
27763 if (node.return === null) {
27764 throw new Error('Expected to reach root first.');
27765 }
27766
27767 node = node.return;
27768 }
27769 }
27770 }
27771
27772 function findChildHostInstancesForFiberShallowly(fiber, hostInstances) {
27773 {
27774 var node = fiber;
27775 var foundHostInstances = false;
27776
27777 while (true) {
27778 if (node.tag === HostComponent) {
27779 // We got a match.
27780 foundHostInstances = true;
27781 hostInstances.add(node.stateNode); // There may still be more, so keep searching.
27782 } else if (node.child !== null) {
27783 node.child.return = node;
27784 node = node.child;
27785 continue;
27786 }
27787
27788 if (node === fiber) {
27789 return foundHostInstances;
27790 }
27791
27792 while (node.sibling === null) {
27793 if (node.return === null || node.return === fiber) {
27794 return foundHostInstances;
27795 }
27796
27797 node = node.return;
27798 }
27799
27800 node.sibling.return = node.return;
27801 node = node.sibling;
27802 }
27803 }
27804
27805 return false;
27806 }
27807
27808 var hasBadMapPolyfill;
27809
27810 {
27811 hasBadMapPolyfill = false;
27812
27813 try {
27814 var nonExtensibleObject = Object.preventExtensions({});
27815 /* eslint-disable no-new */
27816
27817 new Map([[nonExtensibleObject, null]]);
27818 new Set([nonExtensibleObject]);
27819 /* eslint-enable no-new */
27820 } catch (e) {
27821 // TODO: Consider warning about bad polyfills
27822 hasBadMapPolyfill = true;
27823 }
27824 }
27825
27826 function FiberNode(tag, pendingProps, key, mode) {
27827 // Instance
27828 this.tag = tag;
27829 this.key = key;
27830 this.elementType = null;
27831 this.type = null;
27832 this.stateNode = null; // Fiber
27833
27834 this.return = null;
27835 this.child = null;
27836 this.sibling = null;
27837 this.index = 0;
27838 this.ref = null;
27839 this.pendingProps = pendingProps;
27840 this.memoizedProps = null;
27841 this.updateQueue = null;
27842 this.memoizedState = null;
27843 this.dependencies = null;
27844 this.mode = mode; // Effects
27845
27846 this.flags = NoFlags;
27847 this.subtreeFlags = NoFlags;
27848 this.deletions = null;
27849 this.lanes = NoLanes;
27850 this.childLanes = NoLanes;
27851 this.alternate = null;
27852
27853 {
27854 // Note: The following is done to avoid a v8 performance cliff.
27855 //
27856 // Initializing the fields below to smis and later updating them with
27857 // double values will cause Fibers to end up having separate shapes.
27858 // This behavior/bug has something to do with Object.preventExtension().
27859 // Fortunately this only impacts DEV builds.
27860 // Unfortunately it makes React unusably slow for some applications.
27861 // To work around this, initialize the fields below with doubles.
27862 //
27863 // Learn more about this here:
27864 // https://github.com/facebook/react/issues/14365
27865 // https://bugs.chromium.org/p/v8/issues/detail?id=8538
27866 this.actualDuration = Number.NaN;
27867 this.actualStartTime = Number.NaN;
27868 this.selfBaseDuration = Number.NaN;
27869 this.treeBaseDuration = Number.NaN; // It's okay to replace the initial doubles with smis after initialization.
27870 // This won't trigger the performance cliff mentioned above,
27871 // and it simplifies other profiler code (including DevTools).
27872
27873 this.actualDuration = 0;
27874 this.actualStartTime = -1;
27875 this.selfBaseDuration = 0;
27876 this.treeBaseDuration = 0;
27877 }
27878
27879 {
27880 // This isn't directly used but is handy for debugging internals:
27881 this._debugSource = null;
27882 this._debugOwner = null;
27883 this._debugNeedsRemount = false;
27884 this._debugHookTypes = null;
27885
27886 if (!hasBadMapPolyfill && typeof Object.preventExtensions === 'function') {
27887 Object.preventExtensions(this);
27888 }
27889 }
27890 } // This is a constructor function, rather than a POJO constructor, still
27891 // please ensure we do the following:
27892 // 1) Nobody should add any instance methods on this. Instance methods can be
27893 // more difficult to predict when they get optimized and they are almost
27894 // never inlined properly in static compilers.
27895 // 2) Nobody should rely on `instanceof Fiber` for type testing. We should
27896 // always know when it is a fiber.
27897 // 3) We might want to experiment with using numeric keys since they are easier
27898 // to optimize in a non-JIT environment.
27899 // 4) We can easily go from a constructor to a createFiber object literal if that
27900 // is faster.
27901 // 5) It should be easy to port this to a C struct and keep a C implementation
27902 // compatible.
27903
27904
27905 var createFiber = function (tag, pendingProps, key, mode) {
27906 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
27907 return new FiberNode(tag, pendingProps, key, mode);
27908 };
27909
27910 function shouldConstruct$1(Component) {
27911 var prototype = Component.prototype;
27912 return !!(prototype && prototype.isReactComponent);
27913 }
27914
27915 function isSimpleFunctionComponent(type) {
27916 return typeof type === 'function' && !shouldConstruct$1(type) && type.defaultProps === undefined;
27917 }
27918 function resolveLazyComponentTag(Component) {
27919 if (typeof Component === 'function') {
27920 return shouldConstruct$1(Component) ? ClassComponent : FunctionComponent;
27921 } else if (Component !== undefined && Component !== null) {
27922 var $$typeof = Component.$$typeof;
27923
27924 if ($$typeof === REACT_FORWARD_REF_TYPE) {
27925 return ForwardRef;
27926 }
27927
27928 if ($$typeof === REACT_MEMO_TYPE) {
27929 return MemoComponent;
27930 }
27931 }
27932
27933 return IndeterminateComponent;
27934 } // This is used to create an alternate fiber to do work on.
27935
27936 function createWorkInProgress(current, pendingProps) {
27937 var workInProgress = current.alternate;
27938
27939 if (workInProgress === null) {
27940 // We use a double buffering pooling technique because we know that we'll
27941 // only ever need at most two versions of a tree. We pool the "other" unused
27942 // node that we're free to reuse. This is lazily created to avoid allocating
27943 // extra objects for things that are never updated. It also allow us to
27944 // reclaim the extra memory if needed.
27945 workInProgress = createFiber(current.tag, pendingProps, current.key, current.mode);
27946 workInProgress.elementType = current.elementType;
27947 workInProgress.type = current.type;
27948 workInProgress.stateNode = current.stateNode;
27949
27950 {
27951 // DEV-only fields
27952 workInProgress._debugSource = current._debugSource;
27953 workInProgress._debugOwner = current._debugOwner;
27954 workInProgress._debugHookTypes = current._debugHookTypes;
27955 }
27956
27957 workInProgress.alternate = current;
27958 current.alternate = workInProgress;
27959 } else {
27960 workInProgress.pendingProps = pendingProps; // Needed because Blocks store data on type.
27961
27962 workInProgress.type = current.type; // We already have an alternate.
27963 // Reset the effect tag.
27964
27965 workInProgress.flags = NoFlags; // The effects are no longer valid.
27966
27967 workInProgress.subtreeFlags = NoFlags;
27968 workInProgress.deletions = null;
27969
27970 {
27971 // We intentionally reset, rather than copy, actualDuration & actualStartTime.
27972 // This prevents time from endlessly accumulating in new commits.
27973 // This has the downside of resetting values for different priority renders,
27974 // But works for yielding (the common case) and should support resuming.
27975 workInProgress.actualDuration = 0;
27976 workInProgress.actualStartTime = -1;
27977 }
27978 } // Reset all effects except static ones.
27979 // Static effects are not specific to a render.
27980
27981
27982 workInProgress.flags = current.flags & StaticMask;
27983 workInProgress.childLanes = current.childLanes;
27984 workInProgress.lanes = current.lanes;
27985 workInProgress.child = current.child;
27986 workInProgress.memoizedProps = current.memoizedProps;
27987 workInProgress.memoizedState = current.memoizedState;
27988 workInProgress.updateQueue = current.updateQueue; // Clone the dependencies object. This is mutated during the render phase, so
27989 // it cannot be shared with the current fiber.
27990
27991 var currentDependencies = current.dependencies;
27992 workInProgress.dependencies = currentDependencies === null ? null : {
27993 lanes: currentDependencies.lanes,
27994 firstContext: currentDependencies.firstContext
27995 }; // These will be overridden during the parent's reconciliation
27996
27997 workInProgress.sibling = current.sibling;
27998 workInProgress.index = current.index;
27999 workInProgress.ref = current.ref;
28000
28001 {
28002 workInProgress.selfBaseDuration = current.selfBaseDuration;
28003 workInProgress.treeBaseDuration = current.treeBaseDuration;
28004 }
28005
28006 {
28007 workInProgress._debugNeedsRemount = current._debugNeedsRemount;
28008
28009 switch (workInProgress.tag) {
28010 case IndeterminateComponent:
28011 case FunctionComponent:
28012 case SimpleMemoComponent:
28013 workInProgress.type = resolveFunctionForHotReloading(current.type);
28014 break;
28015
28016 case ClassComponent:
28017 workInProgress.type = resolveClassForHotReloading(current.type);
28018 break;
28019
28020 case ForwardRef:
28021 workInProgress.type = resolveForwardRefForHotReloading(current.type);
28022 break;
28023 }
28024 }
28025
28026 return workInProgress;
28027 } // Used to reuse a Fiber for a second pass.
28028
28029 function resetWorkInProgress(workInProgress, renderLanes) {
28030 // This resets the Fiber to what createFiber or createWorkInProgress would
28031 // have set the values to before during the first pass. Ideally this wouldn't
28032 // be necessary but unfortunately many code paths reads from the workInProgress
28033 // when they should be reading from current and writing to workInProgress.
28034 // We assume pendingProps, index, key, ref, return are still untouched to
28035 // avoid doing another reconciliation.
28036 // Reset the effect flags but keep any Placement tags, since that's something
28037 // that child fiber is setting, not the reconciliation.
28038 workInProgress.flags &= StaticMask | Placement; // The effects are no longer valid.
28039
28040 var current = workInProgress.alternate;
28041
28042 if (current === null) {
28043 // Reset to createFiber's initial values.
28044 workInProgress.childLanes = NoLanes;
28045 workInProgress.lanes = renderLanes;
28046 workInProgress.child = null;
28047 workInProgress.subtreeFlags = NoFlags;
28048 workInProgress.memoizedProps = null;
28049 workInProgress.memoizedState = null;
28050 workInProgress.updateQueue = null;
28051 workInProgress.dependencies = null;
28052 workInProgress.stateNode = null;
28053
28054 {
28055 // Note: We don't reset the actualTime counts. It's useful to accumulate
28056 // actual time across multiple render passes.
28057 workInProgress.selfBaseDuration = 0;
28058 workInProgress.treeBaseDuration = 0;
28059 }
28060 } else {
28061 // Reset to the cloned values that createWorkInProgress would've.
28062 workInProgress.childLanes = current.childLanes;
28063 workInProgress.lanes = current.lanes;
28064 workInProgress.child = current.child;
28065 workInProgress.subtreeFlags = NoFlags;
28066 workInProgress.deletions = null;
28067 workInProgress.memoizedProps = current.memoizedProps;
28068 workInProgress.memoizedState = current.memoizedState;
28069 workInProgress.updateQueue = current.updateQueue; // Needed because Blocks store data on type.
28070
28071 workInProgress.type = current.type; // Clone the dependencies object. This is mutated during the render phase, so
28072 // it cannot be shared with the current fiber.
28073
28074 var currentDependencies = current.dependencies;
28075 workInProgress.dependencies = currentDependencies === null ? null : {
28076 lanes: currentDependencies.lanes,
28077 firstContext: currentDependencies.firstContext
28078 };
28079
28080 {
28081 // Note: We don't reset the actualTime counts. It's useful to accumulate
28082 // actual time across multiple render passes.
28083 workInProgress.selfBaseDuration = current.selfBaseDuration;
28084 workInProgress.treeBaseDuration = current.treeBaseDuration;
28085 }
28086 }
28087
28088 return workInProgress;
28089 }
28090 function createHostRootFiber(tag, isStrictMode, concurrentUpdatesByDefaultOverride) {
28091 var mode;
28092
28093 if (tag === ConcurrentRoot) {
28094 mode = ConcurrentMode;
28095
28096 if (isStrictMode === true) {
28097 mode |= StrictLegacyMode;
28098
28099 {
28100 mode |= StrictEffectsMode;
28101 }
28102 }
28103 } else {
28104 mode = NoMode;
28105 }
28106
28107 if ( isDevToolsPresent) {
28108 // Always collect profile timings when DevTools are present.
28109 // This enables DevTools to start capturing timing at any point–
28110 // Without some nodes in the tree having empty base times.
28111 mode |= ProfileMode;
28112 }
28113
28114 return createFiber(HostRoot, null, null, mode);
28115 }
28116 function createFiberFromTypeAndProps(type, // React$ElementType
28117 key, pendingProps, owner, mode, lanes) {
28118 var fiberTag = IndeterminateComponent; // The resolved type is set if we know what the final type will be. I.e. it's not lazy.
28119
28120 var resolvedType = type;
28121
28122 if (typeof type === 'function') {
28123 if (shouldConstruct$1(type)) {
28124 fiberTag = ClassComponent;
28125
28126 {
28127 resolvedType = resolveClassForHotReloading(resolvedType);
28128 }
28129 } else {
28130 {
28131 resolvedType = resolveFunctionForHotReloading(resolvedType);
28132 }
28133 }
28134 } else if (typeof type === 'string') {
28135 fiberTag = HostComponent;
28136 } else {
28137 getTag: switch (type) {
28138 case REACT_FRAGMENT_TYPE:
28139 return createFiberFromFragment(pendingProps.children, mode, lanes, key);
28140
28141 case REACT_STRICT_MODE_TYPE:
28142 fiberTag = Mode;
28143 mode |= StrictLegacyMode;
28144
28145 if ( (mode & ConcurrentMode) !== NoMode) {
28146 // Strict effects should never run on legacy roots
28147 mode |= StrictEffectsMode;
28148 }
28149
28150 break;
28151
28152 case REACT_PROFILER_TYPE:
28153 return createFiberFromProfiler(pendingProps, mode, lanes, key);
28154
28155 case REACT_SUSPENSE_TYPE:
28156 return createFiberFromSuspense(pendingProps, mode, lanes, key);
28157
28158 case REACT_SUSPENSE_LIST_TYPE:
28159 return createFiberFromSuspenseList(pendingProps, mode, lanes, key);
28160
28161 case REACT_OFFSCREEN_TYPE:
28162 return createFiberFromOffscreen(pendingProps, mode, lanes, key);
28163
28164 case REACT_LEGACY_HIDDEN_TYPE:
28165
28166 // eslint-disable-next-line no-fallthrough
28167
28168 case REACT_SCOPE_TYPE:
28169
28170 // eslint-disable-next-line no-fallthrough
28171
28172 case REACT_CACHE_TYPE:
28173
28174 // eslint-disable-next-line no-fallthrough
28175
28176 case REACT_TRACING_MARKER_TYPE:
28177
28178 // eslint-disable-next-line no-fallthrough
28179
28180 case REACT_DEBUG_TRACING_MODE_TYPE:
28181
28182 // eslint-disable-next-line no-fallthrough
28183
28184 default:
28185 {
28186 if (typeof type === 'object' && type !== null) {
28187 switch (type.$$typeof) {
28188 case REACT_PROVIDER_TYPE:
28189 fiberTag = ContextProvider;
28190 break getTag;
28191
28192 case REACT_CONTEXT_TYPE:
28193 // This is a consumer
28194 fiberTag = ContextConsumer;
28195 break getTag;
28196
28197 case REACT_FORWARD_REF_TYPE:
28198 fiberTag = ForwardRef;
28199
28200 {
28201 resolvedType = resolveForwardRefForHotReloading(resolvedType);
28202 }
28203
28204 break getTag;
28205
28206 case REACT_MEMO_TYPE:
28207 fiberTag = MemoComponent;
28208 break getTag;
28209
28210 case REACT_LAZY_TYPE:
28211 fiberTag = LazyComponent;
28212 resolvedType = null;
28213 break getTag;
28214 }
28215 }
28216
28217 var info = '';
28218
28219 {
28220 if (type === undefined || typeof type === 'object' && type !== null && Object.keys(type).length === 0) {
28221 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.';
28222 }
28223
28224 var ownerName = owner ? getComponentNameFromFiber(owner) : null;
28225
28226 if (ownerName) {
28227 info += '\n\nCheck the render method of `' + ownerName + '`.';
28228 }
28229 }
28230
28231 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));
28232 }
28233 }
28234 }
28235
28236 var fiber = createFiber(fiberTag, pendingProps, key, mode);
28237 fiber.elementType = type;
28238 fiber.type = resolvedType;
28239 fiber.lanes = lanes;
28240
28241 {
28242 fiber._debugOwner = owner;
28243 }
28244
28245 return fiber;
28246 }
28247 function createFiberFromElement(element, mode, lanes) {
28248 var owner = null;
28249
28250 {
28251 owner = element._owner;
28252 }
28253
28254 var type = element.type;
28255 var key = element.key;
28256 var pendingProps = element.props;
28257 var fiber = createFiberFromTypeAndProps(type, key, pendingProps, owner, mode, lanes);
28258
28259 {
28260 fiber._debugSource = element._source;
28261 fiber._debugOwner = element._owner;
28262 }
28263
28264 return fiber;
28265 }
28266 function createFiberFromFragment(elements, mode, lanes, key) {
28267 var fiber = createFiber(Fragment, elements, key, mode);
28268 fiber.lanes = lanes;
28269 return fiber;
28270 }
28271
28272 function createFiberFromProfiler(pendingProps, mode, lanes, key) {
28273 {
28274 if (typeof pendingProps.id !== 'string') {
28275 error('Profiler must specify an "id" of type `string` as a prop. Received the type `%s` instead.', typeof pendingProps.id);
28276 }
28277 }
28278
28279 var fiber = createFiber(Profiler, pendingProps, key, mode | ProfileMode);
28280 fiber.elementType = REACT_PROFILER_TYPE;
28281 fiber.lanes = lanes;
28282
28283 {
28284 fiber.stateNode = {
28285 effectDuration: 0,
28286 passiveEffectDuration: 0
28287 };
28288 }
28289
28290 return fiber;
28291 }
28292
28293 function createFiberFromSuspense(pendingProps, mode, lanes, key) {
28294 var fiber = createFiber(SuspenseComponent, pendingProps, key, mode);
28295 fiber.elementType = REACT_SUSPENSE_TYPE;
28296 fiber.lanes = lanes;
28297 return fiber;
28298 }
28299 function createFiberFromSuspenseList(pendingProps, mode, lanes, key) {
28300 var fiber = createFiber(SuspenseListComponent, pendingProps, key, mode);
28301 fiber.elementType = REACT_SUSPENSE_LIST_TYPE;
28302 fiber.lanes = lanes;
28303 return fiber;
28304 }
28305 function createFiberFromOffscreen(pendingProps, mode, lanes, key) {
28306 var fiber = createFiber(OffscreenComponent, pendingProps, key, mode);
28307 fiber.elementType = REACT_OFFSCREEN_TYPE;
28308 fiber.lanes = lanes;
28309 var primaryChildInstance = {};
28310 fiber.stateNode = primaryChildInstance;
28311 return fiber;
28312 }
28313 function createFiberFromText(content, mode, lanes) {
28314 var fiber = createFiber(HostText, content, null, mode);
28315 fiber.lanes = lanes;
28316 return fiber;
28317 }
28318 function createFiberFromHostInstanceForDeletion() {
28319 var fiber = createFiber(HostComponent, null, null, NoMode);
28320 fiber.elementType = 'DELETED';
28321 return fiber;
28322 }
28323 function createFiberFromDehydratedFragment(dehydratedNode) {
28324 var fiber = createFiber(DehydratedFragment, null, null, NoMode);
28325 fiber.stateNode = dehydratedNode;
28326 return fiber;
28327 }
28328 function createFiberFromPortal(portal, mode, lanes) {
28329 var pendingProps = portal.children !== null ? portal.children : [];
28330 var fiber = createFiber(HostPortal, pendingProps, portal.key, mode);
28331 fiber.lanes = lanes;
28332 fiber.stateNode = {
28333 containerInfo: portal.containerInfo,
28334 pendingChildren: null,
28335 // Used by persistent updates
28336 implementation: portal.implementation
28337 };
28338 return fiber;
28339 } // Used for stashing WIP properties to replay failed work in DEV.
28340
28341 function assignFiberPropertiesInDEV(target, source) {
28342 if (target === null) {
28343 // This Fiber's initial properties will always be overwritten.
28344 // We only use a Fiber to ensure the same hidden class so DEV isn't slow.
28345 target = createFiber(IndeterminateComponent, null, null, NoMode);
28346 } // This is intentionally written as a list of all properties.
28347 // We tried to use Object.assign() instead but this is called in
28348 // the hottest path, and Object.assign() was too slow:
28349 // https://github.com/facebook/react/issues/12502
28350 // This code is DEV-only so size is not a concern.
28351
28352
28353 target.tag = source.tag;
28354 target.key = source.key;
28355 target.elementType = source.elementType;
28356 target.type = source.type;
28357 target.stateNode = source.stateNode;
28358 target.return = source.return;
28359 target.child = source.child;
28360 target.sibling = source.sibling;
28361 target.index = source.index;
28362 target.ref = source.ref;
28363 target.pendingProps = source.pendingProps;
28364 target.memoizedProps = source.memoizedProps;
28365 target.updateQueue = source.updateQueue;
28366 target.memoizedState = source.memoizedState;
28367 target.dependencies = source.dependencies;
28368 target.mode = source.mode;
28369 target.flags = source.flags;
28370 target.subtreeFlags = source.subtreeFlags;
28371 target.deletions = source.deletions;
28372 target.lanes = source.lanes;
28373 target.childLanes = source.childLanes;
28374 target.alternate = source.alternate;
28375
28376 {
28377 target.actualDuration = source.actualDuration;
28378 target.actualStartTime = source.actualStartTime;
28379 target.selfBaseDuration = source.selfBaseDuration;
28380 target.treeBaseDuration = source.treeBaseDuration;
28381 }
28382
28383 target._debugSource = source._debugSource;
28384 target._debugOwner = source._debugOwner;
28385 target._debugNeedsRemount = source._debugNeedsRemount;
28386 target._debugHookTypes = source._debugHookTypes;
28387 return target;
28388 }
28389
28390 function FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError) {
28391 this.tag = tag;
28392 this.containerInfo = containerInfo;
28393 this.pendingChildren = null;
28394 this.current = null;
28395 this.pingCache = null;
28396 this.finishedWork = null;
28397 this.timeoutHandle = noTimeout;
28398 this.context = null;
28399 this.pendingContext = null;
28400 this.callbackNode = null;
28401 this.callbackPriority = NoLane;
28402 this.eventTimes = createLaneMap(NoLanes);
28403 this.expirationTimes = createLaneMap(NoTimestamp);
28404 this.pendingLanes = NoLanes;
28405 this.suspendedLanes = NoLanes;
28406 this.pingedLanes = NoLanes;
28407 this.expiredLanes = NoLanes;
28408 this.mutableReadLanes = NoLanes;
28409 this.finishedLanes = NoLanes;
28410 this.entangledLanes = NoLanes;
28411 this.entanglements = createLaneMap(NoLanes);
28412 this.identifierPrefix = identifierPrefix;
28413 this.onRecoverableError = onRecoverableError;
28414
28415 {
28416 this.mutableSourceEagerHydrationData = null;
28417 }
28418
28419 {
28420 this.effectDuration = 0;
28421 this.passiveEffectDuration = 0;
28422 }
28423
28424 {
28425 this.memoizedUpdaters = new Set();
28426 var pendingUpdatersLaneMap = this.pendingUpdatersLaneMap = [];
28427
28428 for (var _i = 0; _i < TotalLanes; _i++) {
28429 pendingUpdatersLaneMap.push(new Set());
28430 }
28431 }
28432
28433 {
28434 switch (tag) {
28435 case ConcurrentRoot:
28436 this._debugRootType = hydrate ? 'hydrateRoot()' : 'createRoot()';
28437 break;
28438
28439 case LegacyRoot:
28440 this._debugRootType = hydrate ? 'hydrate()' : 'render()';
28441 break;
28442 }
28443 }
28444 }
28445
28446 function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, // TODO: We have several of these arguments that are conceptually part of the
28447 // host config, but because they are passed in at runtime, we have to thread
28448 // them through the root constructor. Perhaps we should put them all into a
28449 // single type, like a DynamicHostConfig that is defined by the renderer.
28450 identifierPrefix, onRecoverableError, transitionCallbacks) {
28451 var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError);
28452 // stateNode is any.
28453
28454
28455 var uninitializedFiber = createHostRootFiber(tag, isStrictMode);
28456 root.current = uninitializedFiber;
28457 uninitializedFiber.stateNode = root;
28458
28459 {
28460 var _initialState = {
28461 element: initialChildren,
28462 isDehydrated: hydrate,
28463 cache: null,
28464 // not enabled yet
28465 transitions: null
28466 };
28467 uninitializedFiber.memoizedState = _initialState;
28468 }
28469
28470 initializeUpdateQueue(uninitializedFiber);
28471 return root;
28472 }
28473
28474 var ReactVersion = '18.0.0-fc46dba67-20220329';
28475
28476 function createPortal(children, containerInfo, // TODO: figure out the API for cross-renderer implementation.
28477 implementation) {
28478 var key = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null;
28479
28480 {
28481 checkKeyStringCoercion(key);
28482 }
28483
28484 return {
28485 // This tag allow us to uniquely identify this as a React Portal
28486 $$typeof: REACT_PORTAL_TYPE,
28487 key: key == null ? null : '' + key,
28488 children: children,
28489 containerInfo: containerInfo,
28490 implementation: implementation
28491 };
28492 }
28493
28494 var didWarnAboutNestedUpdates;
28495 var didWarnAboutFindNodeInStrictMode;
28496
28497 {
28498 didWarnAboutNestedUpdates = false;
28499 didWarnAboutFindNodeInStrictMode = {};
28500 }
28501
28502 function getContextForSubtree(parentComponent) {
28503 if (!parentComponent) {
28504 return emptyContextObject;
28505 }
28506
28507 var fiber = get(parentComponent);
28508 var parentContext = findCurrentUnmaskedContext(fiber);
28509
28510 if (fiber.tag === ClassComponent) {
28511 var Component = fiber.type;
28512
28513 if (isContextProvider(Component)) {
28514 return processChildContext(fiber, Component, parentContext);
28515 }
28516 }
28517
28518 return parentContext;
28519 }
28520
28521 function findHostInstanceWithWarning(component, methodName) {
28522 {
28523 var fiber = get(component);
28524
28525 if (fiber === undefined) {
28526 if (typeof component.render === 'function') {
28527 throw new Error('Unable to find node on an unmounted component.');
28528 } else {
28529 var keys = Object.keys(component).join(',');
28530 throw new Error("Argument appears to not be a ReactComponent. Keys: " + keys);
28531 }
28532 }
28533
28534 var hostFiber = findCurrentHostFiber(fiber);
28535
28536 if (hostFiber === null) {
28537 return null;
28538 }
28539
28540 if (hostFiber.mode & StrictLegacyMode) {
28541 var componentName = getComponentNameFromFiber(fiber) || 'Component';
28542
28543 if (!didWarnAboutFindNodeInStrictMode[componentName]) {
28544 didWarnAboutFindNodeInStrictMode[componentName] = true;
28545 var previousFiber = current;
28546
28547 try {
28548 setCurrentFiber(hostFiber);
28549
28550 if (fiber.mode & StrictLegacyMode) {
28551 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);
28552 } else {
28553 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);
28554 }
28555 } finally {
28556 // Ideally this should reset to previous but this shouldn't be called in
28557 // render and there's another warning for that anyway.
28558 if (previousFiber) {
28559 setCurrentFiber(previousFiber);
28560 } else {
28561 resetCurrentFiber();
28562 }
28563 }
28564 }
28565 }
28566
28567 return hostFiber.stateNode;
28568 }
28569 }
28570
28571 function createContainer(containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
28572 var hydrate = false;
28573 var initialChildren = null;
28574 return createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
28575 }
28576 function createHydrationContainer(initialChildren, // TODO: Remove `callback` when we delete legacy mode.
28577 callback, containerInfo, tag, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError, transitionCallbacks) {
28578 var hydrate = true;
28579 var root = createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError); // TODO: Move this to FiberRoot constructor
28580
28581 root.context = getContextForSubtree(null); // Schedule the initial render. In a hydration root, this is different from
28582 // a regular update because the initial render must match was was rendered
28583 // on the server.
28584 // NOTE: This update intentionally doesn't have a payload. We're only using
28585 // the update to schedule work on the root fiber (and, for legacy roots, to
28586 // enqueue the callback if one is provided).
28587
28588 var current = root.current;
28589 var eventTime = requestEventTime();
28590 var lane = requestUpdateLane(current);
28591 var update = createUpdate(eventTime, lane);
28592 update.callback = callback !== undefined && callback !== null ? callback : null;
28593 enqueueUpdate(current, update);
28594 scheduleInitialHydrationOnRoot(root, lane, eventTime);
28595 return root;
28596 }
28597 function updateContainer(element, container, parentComponent, callback) {
28598 {
28599 onScheduleRoot(container, element);
28600 }
28601
28602 var current$1 = container.current;
28603 var eventTime = requestEventTime();
28604 var lane = requestUpdateLane(current$1);
28605
28606 {
28607 markRenderScheduled(lane);
28608 }
28609
28610 var context = getContextForSubtree(parentComponent);
28611
28612 if (container.context === null) {
28613 container.context = context;
28614 } else {
28615 container.pendingContext = context;
28616 }
28617
28618 {
28619 if (isRendering && current !== null && !didWarnAboutNestedUpdates) {
28620 didWarnAboutNestedUpdates = true;
28621
28622 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');
28623 }
28624 }
28625
28626 var update = createUpdate(eventTime, lane); // Caution: React DevTools currently depends on this property
28627 // being called "element".
28628
28629 update.payload = {
28630 element: element
28631 };
28632 callback = callback === undefined ? null : callback;
28633
28634 if (callback !== null) {
28635 {
28636 if (typeof callback !== 'function') {
28637 error('render(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callback);
28638 }
28639 }
28640
28641 update.callback = callback;
28642 }
28643
28644 enqueueUpdate(current$1, update);
28645 var root = scheduleUpdateOnFiber(current$1, lane, eventTime);
28646
28647 if (root !== null) {
28648 entangleTransitions(root, current$1, lane);
28649 }
28650
28651 return lane;
28652 }
28653 function getPublicRootInstance(container) {
28654 var containerFiber = container.current;
28655
28656 if (!containerFiber.child) {
28657 return null;
28658 }
28659
28660 switch (containerFiber.child.tag) {
28661 case HostComponent:
28662 return getPublicInstance(containerFiber.child.stateNode);
28663
28664 default:
28665 return containerFiber.child.stateNode;
28666 }
28667 }
28668 function attemptSynchronousHydration$1(fiber) {
28669 switch (fiber.tag) {
28670 case HostRoot:
28671 var root = fiber.stateNode;
28672
28673 if (isRootDehydrated(root)) {
28674 // Flush the first scheduled "update".
28675 var lanes = getHighestPriorityPendingLanes(root);
28676 flushRoot(root, lanes);
28677 }
28678
28679 break;
28680
28681 case SuspenseComponent:
28682 var eventTime = requestEventTime();
28683 flushSync(function () {
28684 return scheduleUpdateOnFiber(fiber, SyncLane, eventTime);
28685 }); // If we're still blocked after this, we need to increase
28686 // the priority of any promises resolving within this
28687 // boundary so that they next attempt also has higher pri.
28688
28689 var retryLane = SyncLane;
28690 markRetryLaneIfNotHydrated(fiber, retryLane);
28691 break;
28692 }
28693 }
28694
28695 function markRetryLaneImpl(fiber, retryLane) {
28696 var suspenseState = fiber.memoizedState;
28697
28698 if (suspenseState !== null && suspenseState.dehydrated !== null) {
28699 suspenseState.retryLane = higherPriorityLane(suspenseState.retryLane, retryLane);
28700 }
28701 } // Increases the priority of thenables when they resolve within this boundary.
28702
28703
28704 function markRetryLaneIfNotHydrated(fiber, retryLane) {
28705 markRetryLaneImpl(fiber, retryLane);
28706 var alternate = fiber.alternate;
28707
28708 if (alternate) {
28709 markRetryLaneImpl(alternate, retryLane);
28710 }
28711 }
28712
28713 function attemptContinuousHydration$1(fiber) {
28714 if (fiber.tag !== SuspenseComponent) {
28715 // We ignore HostRoots here because we can't increase
28716 // their priority and they should not suspend on I/O,
28717 // since you have to wrap anything that might suspend in
28718 // Suspense.
28719 return;
28720 }
28721
28722 var eventTime = requestEventTime();
28723 var lane = SelectiveHydrationLane;
28724 scheduleUpdateOnFiber(fiber, lane, eventTime);
28725 markRetryLaneIfNotHydrated(fiber, lane);
28726 }
28727 function attemptHydrationAtCurrentPriority$1(fiber) {
28728 if (fiber.tag !== SuspenseComponent) {
28729 // We ignore HostRoots here because we can't increase
28730 // their priority other than synchronously flush it.
28731 return;
28732 }
28733
28734 var eventTime = requestEventTime();
28735 var lane = requestUpdateLane(fiber);
28736 scheduleUpdateOnFiber(fiber, lane, eventTime);
28737 markRetryLaneIfNotHydrated(fiber, lane);
28738 }
28739 function findHostInstanceWithNoPortals(fiber) {
28740 var hostFiber = findCurrentHostFiberWithNoPortals(fiber);
28741
28742 if (hostFiber === null) {
28743 return null;
28744 }
28745
28746 return hostFiber.stateNode;
28747 }
28748
28749 var shouldErrorImpl = function (fiber) {
28750 return null;
28751 };
28752
28753 function shouldError(fiber) {
28754 return shouldErrorImpl(fiber);
28755 }
28756
28757 var shouldSuspendImpl = function (fiber) {
28758 return false;
28759 };
28760
28761 function shouldSuspend(fiber) {
28762 return shouldSuspendImpl(fiber);
28763 }
28764 var overrideHookState = null;
28765 var overrideHookStateDeletePath = null;
28766 var overrideHookStateRenamePath = null;
28767 var overrideProps = null;
28768 var overridePropsDeletePath = null;
28769 var overridePropsRenamePath = null;
28770 var scheduleUpdate = null;
28771 var setErrorHandler = null;
28772 var setSuspenseHandler = null;
28773
28774 {
28775 var copyWithDeleteImpl = function (obj, path, index) {
28776 var key = path[index];
28777 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
28778
28779 if (index + 1 === path.length) {
28780 if (isArray(updated)) {
28781 updated.splice(key, 1);
28782 } else {
28783 delete updated[key];
28784 }
28785
28786 return updated;
28787 } // $FlowFixMe number or string is fine here
28788
28789
28790 updated[key] = copyWithDeleteImpl(obj[key], path, index + 1);
28791 return updated;
28792 };
28793
28794 var copyWithDelete = function (obj, path) {
28795 return copyWithDeleteImpl(obj, path, 0);
28796 };
28797
28798 var copyWithRenameImpl = function (obj, oldPath, newPath, index) {
28799 var oldKey = oldPath[index];
28800 var updated = isArray(obj) ? obj.slice() : assign({}, obj);
28801
28802 if (index + 1 === oldPath.length) {
28803 var newKey = newPath[index]; // $FlowFixMe number or string is fine here
28804
28805 updated[newKey] = updated[oldKey];
28806
28807 if (isArray(updated)) {
28808 updated.splice(oldKey, 1);
28809 } else {
28810 delete updated[oldKey];
28811 }
28812 } else {
28813 // $FlowFixMe number or string is fine here
28814 updated[oldKey] = copyWithRenameImpl( // $FlowFixMe number or string is fine here
28815 obj[oldKey], oldPath, newPath, index + 1);
28816 }
28817
28818 return updated;
28819 };
28820
28821 var copyWithRename = function (obj, oldPath, newPath) {
28822 if (oldPath.length !== newPath.length) {
28823 warn('copyWithRename() expects paths of the same length');
28824
28825 return;
28826 } else {
28827 for (var i = 0; i < newPath.length - 1; i++) {
28828 if (oldPath[i] !== newPath[i]) {
28829 warn('copyWithRename() expects paths to be the same except for the deepest key');
28830
28831 return;
28832 }
28833 }
28834 }
28835
28836 return copyWithRenameImpl(obj, oldPath, newPath, 0);
28837 };
28838
28839 var copyWithSetImpl = function (obj, path, index, value) {
28840 if (index >= path.length) {
28841 return value;
28842 }
28843
28844 var key = path[index];
28845 var updated = isArray(obj) ? obj.slice() : assign({}, obj); // $FlowFixMe number or string is fine here
28846
28847 updated[key] = copyWithSetImpl(obj[key], path, index + 1, value);
28848 return updated;
28849 };
28850
28851 var copyWithSet = function (obj, path, value) {
28852 return copyWithSetImpl(obj, path, 0, value);
28853 };
28854
28855 var findHook = function (fiber, id) {
28856 // For now, the "id" of stateful hooks is just the stateful hook index.
28857 // This may change in the future with e.g. nested hooks.
28858 var currentHook = fiber.memoizedState;
28859
28860 while (currentHook !== null && id > 0) {
28861 currentHook = currentHook.next;
28862 id--;
28863 }
28864
28865 return currentHook;
28866 }; // Support DevTools editable values for useState and useReducer.
28867
28868
28869 overrideHookState = function (fiber, id, path, value) {
28870 var hook = findHook(fiber, id);
28871
28872 if (hook !== null) {
28873 var newState = copyWithSet(hook.memoizedState, path, value);
28874 hook.memoizedState = newState;
28875 hook.baseState = newState; // We aren't actually adding an update to the queue,
28876 // because there is no update we can add for useReducer hooks that won't trigger an error.
28877 // (There's no appropriate action type for DevTools overrides.)
28878 // As a result though, React will see the scheduled update as a noop and bailout.
28879 // Shallow cloning props works as a workaround for now to bypass the bailout check.
28880
28881 fiber.memoizedProps = assign({}, fiber.memoizedProps);
28882 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
28883 }
28884 };
28885
28886 overrideHookStateDeletePath = function (fiber, id, path) {
28887 var hook = findHook(fiber, id);
28888
28889 if (hook !== null) {
28890 var newState = copyWithDelete(hook.memoizedState, path);
28891 hook.memoizedState = newState;
28892 hook.baseState = newState; // We aren't actually adding an update to the queue,
28893 // because there is no update we can add for useReducer hooks that won't trigger an error.
28894 // (There's no appropriate action type for DevTools overrides.)
28895 // As a result though, React will see the scheduled update as a noop and bailout.
28896 // Shallow cloning props works as a workaround for now to bypass the bailout check.
28897
28898 fiber.memoizedProps = assign({}, fiber.memoizedProps);
28899 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
28900 }
28901 };
28902
28903 overrideHookStateRenamePath = function (fiber, id, oldPath, newPath) {
28904 var hook = findHook(fiber, id);
28905
28906 if (hook !== null) {
28907 var newState = copyWithRename(hook.memoizedState, oldPath, newPath);
28908 hook.memoizedState = newState;
28909 hook.baseState = newState; // We aren't actually adding an update to the queue,
28910 // because there is no update we can add for useReducer hooks that won't trigger an error.
28911 // (There's no appropriate action type for DevTools overrides.)
28912 // As a result though, React will see the scheduled update as a noop and bailout.
28913 // Shallow cloning props works as a workaround for now to bypass the bailout check.
28914
28915 fiber.memoizedProps = assign({}, fiber.memoizedProps);
28916 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
28917 }
28918 }; // Support DevTools props for function components, forwardRef, memo, host components, etc.
28919
28920
28921 overrideProps = function (fiber, path, value) {
28922 fiber.pendingProps = copyWithSet(fiber.memoizedProps, path, value);
28923
28924 if (fiber.alternate) {
28925 fiber.alternate.pendingProps = fiber.pendingProps;
28926 }
28927
28928 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
28929 };
28930
28931 overridePropsDeletePath = function (fiber, path) {
28932 fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path);
28933
28934 if (fiber.alternate) {
28935 fiber.alternate.pendingProps = fiber.pendingProps;
28936 }
28937
28938 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
28939 };
28940
28941 overridePropsRenamePath = function (fiber, oldPath, newPath) {
28942 fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
28943
28944 if (fiber.alternate) {
28945 fiber.alternate.pendingProps = fiber.pendingProps;
28946 }
28947
28948 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
28949 };
28950
28951 scheduleUpdate = function (fiber) {
28952 scheduleUpdateOnFiber(fiber, SyncLane, NoTimestamp);
28953 };
28954
28955 setErrorHandler = function (newShouldErrorImpl) {
28956 shouldErrorImpl = newShouldErrorImpl;
28957 };
28958
28959 setSuspenseHandler = function (newShouldSuspendImpl) {
28960 shouldSuspendImpl = newShouldSuspendImpl;
28961 };
28962 }
28963
28964 function findHostInstanceByFiber(fiber) {
28965 var hostFiber = findCurrentHostFiber(fiber);
28966
28967 if (hostFiber === null) {
28968 return null;
28969 }
28970
28971 return hostFiber.stateNode;
28972 }
28973
28974 function emptyFindFiberByHostInstance(instance) {
28975 return null;
28976 }
28977
28978 function getCurrentFiberForDevTools() {
28979 return current;
28980 }
28981
28982 function injectIntoDevTools(devToolsConfig) {
28983 var findFiberByHostInstance = devToolsConfig.findFiberByHostInstance;
28984 var ReactCurrentDispatcher = ReactSharedInternals.ReactCurrentDispatcher;
28985 return injectInternals({
28986 bundleType: devToolsConfig.bundleType,
28987 version: devToolsConfig.version,
28988 rendererPackageName: devToolsConfig.rendererPackageName,
28989 rendererConfig: devToolsConfig.rendererConfig,
28990 overrideHookState: overrideHookState,
28991 overrideHookStateDeletePath: overrideHookStateDeletePath,
28992 overrideHookStateRenamePath: overrideHookStateRenamePath,
28993 overrideProps: overrideProps,
28994 overridePropsDeletePath: overridePropsDeletePath,
28995 overridePropsRenamePath: overridePropsRenamePath,
28996 setErrorHandler: setErrorHandler,
28997 setSuspenseHandler: setSuspenseHandler,
28998 scheduleUpdate: scheduleUpdate,
28999 currentDispatcherRef: ReactCurrentDispatcher,
29000 findHostInstanceByFiber: findHostInstanceByFiber,
29001 findFiberByHostInstance: findFiberByHostInstance || emptyFindFiberByHostInstance,
29002 // React Refresh
29003 findHostInstancesForRefresh: findHostInstancesForRefresh ,
29004 scheduleRefresh: scheduleRefresh ,
29005 scheduleRoot: scheduleRoot ,
29006 setRefreshHandler: setRefreshHandler ,
29007 // Enables DevTools to append owner stacks to error messages in DEV mode.
29008 getCurrentFiber: getCurrentFiberForDevTools ,
29009 // Enables DevTools to detect reconciler version rather than renderer version
29010 // which may not match for third party renderers.
29011 reconcilerVersion: ReactVersion
29012 });
29013 }
29014
29015 /* global reportError */
29016
29017 var defaultOnRecoverableError = typeof reportError === 'function' ? // In modern browsers, reportError will dispatch an error event,
29018 // emulating an uncaught JavaScript error.
29019 reportError : function (error) {
29020 // In older browsers and test environments, fallback to console.error.
29021 // eslint-disable-next-line react-internal/no-production-logging
29022 console['error'](error);
29023 };
29024
29025 function ReactDOMRoot(internalRoot) {
29026 this._internalRoot = internalRoot;
29027 }
29028
29029 ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function (children) {
29030 var root = this._internalRoot;
29031
29032 if (root === null) {
29033 throw new Error('Cannot update an unmounted root.');
29034 }
29035
29036 {
29037 if (typeof arguments[1] === 'function') {
29038 error('render(...): does not support the second callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
29039 } else if (isValidContainer(arguments[1])) {
29040 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.");
29041 } else if (typeof arguments[1] !== 'undefined') {
29042 error('You passed a second argument to root.render(...) but it only accepts ' + 'one argument.');
29043 }
29044
29045 var container = root.containerInfo;
29046
29047 if (container.nodeType !== COMMENT_NODE) {
29048 var hostInstance = findHostInstanceWithNoPortals(root.current);
29049
29050 if (hostInstance) {
29051 if (hostInstance.parentNode !== container) {
29052 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.");
29053 }
29054 }
29055 }
29056 }
29057
29058 updateContainer(children, root, null, null);
29059 };
29060
29061 ReactDOMHydrationRoot.prototype.unmount = ReactDOMRoot.prototype.unmount = function () {
29062 {
29063 if (typeof arguments[0] === 'function') {
29064 error('unmount(...): does not support a callback argument. ' + 'To execute a side effect after rendering, declare it in a component body with useEffect().');
29065 }
29066 }
29067
29068 var root = this._internalRoot;
29069
29070 if (root !== null) {
29071 this._internalRoot = null;
29072 var container = root.containerInfo;
29073
29074 {
29075 if (isAlreadyRendering()) {
29076 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.');
29077 }
29078 }
29079
29080 flushSync(function () {
29081 updateContainer(null, root, null, null);
29082 });
29083 unmarkContainerAsRoot(container);
29084 }
29085 };
29086
29087 function createRoot(container, options) {
29088 if (!isValidContainer(container)) {
29089 throw new Error('createRoot(...): Target container is not a DOM element.');
29090 }
29091
29092 warnIfReactDOMContainerInDEV(container);
29093 var isStrictMode = false;
29094 var concurrentUpdatesByDefaultOverride = false;
29095 var identifierPrefix = '';
29096 var onRecoverableError = defaultOnRecoverableError;
29097 var transitionCallbacks = null;
29098
29099 if (options !== null && options !== undefined) {
29100 {
29101 if (options.hydrate) {
29102 warn('hydrate through createRoot is deprecated. Use ReactDOMClient.hydrateRoot(container, <App />) instead.');
29103 } else {
29104 if (typeof options === 'object' && options !== null && options.$$typeof === REACT_ELEMENT_TYPE) {
29105 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 />);');
29106 }
29107 }
29108 }
29109
29110 if (options.unstable_strictMode === true) {
29111 isStrictMode = true;
29112 }
29113
29114 if (options.identifierPrefix !== undefined) {
29115 identifierPrefix = options.identifierPrefix;
29116 }
29117
29118 if (options.onRecoverableError !== undefined) {
29119 onRecoverableError = options.onRecoverableError;
29120 }
29121
29122 if (options.transitionCallbacks !== undefined) {
29123 transitionCallbacks = options.transitionCallbacks;
29124 }
29125 }
29126
29127 var root = createContainer(container, ConcurrentRoot, null, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
29128 markContainerAsRoot(root.current, container);
29129 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29130 listenToAllSupportedEvents(rootContainerElement);
29131 return new ReactDOMRoot(root);
29132 }
29133
29134 function ReactDOMHydrationRoot(internalRoot) {
29135 this._internalRoot = internalRoot;
29136 }
29137
29138 function scheduleHydration(target) {
29139 if (target) {
29140 queueExplicitHydrationTarget(target);
29141 }
29142 }
29143
29144 ReactDOMHydrationRoot.prototype.unstable_scheduleHydration = scheduleHydration;
29145 function hydrateRoot(container, initialChildren, options) {
29146 if (!isValidContainer(container)) {
29147 throw new Error('hydrateRoot(...): Target container is not a DOM element.');
29148 }
29149
29150 warnIfReactDOMContainerInDEV(container);
29151
29152 {
29153 if (initialChildren === undefined) {
29154 error('Must provide initial children as second argument to hydrateRoot. ' + 'Example usage: hydrateRoot(domContainer, <App />)');
29155 }
29156 } // For now we reuse the whole bag of options since they contain
29157 // the hydration callbacks.
29158
29159
29160 var hydrationCallbacks = options != null ? options : null; // TODO: Delete this option
29161
29162 var mutableSources = options != null && options.hydratedSources || null;
29163 var isStrictMode = false;
29164 var concurrentUpdatesByDefaultOverride = false;
29165 var identifierPrefix = '';
29166 var onRecoverableError = defaultOnRecoverableError;
29167
29168 if (options !== null && options !== undefined) {
29169 if (options.unstable_strictMode === true) {
29170 isStrictMode = true;
29171 }
29172
29173 if (options.identifierPrefix !== undefined) {
29174 identifierPrefix = options.identifierPrefix;
29175 }
29176
29177 if (options.onRecoverableError !== undefined) {
29178 onRecoverableError = options.onRecoverableError;
29179 }
29180 }
29181
29182 var root = createHydrationContainer(initialChildren, null, container, ConcurrentRoot, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride, identifierPrefix, onRecoverableError);
29183 markContainerAsRoot(root.current, container); // This can't be a comment node since hydration doesn't work on comment nodes anyway.
29184
29185 listenToAllSupportedEvents(container);
29186
29187 if (mutableSources) {
29188 for (var i = 0; i < mutableSources.length; i++) {
29189 var mutableSource = mutableSources[i];
29190 registerMutableSourceForHydration(root, mutableSource);
29191 }
29192 }
29193
29194 return new ReactDOMHydrationRoot(root);
29195 }
29196 function isValidContainer(node) {
29197 return !!(node && (node.nodeType === ELEMENT_NODE || node.nodeType === DOCUMENT_NODE || node.nodeType === DOCUMENT_FRAGMENT_NODE || !disableCommentsAsDOMContainers ));
29198 } // TODO: Remove this function which also includes comment nodes.
29199 // We only use it in places that are currently more relaxed.
29200
29201 function isValidContainerLegacy(node) {
29202 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 '));
29203 }
29204
29205 function warnIfReactDOMContainerInDEV(container) {
29206 {
29207 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
29208 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.');
29209 }
29210
29211 if (isContainerMarkedAsRoot(container)) {
29212 if (container._reactRootContainer) {
29213 error('You are calling ReactDOMClient.createRoot() on a container that was previously ' + 'passed to ReactDOM.render(). This is not supported.');
29214 } else {
29215 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.');
29216 }
29217 }
29218 }
29219 }
29220
29221 var ReactCurrentOwner$3 = ReactSharedInternals.ReactCurrentOwner;
29222 var topLevelUpdateWarnings;
29223
29224 {
29225 topLevelUpdateWarnings = function (container) {
29226 if (container._reactRootContainer && container.nodeType !== COMMENT_NODE) {
29227 var hostInstance = findHostInstanceWithNoPortals(container._reactRootContainer.current);
29228
29229 if (hostInstance) {
29230 if (hostInstance.parentNode !== container) {
29231 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.');
29232 }
29233 }
29234 }
29235
29236 var isRootRenderedBySomeReact = !!container._reactRootContainer;
29237 var rootEl = getReactRootElementInContainer(container);
29238 var hasNonRootReactChild = !!(rootEl && getInstanceFromNode(rootEl));
29239
29240 if (hasNonRootReactChild && !isRootRenderedBySomeReact) {
29241 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.');
29242 }
29243
29244 if (container.nodeType === ELEMENT_NODE && container.tagName && container.tagName.toUpperCase() === 'BODY') {
29245 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.');
29246 }
29247 };
29248 }
29249
29250 function getReactRootElementInContainer(container) {
29251 if (!container) {
29252 return null;
29253 }
29254
29255 if (container.nodeType === DOCUMENT_NODE) {
29256 return container.documentElement;
29257 } else {
29258 return container.firstChild;
29259 }
29260 }
29261
29262 function noopOnRecoverableError() {// This isn't reachable because onRecoverableError isn't called in the
29263 // legacy API.
29264 }
29265
29266 function legacyCreateRootFromDOMContainer(container, initialChildren, parentComponent, callback, isHydrationContainer) {
29267 if (isHydrationContainer) {
29268 if (typeof callback === 'function') {
29269 var originalCallback = callback;
29270
29271 callback = function () {
29272 var instance = getPublicRootInstance(root);
29273 originalCallback.call(instance);
29274 };
29275 }
29276
29277 var root = createHydrationContainer(initialChildren, callback, container, LegacyRoot, null, // hydrationCallbacks
29278 false, // isStrictMode
29279 false, // concurrentUpdatesByDefaultOverride,
29280 '', // identifierPrefix
29281 noopOnRecoverableError);
29282 container._reactRootContainer = root;
29283 markContainerAsRoot(root.current, container);
29284 var rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29285 listenToAllSupportedEvents(rootContainerElement);
29286 flushSync();
29287 return root;
29288 } else {
29289 // First clear any existing content.
29290 var rootSibling;
29291
29292 while (rootSibling = container.lastChild) {
29293 container.removeChild(rootSibling);
29294 }
29295
29296 if (typeof callback === 'function') {
29297 var _originalCallback = callback;
29298
29299 callback = function () {
29300 var instance = getPublicRootInstance(_root);
29301
29302 _originalCallback.call(instance);
29303 };
29304 }
29305
29306 var _root = createContainer(container, LegacyRoot, null, // hydrationCallbacks
29307 false, // isStrictMode
29308 false, // concurrentUpdatesByDefaultOverride,
29309 '', // identifierPrefix
29310 noopOnRecoverableError);
29311
29312 container._reactRootContainer = _root;
29313 markContainerAsRoot(_root.current, container);
29314
29315 var _rootContainerElement = container.nodeType === COMMENT_NODE ? container.parentNode : container;
29316
29317 listenToAllSupportedEvents(_rootContainerElement); // Initial mount should not be batched.
29318
29319 flushSync(function () {
29320 updateContainer(initialChildren, _root, parentComponent, callback);
29321 });
29322 return _root;
29323 }
29324 }
29325
29326 function warnOnInvalidCallback$1(callback, callerName) {
29327 {
29328 if (callback !== null && typeof callback !== 'function') {
29329 error('%s(...): Expected the last optional `callback` argument to be a ' + 'function. Instead received: %s.', callerName, callback);
29330 }
29331 }
29332 }
29333
29334 function legacyRenderSubtreeIntoContainer(parentComponent, children, container, forceHydrate, callback) {
29335 {
29336 topLevelUpdateWarnings(container);
29337 warnOnInvalidCallback$1(callback === undefined ? null : callback, 'render');
29338 }
29339
29340 var maybeRoot = container._reactRootContainer;
29341 var root;
29342
29343 if (!maybeRoot) {
29344 // Initial mount
29345 root = legacyCreateRootFromDOMContainer(container, children, parentComponent, callback, forceHydrate);
29346 } else {
29347 root = maybeRoot;
29348
29349 if (typeof callback === 'function') {
29350 var originalCallback = callback;
29351
29352 callback = function () {
29353 var instance = getPublicRootInstance(root);
29354 originalCallback.call(instance);
29355 };
29356 } // Update
29357
29358
29359 updateContainer(children, root, parentComponent, callback);
29360 }
29361
29362 return getPublicRootInstance(root);
29363 }
29364
29365 function findDOMNode(componentOrElement) {
29366 {
29367 var owner = ReactCurrentOwner$3.current;
29368
29369 if (owner !== null && owner.stateNode !== null) {
29370 var warnedAboutRefsInRender = owner.stateNode._warnedAboutRefsInRender;
29371
29372 if (!warnedAboutRefsInRender) {
29373 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');
29374 }
29375
29376 owner.stateNode._warnedAboutRefsInRender = true;
29377 }
29378 }
29379
29380 if (componentOrElement == null) {
29381 return null;
29382 }
29383
29384 if (componentOrElement.nodeType === ELEMENT_NODE) {
29385 return componentOrElement;
29386 }
29387
29388 {
29389 return findHostInstanceWithWarning(componentOrElement, 'findDOMNode');
29390 }
29391 }
29392 function hydrate(element, container, callback) {
29393 {
29394 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');
29395 }
29396
29397 if (!isValidContainerLegacy(container)) {
29398 throw new Error('Target container is not a DOM element.');
29399 }
29400
29401 {
29402 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29403
29404 if (isModernRoot) {
29405 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)?');
29406 }
29407 } // TODO: throw or warn if we couldn't hydrate?
29408
29409
29410 return legacyRenderSubtreeIntoContainer(null, element, container, true, callback);
29411 }
29412 function render(element, container, callback) {
29413 {
29414 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');
29415 }
29416
29417 if (!isValidContainerLegacy(container)) {
29418 throw new Error('Target container is not a DOM element.');
29419 }
29420
29421 {
29422 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29423
29424 if (isModernRoot) {
29425 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)?');
29426 }
29427 }
29428
29429 return legacyRenderSubtreeIntoContainer(null, element, container, false, callback);
29430 }
29431 function unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
29432 {
29433 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');
29434 }
29435
29436 if (!isValidContainerLegacy(containerNode)) {
29437 throw new Error('Target container is not a DOM element.');
29438 }
29439
29440 if (parentComponent == null || !has(parentComponent)) {
29441 throw new Error('parentComponent must be a valid React Component');
29442 }
29443
29444 return legacyRenderSubtreeIntoContainer(parentComponent, element, containerNode, false, callback);
29445 }
29446 function unmountComponentAtNode(container) {
29447 if (!isValidContainerLegacy(container)) {
29448 throw new Error('unmountComponentAtNode(...): Target container is not a DOM element.');
29449 }
29450
29451 {
29452 var isModernRoot = isContainerMarkedAsRoot(container) && container._reactRootContainer === undefined;
29453
29454 if (isModernRoot) {
29455 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()?');
29456 }
29457 }
29458
29459 if (container._reactRootContainer) {
29460 {
29461 var rootEl = getReactRootElementInContainer(container);
29462 var renderedByDifferentReact = rootEl && !getInstanceFromNode(rootEl);
29463
29464 if (renderedByDifferentReact) {
29465 error("unmountComponentAtNode(): The node you're attempting to unmount " + 'was rendered by another copy of React.');
29466 }
29467 } // Unmount should not be batched.
29468
29469
29470 flushSync(function () {
29471 legacyRenderSubtreeIntoContainer(null, null, container, false, function () {
29472 // $FlowFixMe This should probably use `delete container._reactRootContainer`
29473 container._reactRootContainer = null;
29474 unmarkContainerAsRoot(container);
29475 });
29476 }); // If you call unmountComponentAtNode twice in quick succession, you'll
29477 // get `true` twice. That's probably fine?
29478
29479 return true;
29480 } else {
29481 {
29482 var _rootEl = getReactRootElementInContainer(container);
29483
29484 var hasNonRootReactChild = !!(_rootEl && getInstanceFromNode(_rootEl)); // Check if the container itself is a React root node.
29485
29486 var isContainerReactRoot = container.nodeType === ELEMENT_NODE && isValidContainerLegacy(container.parentNode) && !!container.parentNode._reactRootContainer;
29487
29488 if (hasNonRootReactChild) {
29489 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.');
29490 }
29491 }
29492
29493 return false;
29494 }
29495 }
29496
29497 setAttemptSynchronousHydration(attemptSynchronousHydration$1);
29498 setAttemptContinuousHydration(attemptContinuousHydration$1);
29499 setAttemptHydrationAtCurrentPriority(attemptHydrationAtCurrentPriority$1);
29500 setGetCurrentUpdatePriority(getCurrentUpdatePriority);
29501 setAttemptHydrationAtPriority(runWithPriority);
29502
29503 {
29504 if (typeof Map !== 'function' || // $FlowIssue Flow incorrectly thinks Map has no prototype
29505 Map.prototype == null || typeof Map.prototype.forEach !== 'function' || typeof Set !== 'function' || // $FlowIssue Flow incorrectly thinks Set has no prototype
29506 Set.prototype == null || typeof Set.prototype.clear !== 'function' || typeof Set.prototype.forEach !== 'function') {
29507 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');
29508 }
29509 }
29510
29511 setRestoreImplementation(restoreControlledState$3);
29512 setBatchingImplementation(batchedUpdates$1, discreteUpdates, flushSync);
29513
29514 function createPortal$1(children, container) {
29515 var key = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null;
29516
29517 if (!isValidContainer(container)) {
29518 throw new Error('Target container is not a DOM element.');
29519 } // TODO: pass ReactDOM portal implementation as third argument
29520 // $FlowFixMe The Flow type is opaque but there's no way to actually create it.
29521
29522
29523 return createPortal(children, container, null, key);
29524 }
29525
29526 function renderSubtreeIntoContainer(parentComponent, element, containerNode, callback) {
29527 return unstable_renderSubtreeIntoContainer(parentComponent, element, containerNode, callback);
29528 }
29529
29530 var Internals = {
29531 usingClientEntryPoint: false,
29532 // Keep in sync with ReactTestUtils.js.
29533 // This is an array for better minification.
29534 Events: [getInstanceFromNode, getNodeFromInstance, getFiberCurrentPropsFromNode, enqueueStateRestore, restoreStateIfNeeded, batchedUpdates$1]
29535 };
29536
29537 function createRoot$1(container, options) {
29538 {
29539 if (!Internals.usingClientEntryPoint) {
29540 error('You are importing createRoot from "react-dom" which is not supported. ' + 'You should instead import it from "react-dom/client".');
29541 }
29542 }
29543
29544 return createRoot(container, options);
29545 }
29546
29547 function hydrateRoot$1(container, initialChildren, options) {
29548 {
29549 if (!Internals.usingClientEntryPoint) {
29550 error('You are importing hydrateRoot from "react-dom" which is not supported. ' + 'You should instead import it from "react-dom/client".');
29551 }
29552 }
29553
29554 return hydrateRoot(container, initialChildren, options);
29555 } // Overload the definition to the two valid signatures.
29556 // Warning, this opts-out of checking the function body.
29557
29558
29559 // eslint-disable-next-line no-redeclare
29560 function flushSync$1(fn) {
29561 {
29562 if (isAlreadyRendering()) {
29563 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.');
29564 }
29565 }
29566
29567 return flushSync(fn);
29568 }
29569 var foundDevTools = injectIntoDevTools({
29570 findFiberByHostInstance: getClosestInstanceFromNode,
29571 bundleType: 1 ,
29572 version: ReactVersion,
29573 rendererPackageName: 'react-dom'
29574 });
29575
29576 {
29577 if (!foundDevTools && canUseDOM && window.top === window.self) {
29578 // If we're in Chrome or Firefox, provide a download link if not installed.
29579 if (navigator.userAgent.indexOf('Chrome') > -1 && navigator.userAgent.indexOf('Edge') === -1 || navigator.userAgent.indexOf('Firefox') > -1) {
29580 var protocol = window.location.protocol; // Don't warn in exotic cases like chrome-extension://.
29581
29582 if (/^(https?|file):$/.test(protocol)) {
29583 // eslint-disable-next-line react-internal/no-production-logging
29584 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');
29585 }
29586 }
29587 }
29588 }
29589
29590 exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
29591 exports.createPortal = createPortal$1;
29592 exports.createRoot = createRoot$1;
29593 exports.findDOMNode = findDOMNode;
29594 exports.flushSync = flushSync$1;
29595 exports.hydrate = hydrate;
29596 exports.hydrateRoot = hydrateRoot$1;
29597 exports.render = render;
29598 exports.unmountComponentAtNode = unmountComponentAtNode;
29599 exports.unstable_batchedUpdates = batchedUpdates$1;
29600 exports.unstable_renderSubtreeIntoContainer = renderSubtreeIntoContainer;
29601 exports.version = ReactVersion;
29602
29603})));