text: /** @license React v16.5.2
   * scheduler.development.js
   *
   * Copyright (c) Facebook, Inc. and its affiliates.
   *
   * This source code is licensed under the MIT license found in the
   * LICENSE file in the root directory of this source tree.
   */
  
  'use strict';
  
  
  
  if (process.env.NODE_ENV !== "production") {
    (function() {
  'use strict';
  
  Object.defineProperty(exports, '__esModule', { value: true });
  
  /* eslint-disable no-var */
  
  // TODO: Use symbols?
  var ImmediatePriority = 1;
  var InteractivePriority = 2;
  var NormalPriority = 3;
  var WheneverPriority = 4;
  
  // Max 31 bit integer. The max integer size in V8 for 32-bit systems.
  // Math.pow(2, 30) - 1
  // 0b111111111111111111111111111111
  var maxSigned31BitInt = 1073741823;
  
  // Times out immediately
  var IMMEDIATE_PRIORITY_TIMEOUT = -1;
  // Eventually times out
  var INTERACTIVE_PRIORITY_TIMEOUT = 250;
  var NORMAL_PRIORITY_TIMEOUT = 5000;
  // Never times out
  var WHENEVER_PRIORITY_TIMEOUT = maxSigned31BitInt;
  
  // Callbacks are stored as a circular, doubly linked list.
  var firstCallbackNode = null;
  
  var currentPriorityLevel = NormalPriority;
  var currentEventStartTime = -1;
  var currentExpirationTime = -1;
  
  // This is set when a callback is being executed, to prevent re-entrancy.
  var isExecutingCallback = false;
  
  var isHostCallbackScheduled = false;
  
  var hasNativePerformanceNow = typeof performance === 'object' && typeof performance.now === 'function';
  
  var timeRemaining;
  if (hasNativePerformanceNow) {
    timeRemaining = function () {
      if (firstCallbackNode !== null && firstCallbackNode.expirationTime < currentExpirationTime) {
        // A higher priority callback was scheduled. Yield so we can switch to
        // working on that.
        return 0;
      }
      // We assume that if we have a performance timer that the rAF callback
      // gets a performance timer value. Not sure if this is always true.
      var remaining = getFrameDeadline() - performance.now();
      return remaining > 0 ? remaining : 0;
    };
  } else {
    timeRemaining = function () {
      // Fallback to Date.now()
      if (firstCallbackNode !== null && firstCallbackNode.expirationTime < currentExpirationTime) {
        return 0;
      }
      var remaining = getFrameDeadline() - Date.now();
      return remaining > 0 ? remaining : 0;
    };
  }
  
  var deadlineObject = {
    timeRemaining: timeRemaining,
    didTimeout: false
  };
  
  function ensureHostCallbackIsScheduled() {
    if (isExecutingCallback) {
      // Don't schedule work yet; wait until the next time we yield.
      return;
    }
    // Schedule the host callback using the earliest expiration in the list.
    var expirationTime = firstCallbackNode.expirationTime;
    if (!isHostCallbackScheduled) {
      isHostCallbackScheduled = true;
    } else {
      // Cancel the existing host callback.
      cancelHostCallback();
    }
    requestHostCallback(flushWork, expirationTime);
  }
  
  function flushFirstCallback() {
    var flushedNode = firstCallbackNode;
  
    // Remove the node from the list before calling the callback. That way the
    // list is in a consistent state even if the callback throws.
    var next = firstCallbackNode.next;
    if (firstCallbackNode === next) {
      // This is the last callback in the list.
      firstCallbackNode = null;
      next = null;
    } else {
      var lastCallbackNode = firstCallbackNode.previous;
      firstCallbackNode = lastCallbackNode.next = next;
      next.previous = lastCallbackNode;
    }
  
    flushedNode.next = flushedNode.previous = null;
  
    // Now it's safe to call the callback.
    var callback = flushedNode.callback;
    var expirationTime = flushedNode.expirationTime;
    var priorityLevel = flushedNode.priorityLevel;
    var previousPriorityLevel = currentPriorityLevel;
    var previousExpirationTime = currentExpirationTime;
    currentPriorityLevel = priorityLevel;
    currentExpirationTime = expirationTime;
    var continuationCallback;
    try {
      continuationCallback = callback(deadlineObject);
    } finally {
      currentPriorityLevel = previousPriorityLevel;
      currentExpirationTime = previousExpirationTime;
    }
  
    // A callback may return a continuation. The continuation should be scheduled
    // with the same priority and expiration as the just-finished callback.
    if (typeof continuationCallback === 'function') {
      var continuationNode = {
        callback: continuationCallback,
        priorityLevel: priorityLevel,
        expirationTime: expirationTime,
        next: null,
        previous: null
      };
  
      // Insert the new callback into the list, sorted by its expiration. This is
      // almost the same as the code in `scheduleCallback`, except the callback
      // is inserted into the list *before* callbacks of equal expiration instead
      // of after.
      if (firstCallbackNode === null) {
        // This is the first callback in the list.
        firstCallbackNode = continuationNode.next = continuationNode.previous = continuationNode;
      } else {
        var nextAfterContinuation = null;
        var node = firstCallbackNode;
        do {
          if (node.expirationTime >= expirationTime) {
            // This callback expires at or after the continuation. We will insert
            // the continuation *before* this callback.
            nextAfterContinuation = node;
            break;
          }
          node = node.next;
        } while (node !== firstCallbackNode);
  
        if (nextAfterContinuation === null) {
          // No equal or lower priority callback was found, which means the new
          // callback is the lowest priority callback in the list.
          nextAfterContinuation = firstCallbackNode;
        } else if (nextAfterContinuation === firstCallbackNode) {
          // The new callback is the highest priority callback in the list.
          firstCallbackNode = continuationNode;
          ensureHostCallbackIsScheduled(firstCallbackNode);
        }
  
        var previous = nextAfterContinuation.previous;
        previous.next = nextAfterContinuation.previous = continuationNode;
        continuationNode.next = nextAfterContinuation;
        continuationNode.previous = previous;
      }
    }
  }
  
  function flushImmediateWork() {
    if (
    // Confirm we've exited the outer most event handler
    currentEventStartTime === -1 && firstCallbackNode !== null && firstCallbackNode.priorityLevel === ImmediatePriority) {
      isExecutingCallback = true;
      deadlineObject.didTimeout = true;
      try {
        do {
          flushFirstCallback();
        } while (
        // Keep flushing until there are no more immediate callbacks
        firstCallbackNode !== null && firstCallbackNode.priorityLevel === ImmediatePriority);
      } finally {
        isExecutingCallback = false;
        if (firstCallbackNode !== null) {
          // There's still work remaining. Request another callback.
          ensureHostCallbackIsScheduled(firstCallbackNode);
        } else {
          isHostCallbackScheduled = false;
        }
      }
    }
  }
  
  function flushWork(didTimeout) {
    isExecutingCallback = true;
    deadlineObject.didTimeout = didTimeout;
    try {
      if (didTimeout) {
        // Flush all the expired callbacks without yielding.
        while (firstCallbackNode !== null) {
          // Read the current time. Flush all the callbacks that expire at or
          // earlier than that time. Then read the current time again and repeat.
          // This optimizes for as few performance.now calls as possible.
          var currentTime = exports.unstable_now();
          if (firstCallbackNode.expirationTime <= currentTime) {
            do {
              flushFirstCallback();
            } while (firstCallbackNode !== null && firstCallbackNode.expirationTime <= currentTime);
            continue;
          }
          break;
        }
      } else {
        // Keep flushing callbacks until we run out of time in the frame.
        if (firstCallbackNode !== null) {
          do {
            flushFirstCallback();
          } while (firstCallbackNode !== null && getFrameDeadline() - exports.unstable_now() > 0);
        }
      }
    } finally {
      isExecutingCallback = false;
      if (firstCallbackNode !== null) {
        // There's still work remaining. Request another callback.
        ensureHostCallbackIsScheduled(firstCallbackNode);
      } else {
        isHostCallbackScheduled = false;
      }
      // Before exiting, flush all the immediate work that was scheduled.
      flushImmediateWork();
    }
  }
  
  function unstable_runWithPriority(priorityLevel, eventHandler) {
    switch (priorityLevel) {
      case ImmediatePriority:
      case InteractivePriority:
      case NormalPriority:
      case WheneverPriority:
        break;
      default:
        priorityLevel = NormalPriority;
    }
  
    var previousPriorityLevel = currentPriorityLevel;
    var previousEventStartTime = currentEventStartTime;
    currentPriorityLevel = priorityLevel;
    currentEventStartTime = exports.unstable_now();
  
    try {
      return eventHandler();
    } finally {
      currentPriorityLevel = previousPriorityLevel;
      currentEventStartTime = previousEventStartTime;
  
      // Before exiting, flush all the immediate work that was scheduled.
      flushImmediateWork();
    }
  }
  
  function unstable_wrapCallback(callback) {
    var parentPriorityLevel = currentPriorityLevel;
    return function () {
      // This is a fork of runWithPriority, inlined for performance.
      var previousPriorityLevel = currentPriorityLevel;
      var previousEventStartTime = currentEventStartTime;
      currentPriorityLevel = parentPriorityLevel;
      currentEventStartTime = exports.unstable_now();
  
      try {
        return callback.apply(this, arguments);
      } finally {
        currentPriorityLevel = previousPriorityLevel;
        currentEventStartTime = previousEventStartTime;
        flushImmediateWork();
      }
    };
  }
  
  function unstable_scheduleCallback(callback, deprecated_options) {
    var startTime = currentEventStartTime !== -1 ? currentEventStartTime : exports.unstable_now();
  
    var expirationTime;
    if (typeof deprecated_options === 'object' && deprecated_options !== null && typeof deprecated_options.timeout === 'number') {
      // FIXME: Remove this branch once we lift expiration times out of React.
      expirationTime = startTime + deprecated_options.timeout;
    } else {
      switch (currentPriorityLevel) {
        case ImmediatePriority:
          expirationTime = startTime + IMMEDIATE_PRIORITY_TIMEOUT;
          break;
        case InteractivePriority:
          expirationTime = startTime + INTERACTIVE_PRIORITY_TIMEOUT;
          break;
        case WheneverPriority:
          expirationTime = startTime + WHENEVER_PRIORITY_TIMEOUT;
          break;
        case NormalPriority:
        default:
          expirationTime = startTime + NORMAL_PRIORITY_TIMEOUT;
      }
    }
  
    var newNode = {
      callback: callback,
      priorityLevel: currentPriorityLevel,
      expirationTime: expirationTime,
      next: null,
      previous: null
    };
  
    // Insert the new callback into the list, ordered first by expiration, then
    // by insertion. So the new callback is inserted any other callback with
    // equal expiration.
    if (firstCallbackNode === null) {
      // This is the first callback in the list.
      firstCallbackNode = newNode.next = newNode.previous = newNode;
      ensureHostCallbackIsScheduled(firstCallbackNode);
    } else {
      var next = null;
      var node = firstCallbackNode;
      do {
        if (node.expirationTime > expirationTime) {
          // The new callback expires before this one.
          next = node;
          break;
        }
        node = node.next;
      } while (node !== firstCallbackNode);
  
      if (next === null) {
        // No callback with a later expiration was found, which means the new
        // callback has the latest expiration in the list.
        next = firstCallbackNode;
      } else if (next === firstCallbackNode) {
        // The new callback has the earliest expiration in the entire list.
        firstCallbackNode = newNode;
        ensureHostCallbackIsScheduled(firstCallbackNode);
      }
  
      var previous = next.previous;
      previous.next = next.previous = newNode;
      newNode.next = next;
      newNode.previous = previous;
    }
  
    return newNode;
  }
  
  function unstable_cancelCallback(callbackNode) {
    var next = callbackNode.next;
    if (next === null) {
      // Already cancelled.
      return;
    }
  
    if (next === callbackNode) {
      // This is the only scheduled callback. Clear the list.
      firstCallbackNode = null;
    } else {
      // Remove the callback from its position in the list.
      if (callbackNode === firstCallbackNode) {
        firstCallbackNode = next;
      }
      var previous = callbackNode.previous;
      previous.next = next;
      next.previous = previous;
    }
  
    callbackNode.next = callbackNode.previous = null;
  }
  
  function unstable_getCurrentPriorityLevel() {
    return currentPriorityLevel;
  }
  
  // The remaining code is essentially a polyfill for requestIdleCallback. It
  // works by scheduling a requestAnimationFrame, storing the time for the start
  // of the frame, then scheduling a postMessage which gets scheduled after paint.
  // Within the postMessage handler do as much work as possible until time + frame
  // rate. By separating the idle call into a separate event tick we ensure that
  // layout, paint and other browser work is counted against the available time.
  // The frame rate is dynamically adjusted.
  
  // We capture a local reference to any global, in case it gets polyfilled after
  // this module is initially evaluated. We want to be using a
  // consistent implementation.
  var localDate = Date;
  
  // This initialization code may run even on server environments if a component
  // just imports ReactDOM (e.g. for findDOMNode). Some environments might not
  // have setTimeout or clearTimeout. However, we always expect them to be defined
  // on the client. https://github.com/facebook/react/pull/13088
  var localSetTimeout = typeof setTimeout === 'function' ? setTimeout : undefined;
  var localClearTimeout = typeof clearTimeout === 'function' ? clearTimeout : undefined;
  
  // We don't expect either of these to necessarily be defined, but we will error
  // later if they are missing on the client.
  var localRequestAnimationFrame = typeof requestAnimationFrame === 'function' ? requestAnimationFrame : undefined;
  var localCancelAnimationFrame = typeof cancelAnimationFrame === 'function' ? cancelAnimationFrame : undefined;
  
  // requestAnimationFrame does not run when the tab is in the background. If
  // we're backgrounded we prefer for that work to happen so that the page
  // continues to load in the background. So we also schedule a 'setTimeout' as
  // a fallback.
  // TODO: Need a better heuristic for backgrounded work.
  var ANIMATION_FRAME_TIMEOUT = 100;
  var rAFID;
  var rAFTimeoutID;
  var requestAnimationFrameWithTimeout = function (callback) {
    // schedule rAF and also a setTimeout
    rAFID = localRequestAnimationFrame(function (timestamp) {
      // cancel the setTimeout
      localClearTimeout(rAFTimeoutID);
      callback(timestamp);
    });
    rAFTimeoutID = localSetTimeout(function () {
      // cancel the requestAnimationFrame
      localCancelAnimationFrame(rAFID);
      callback(exports.unstable_now());
    }, ANIMATION_FRAME_TIMEOUT);
  };
  
  if (hasNativePerformanceNow) {
    var Performance = performance;
    exports.unstable_now = function () {
      return Performance.now();
    };
  } else {
    exports.unstable_now = function () {
      return localDate.now();
    };
  }
  
  var requestHostCallback;
  var cancelHostCallback;
  var getFrameDeadline;
  
  if (typeof window !== 'undefined' && window._schedMock) {
    // Dynamic injection, only for testing purposes.
    var impl = window._schedMock;
    requestHostCallback = impl[0];
    cancelHostCallback = impl[1];
    getFrameDeadline = impl[2];
  } else if (
  // If Scheduler runs in a non-DOM environment, it falls back to a naive
  // implementation using setTimeout.
  typeof window === 'undefined' ||
  // "addEventListener" might not be available on the window object
  // if this is a mocked "window" object. So we need to validate that too.
  typeof window.addEventListener !== 'function') {
    var _callback = null;
    var _currentTime = -1;
    var _flushCallback = function (didTimeout, ms) {
      if (_callback !== null) {
        var cb = _callback;
        _callback = null;
        try {
          _currentTime = ms;
          cb(didTimeout);
        } finally {
          _currentTime = -1;
        }
      }
    };
    requestHostCallback = function (cb, ms) {
      if (_currentTime !== -1) {
        // Protect against re-entrancy.
        setTimeout(requestHostCallback, 0, cb, ms);
      } else {
        _callback = cb;
        setTimeout(_flushCallback, ms, true, ms);
        setTimeout(_flushCallback, maxSigned31BitInt, false, maxSigned31BitInt);
      }
    };
    cancelHostCallback = function () {
      _callback = null;
    };
    getFrameDeadline = function () {
      return Infinity;
    };
    exports.unstable_now = function () {
      return _currentTime === -1 ? 0 : _currentTime;
    };
  } else {
    if (typeof console !== 'undefined') {
      // TODO: Remove fb.me link
      if (typeof localRequestAnimationFrame !== 'function') {
        console.error("This browser doesn't support requestAnimationFrame. " + 'Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
      }
      if (typeof localCancelAnimationFrame !== 'function') {
        console.error("This browser doesn't support cancelAnimationFrame. " + 'Make sure that you load a ' + 'polyfill in older browsers. https://fb.me/react-polyfills');
      }
    }
  
    var scheduledCallback = null;
    var isIdleScheduled = false;
    var timeoutTime = -1;
  
    var isAnimationFrameScheduled = false;
  
    var isPerformingIdleWork = false;
  
    var frameDeadline = 0;
    // We start out assuming that we run at 30fps but then the heuristic tracking
    // will adjust this value to a faster fps if we get more frequent animation
    // frames.
    var previousFrameTime = 33;
    var activeFrameTime = 33;
  
    getFrameDeadline = function () {
      return frameDeadline;
    };
  
    // We use the postMessage trick to defer idle work until after the repaint.
    var messageKey = '__reactIdleCallback$' + Math.random().toString(36).slice(2);
    var idleTick = function (event) {
      if (event.source !== window || event.data !== messageKey) {
        return;
      }
  
      isIdleScheduled = false;
  
      var currentTime = exports.unstable_now();
  
      var didTimeout = false;
      if (frameDeadline - currentTime <= 0) {
        // There's no time left in this idle period. Check if the callback has
        // a timeout and whether it's been exceeded.
        if (timeoutTime !== -1 && timeoutTime <= currentTime) {
          // Exceeded the timeout. Invoke the callback even though there's no
          // time left.
          didTimeout = true;
        } else {
          // No timeout.
          if (!isAnimationFrameScheduled) {
            // Schedule another animation callback so we retry later.
            isAnimationFrameScheduled = true;
            requestAnimationFrameWithTimeout(animationTick);
          }
          // Exit without invoking the callback.
          return;
        }
      }
  
      timeoutTime = -1;
      var callback = scheduledCallback;
      scheduledCallback = null;
      if (callback !== null) {
        isPerformingIdleWork = true;
        try {
          callback(didTimeout);
        } finally {
          isPerformingIdleWork = false;
        }
      }
    };
    // Assumes that we have addEventListener in this environment. Might need
    // something better for old IE.
    window.addEventListener('message', idleTick, false);
  
    var animationTick = function (rafTime) {
      isAnimationFrameScheduled = false;
      var nextFrameTime = rafTime - frameDeadline + activeFrameTime;
      if (nextFrameTime < activeFrameTime && previousFrameTime < activeFrameTime) {
        if (nextFrameTime < 8) {
          // Defensive coding. We don't support higher frame rates than 120hz.
          // If the calculated frame time gets lower than 8, it is probably a bug.
          nextFrameTime = 8;
        }
        // If one frame goes long, then the next one can be short to catch up.
        // If two frames are short in a row, then that's an indication that we
        // actually have a higher frame rate than what we're currently optimizing.
        // We adjust our heuristic dynamically accordingly. For example, if we're
        // running on 120hz display or 90hz VR display.
        // Take the max of the two in case one of them was an anomaly due to
        // missed frame deadlines.
        activeFrameTime = nextFrameTime < previousFrameTime ? previousFrameTime : nextFrameTime;
      } else {
        previousFrameTime = nextFrameTime;
      }
      frameDeadline = rafTime + activeFrameTime;
      if (!isIdleScheduled) {
        isIdleScheduled = true;
        window.postMessage(messageKey, '*');
      }
    };
  
    requestHostCallback = function (callback, absoluteTimeout) {
      scheduledCallback = callback;
      timeoutTime = absoluteTimeout;
      if (isPerformingIdleWork || absoluteTimeout < 0) {
        // Don't wait for the next frame. Continue working ASAP, in a new event.
        window.postMessage(messageKey, '*');
      } else if (!isAnimationFrameScheduled) {
        // If rAF didn't already schedule one, we need to schedule a frame.
        // TODO: If this rAF doesn't materialize because the browser throttles, we
        // might want to still have setTimeout trigger rIC as a backup to ensure
        // that we keep performing work.
        isAnimationFrameScheduled = true;
        requestAnimationFrameWithTimeout(animationTick);
      }
    };
  
    cancelHostCallback = function () {
      scheduledCallback = null;
      isIdleScheduled = false;
      timeoutTime = -1;
    };
  }
  
  exports.unstable_ImmediatePriority = ImmediatePriority;
  exports.unstable_InteractivePriority = InteractivePriority;
  exports.unstable_NormalPriority = NormalPriority;
  exports.unstable_WheneverPriority = WheneverPriority;
  exports.unstable_runWithPriority = unstable_runWithPriority;
  exports.unstable_scheduleCallback = unstable_scheduleCallback;
  exports.unstable_cancelCallback = unstable_cancelCallback;
  exports.unstable_wrapCallback = unstable_wrapCallback;
  exports.unstable_getCurrentPriorityLevel = unstable_getCurrentPriorityLevel;
    })();
  }
  