text: //@ui5-bundle sap-ui-core-nojQuery-dbg.js
  //@ui5-bundle-raw-include sap/ui/thirdparty/baseuri.js
  /*!
   * OpenUI5
   * (c) Copyright 2009-2019 SAP SE or an SAP affiliate company.
   * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
   */
  
  /*global Node, window */
  /*
   * A polyfill for document.baseURI (mainly targeting IE11).
   *
   * Implemented as a property getter to also support dynamically created &lt;base&gt; tags.
   */
  if ( !('baseURI' in Node.prototype) ) {
  	Object.defineProperty(Node.prototype, 'baseURI', {
  		get: function() {
  			var doc = this.ownerDocument || this, // a Document node returns ownerDocument null
  				// look for first base tag with an href attribute
  				// (https://html.spec.whatwg.org/multipage/urls-and-fetching.html#document-base-url )
  				baseOrLoc = doc.querySelector("base[href]") || window.location;
  			return baseOrLoc.href;
  		},
  		configurable: true
  	});
  }
  //@ui5-bundle-raw-include sap/ui/thirdparty/es6-promise.js
  /*!
   * @overview es6-promise - a tiny implementation of Promises/A+.
   * @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
   * @license   Licensed under MIT license
   *            See https://raw.githubusercontent.com/stefanpenner/es6-promise/master/LICENSE
   * @version   v4.2.4+314e4831
    */
  // Note: despite its file name, this is the es6-promise-auto.js variant of es6-promise.
  
  (function (global, factory) {
  	typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
  	// ##### BEGIN: MODIFIED BY SAP
  	// provide an id during registration and always register to global
  	// Original lines:
  	// typeof define === 'function' && define.amd ? define(factory) :
  	// (global.ES6Promise = factory());
  	// Modified lines:
  	typeof define === 'function' && define.amd ? define('sap/ui/thirdparty/es6-promise', factory) : null;
  	global.ES6Promise = factory();
  	// ##### END: MODIFIED BY SAP
  }(this, (function () { 'use strict';
  
  function objectOrFunction(x) {
    var type = typeof x;
    return x !== null && (type === 'object' || type === 'function');
  }
  
  function isFunction(x) {
    return typeof x === 'function';
  }
  
  
  
  var _isArray = void 0;
  if (Array.isArray) {
    _isArray = Array.isArray;
  } else {
    _isArray = function (x) {
      return Object.prototype.toString.call(x) === '[object Array]';
    };
  }
  
  var isArray = _isArray;
  
  var len = 0;
  var vertxNext = void 0;
  var customSchedulerFn = void 0;
  
  var asap = function asap(callback, arg) {
    queue[len] = callback;
    queue[len + 1] = arg;
    len += 2;
    if (len === 2) {
      // If len is 2, that means that we need to schedule an async flush.
      // If additional callbacks are queued before the queue is flushed, they
      // will be processed by this flush that we are scheduling.
      if (customSchedulerFn) {
        customSchedulerFn(flush);
      } else {
        scheduleFlush();
      }
    }
  };
  
  function setScheduler(scheduleFn) {
    customSchedulerFn = scheduleFn;
  }
  
  function setAsap(asapFn) {
    asap = asapFn;
  }
  
  var browserWindow = typeof window !== 'undefined' ? window : undefined;
  var browserGlobal = browserWindow || {};
  var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
  var isNode = typeof self === 'undefined' && typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
  
  // test for web worker but not in IE10
  var isWorker = typeof Uint8ClampedArray !== 'undefined' && typeof importScripts !== 'undefined' && typeof MessageChannel !== 'undefined';
  
  // node
  function useNextTick() {
    // node version 0.10.x displays a deprecation warning when nextTick is used recursively
    // see https://github.com/cujojs/when/issues/410 for details
    return function () {
      return process.nextTick(flush);
    };
  }
  
  // vertx
  function useVertxTimer() {
    if (typeof vertxNext !== 'undefined') {
      return function () {
        vertxNext(flush);
      };
    }
  
    return useSetTimeout();
  }
  
  function useMutationObserver() {
    var iterations = 0;
    var observer = new BrowserMutationObserver(flush);
    var node = document.createTextNode('');
    observer.observe(node, { characterData: true });
  
    return function () {
      node.data = iterations = ++iterations % 2;
    };
  }
  
  // web worker
  function useMessageChannel() {
    var channel = new MessageChannel();
    channel.port1.onmessage = flush;
    return function () {
      return channel.port2.postMessage(0);
    };
  }
  
  function useSetTimeout() {
    // Store setTimeout reference so es6-promise will be unaffected by
    // other code modifying setTimeout (like sinon.useFakeTimers())
    var globalSetTimeout = setTimeout;
    return function () {
      return globalSetTimeout(flush, 1);
    };
  }
  
  var queue = new Array(1000);
  function flush() {
    for (var i = 0; i < len; i += 2) {
      var callback = queue[i];
      var arg = queue[i + 1];
  
      callback(arg);
  
      queue[i] = undefined;
      queue[i + 1] = undefined;
    }
  
    len = 0;
  }
  
  function attemptVertx() {
    try {
      var vertx = Function('return this')().require('vertx');
      vertxNext = vertx.runOnLoop || vertx.runOnContext;
      return useVertxTimer();
    } catch (e) {
      return useSetTimeout();
    }
  }
  
  var scheduleFlush = void 0;
  // Decide what async method to use to triggering processing of queued callbacks:
  if (isNode) {
    scheduleFlush = useNextTick();
  } else if (BrowserMutationObserver) {
    scheduleFlush = useMutationObserver();
  } else if (isWorker) {
    scheduleFlush = useMessageChannel();
  } else if (browserWindow === undefined && typeof require === 'function') {
    scheduleFlush = attemptVertx();
  } else {
    scheduleFlush = useSetTimeout();
  }
  
  function then(onFulfillment, onRejection) {
    var parent = this;
  
    var child = new this.constructor(noop);
  
    if (child[PROMISE_ID] === undefined) {
      makePromise(child);
    }
  
    var _state = parent._state;
  
  
    if (_state) {
      var callback = arguments[_state - 1];
      asap(function () {
        return invokeCallback(_state, child, callback, parent._result);
      });
    } else {
      subscribe(parent, child, onFulfillment, onRejection);
    }
  
    return child;
  }
  
  /**
    `Promise.resolve` returns a promise that will become resolved with the
    passed `value`. It is shorthand for the following:
  
    ```javascript
    let promise = new Promise(function(resolve, reject){
      resolve(1);
    });
  
    promise.then(function(value){
      // value === 1
    });
    ```
  
    Instead of writing the above, your code now simply becomes the following:
  
    ```javascript
    let promise = Promise.resolve(1);
  
    promise.then(function(value){
      // value === 1
    });
    ```
  
    @method resolve
    @static
    @param {Any} value value that the returned promise will be resolved with
    Useful for tooling.
    @return {Promise} a promise that will become fulfilled with the given
    `value`
  */
  function resolve$1(object) {
    /*jshint validthis:true */
    var Constructor = this;
  
    if (object && typeof object === 'object' && object.constructor === Constructor) {
      return object;
    }
  
    var promise = new Constructor(noop);
    resolve(promise, object);
    return promise;
  }
  
  var PROMISE_ID = Math.random().toString(36).substring(2);
  
  function noop() {}
  
  var PENDING = void 0;
  var FULFILLED = 1;
  var REJECTED = 2;
  
  var TRY_CATCH_ERROR = { error: null };
  
  function selfFulfillment() {
    return new TypeError("You cannot resolve a promise with itself");
  }
  
  function cannotReturnOwn() {
    return new TypeError('A promises callback cannot return that same promise.');
  }
  
  function getThen(promise) {
    try {
      return promise.then;
    } catch (error) {
      TRY_CATCH_ERROR.error = error;
      return TRY_CATCH_ERROR;
    }
  }
  
  function tryThen(then$$1, value, fulfillmentHandler, rejectionHandler) {
    try {
      then$$1.call(value, fulfillmentHandler, rejectionHandler);
    } catch (e) {
      return e;
    }
  }
  
  function handleForeignThenable(promise, thenable, then$$1) {
    asap(function (promise) {
      var sealed = false;
      var error = tryThen(then$$1, thenable, function (value) {
        if (sealed) {
          return;
        }
        sealed = true;
        if (thenable !== value) {
          resolve(promise, value);
        } else {
          fulfill(promise, value);
        }
      }, function (reason) {
        if (sealed) {
          return;
        }
        sealed = true;
  
        reject(promise, reason);
      }, 'Settle: ' + (promise._label || ' unknown promise'));
  
      if (!sealed && error) {
        sealed = true;
        reject(promise, error);
      }
    }, promise);
  }
  
  function handleOwnThenable(promise, thenable) {
    if (thenable._state === FULFILLED) {
      fulfill(promise, thenable._result);
    } else if (thenable._state === REJECTED) {
      reject(promise, thenable._result);
    } else {
      subscribe(thenable, undefined, function (value) {
        return resolve(promise, value);
      }, function (reason) {
        return reject(promise, reason);
      });
    }
  }
  
  function handleMaybeThenable(promise, maybeThenable, then$$1) {
    if (maybeThenable.constructor === promise.constructor && then$$1 === then && maybeThenable.constructor.resolve === resolve$1) {
      handleOwnThenable(promise, maybeThenable);
    } else {
      if (then$$1 === TRY_CATCH_ERROR) {
        reject(promise, TRY_CATCH_ERROR.error);
        TRY_CATCH_ERROR.error = null;
      } else if (then$$1 === undefined) {
        fulfill(promise, maybeThenable);
      } else if (isFunction(then$$1)) {
        handleForeignThenable(promise, maybeThenable, then$$1);
      } else {
        fulfill(promise, maybeThenable);
      }
    }
  }
  
  function resolve(promise, value) {
    if (promise === value) {
      reject(promise, selfFulfillment());
    } else if (objectOrFunction(value)) {
      handleMaybeThenable(promise, value, getThen(value));
    } else {
      fulfill(promise, value);
    }
  }
  
  function publishRejection(promise) {
    if (promise._onerror) {
      promise._onerror(promise._result);
    }
  
    publish(promise);
  }
  
  function fulfill(promise, value) {
    if (promise._state !== PENDING) {
      return;
    }
  
    promise._result = value;
    promise._state = FULFILLED;
  
    if (promise._subscribers.length !== 0) {
      asap(publish, promise);
    }
  }
  
  function reject(promise, reason) {
    if (promise._state !== PENDING) {
      return;
    }
    promise._state = REJECTED;
    promise._result = reason;
  
    asap(publishRejection, promise);
  }
  
  function subscribe(parent, child, onFulfillment, onRejection) {
    var _subscribers = parent._subscribers;
    var length = _subscribers.length;
  
  
    parent._onerror = null;
  
    _subscribers[length] = child;
    _subscribers[length + FULFILLED] = onFulfillment;
    _subscribers[length + REJECTED] = onRejection;
  
    if (length === 0 && parent._state) {
      asap(publish, parent);
    }
  }
  
  function publish(promise) {
    var subscribers = promise._subscribers;
    var settled = promise._state;
  
    if (subscribers.length === 0) {
      return;
    }
  
    var child = void 0,
        callback = void 0,
        detail = promise._result;
  
    for (var i = 0; i < subscribers.length; i += 3) {
      child = subscribers[i];
      callback = subscribers[i + settled];
  
      if (child) {
        invokeCallback(settled, child, callback, detail);
      } else {
        callback(detail);
      }
    }
  
    promise._subscribers.length = 0;
  }
  
  function tryCatch(callback, detail) {
    try {
      return callback(detail);
    } catch (e) {
      TRY_CATCH_ERROR.error = e;
      return TRY_CATCH_ERROR;
    }
  }
  
  function invokeCallback(settled, promise, callback, detail) {
    var hasCallback = isFunction(callback),
        value = void 0,
        error = void 0,
        succeeded = void 0,
        failed = void 0;
  
    if (hasCallback) {
      value = tryCatch(callback, detail);
  
      if (value === TRY_CATCH_ERROR) {
        failed = true;
        error = value.error;
        value.error = null;
      } else {
        succeeded = true;
      }
  
      if (promise === value) {
        reject(promise, cannotReturnOwn());
        return;
      }
    } else {
      value = detail;
      succeeded = true;
    }
  
    if (promise._state !== PENDING) {
      // noop
    } else if (hasCallback && succeeded) {
      resolve(promise, value);
    } else if (failed) {
      reject(promise, error);
    } else if (settled === FULFILLED) {
      fulfill(promise, value);
    } else if (settled === REJECTED) {
      reject(promise, value);
    }
  }
  
  function initializePromise(promise, resolver) {
    try {
      resolver(function resolvePromise(value) {
        resolve(promise, value);
      }, function rejectPromise(reason) {
        reject(promise, reason);
      });
    } catch (e) {
      reject(promise, e);
    }
  }
  
  var id = 0;
  function nextId() {
    return id++;
  }
  
  function makePromise(promise) {
    promise[PROMISE_ID] = id++;
    promise._state = undefined;
    promise._result = undefined;
    promise._subscribers = [];
  }
  
  function validationError() {
    return new Error('Array Methods must be provided an Array');
  }
  
  var Enumerator = function () {
    function Enumerator(Constructor, input) {
      this._instanceConstructor = Constructor;
      this.promise = new Constructor(noop);
  
      if (!this.promise[PROMISE_ID]) {
        makePromise(this.promise);
      }
  
      if (isArray(input)) {
        this.length = input.length;
        this._remaining = input.length;
  
        this._result = new Array(this.length);
  
        if (this.length === 0) {
          fulfill(this.promise, this._result);
        } else {
          this.length = this.length || 0;
          this._enumerate(input);
          if (this._remaining === 0) {
            fulfill(this.promise, this._result);
          }
        }
      } else {
        reject(this.promise, validationError());
      }
    }
  
    Enumerator.prototype._enumerate = function _enumerate(input) {
      for (var i = 0; this._state === PENDING && i < input.length; i++) {
        this._eachEntry(input[i], i);
      }
    };
  
    Enumerator.prototype._eachEntry = function _eachEntry(entry, i) {
      var c = this._instanceConstructor;
      var resolve$$1 = c.resolve;
  
  
      if (resolve$$1 === resolve$1) {
        var _then = getThen(entry);
  
        if (_then === then && entry._state !== PENDING) {
          this._settledAt(entry._state, i, entry._result);
        } else if (typeof _then !== 'function') {
          this._remaining--;
          this._result[i] = entry;
        } else if (c === Promise$2) {
          var promise = new c(noop);
          handleMaybeThenable(promise, entry, _then);
          this._willSettleAt(promise, i);
        } else {
          this._willSettleAt(new c(function (resolve$$1) {
            return resolve$$1(entry);
          }), i);
        }
      } else {
        // ##### BEGIN: MODIFIED BY SAP
        // Original Line:
        // this._willSettleAt(resolve$$1(entry), i);
        this._willSettleAt(c.resolve(entry), i);
        // ##### END: MODIFIED BY SAP
      }
    };
  
    Enumerator.prototype._settledAt = function _settledAt(state, i, value) {
      var promise = this.promise;
  
  
      if (promise._state === PENDING) {
        this._remaining--;
  
        if (state === REJECTED) {
          reject(promise, value);
        } else {
          this._result[i] = value;
        }
      }
  
      if (this._remaining === 0) {
        fulfill(promise, this._result);
      }
    };
  
    Enumerator.prototype._willSettleAt = function _willSettleAt(promise, i) {
      var enumerator = this;
  
      subscribe(promise, undefined, function (value) {
        return enumerator._settledAt(FULFILLED, i, value);
      }, function (reason) {
        return enumerator._settledAt(REJECTED, i, reason);
      });
    };
  
    return Enumerator;
  }();
  
  /**
    `Promise.all` accepts an array of promises, and returns a new promise which
    is fulfilled with an array of fulfillment values for the passed promises, or
    rejected with the reason of the first passed promise to be rejected. It casts all
    elements of the passed iterable to promises as it runs this algorithm.
  
    Example:
  
    ```javascript
    let promise1 = resolve(1);
    let promise2 = resolve(2);
    let promise3 = resolve(3);
    let promises = [ promise1, promise2, promise3 ];
  
    Promise.all(promises).then(function(array){
      // The array here would be [ 1, 2, 3 ];
    });
    ```
  
    If any of the `promises` given to `all` are rejected, the first promise
    that is rejected will be given as an argument to the returned promises's
    rejection handler. For example:
  
    Example:
  
    ```javascript
    let promise1 = resolve(1);
    let promise2 = reject(new Error("2"));
    let promise3 = reject(new Error("3"));
    let promises = [ promise1, promise2, promise3 ];
  
    Promise.all(promises).then(function(array){
      // Code here never runs because there are rejected promises!
    }, function(error) {
      // error.message === "2"
    });
    ```
  
    @method all
    @static
    @param {Array} entries array of promises
    @param {String} label optional string for labeling the promise.
    Useful for tooling.
    @return {Promise} promise that is fulfilled when all `promises` have been
    fulfilled, or rejected if any of them become rejected.
    @static
  */
  function all(entries) {
    return new Enumerator(this, entries).promise;
  }
  
  /**
    `Promise.race` returns a new promise which is settled in the same way as the
    first passed promise to settle.
  
    Example:
  
    ```javascript
    let promise1 = new Promise(function(resolve, reject){
      setTimeout(function(){
        resolve('promise 1');
      }, 200);
    });
  
    let promise2 = new Promise(function(resolve, reject){
      setTimeout(function(){
        resolve('promise 2');
      }, 100);
    });
  
    Promise.race([promise1, promise2]).then(function(result){
      // result === 'promise 2' because it was resolved before promise1
      // was resolved.
    });
    ```
  
    `Promise.race` is deterministic in that only the state of the first
    settled promise matters. For example, even if other promises given to the
    `promises` array argument are resolved, but the first settled promise has
    become rejected before the other promises became fulfilled, the returned
    promise will become rejected:
  
    ```javascript
    let promise1 = new Promise(function(resolve, reject){
      setTimeout(function(){
        resolve('promise 1');
      }, 200);
    });
  
    let promise2 = new Promise(function(resolve, reject){
      setTimeout(function(){
        reject(new Error('promise 2'));
      }, 100);
    });
  
    Promise.race([promise1, promise2]).then(function(result){
      // Code here never runs
    }, function(reason){
      // reason.message === 'promise 2' because promise 2 became rejected before
      // promise 1 became fulfilled
    });
    ```
  
    An example real-world use case is implementing timeouts:
  
    ```javascript
    Promise.race([ajax('foo.json'), timeout(5000)])
    ```
  
    @method race
    @static
    @param {Array} promises array of promises to observe
    Useful for tooling.
    @return {Promise} a promise which settles in the same way as the first passed
    promise to settle.
  */
  function race(entries) {
    /*jshint validthis:true */
    var Constructor = this;
  
    if (!isArray(entries)) {
      return new Constructor(function (_, reject) {
        return reject(new TypeError('You must pass an array to race.'));
      });
    } else {
      return new Constructor(function (resolve, reject) {
        var length = entries.length;
        for (var i = 0; i < length; i++) {
          Constructor.resolve(entries[i]).then(resolve, reject);
        }
      });
    }
  }
  
  /**
    `Promise.reject` returns a promise rejected with the passed `reason`.
    It is shorthand for the following:
  
    ```javascript
    let promise = new Promise(function(resolve, reject){
      reject(new Error('WHOOPS'));
    });
  
    promise.then(function(value){
      // Code here doesn't run because the promise is rejected!
    }, function(reason){
      // reason.message === 'WHOOPS'
    });
    ```
  
    Instead of writing the above, your code now simply becomes the following:
  
    ```javascript
    let promise = Promise.reject(new Error('WHOOPS'));
  
    promise.then(function(value){
      // Code here doesn't run because the promise is rejected!
    }, function(reason){
      // reason.message === 'WHOOPS'
    });
    ```
  
    @method reject
    @static
    @param {Any} reason value that the returned promise will be rejected with.
    Useful for tooling.
    @return {Promise} a promise rejected with the given `reason`.
  */
  function reject$1(reason) {
    /*jshint validthis:true */
    var Constructor = this;
    var promise = new Constructor(noop);
    reject(promise, reason);
    return promise;
  }
  
  function needsResolver() {
    throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
  }
  
  function needsNew() {
    throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
  }
  
  /**
    Promise objects represent the eventual result of an asynchronous operation. The
    primary way of interacting with a promise is through its `then` method, which
    registers callbacks to receive either a promise's eventual value or the reason
    why the promise cannot be fulfilled.
  
    Terminology
    -----------
  
    - `promise` is an object or function with a `then` method whose behavior conforms to this specification.
    - `thenable` is an object or function that defines a `then` method.
    - `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
    - `exception` is a value that is thrown using the throw statement.
    - `reason` is a value that indicates why a promise was rejected.
    - `settled` the final resting state of a promise, fulfilled or rejected.
  
    A promise can be in one of three states: pending, fulfilled, or rejected.
  
    Promises that are fulfilled have a fulfillment value and are in the fulfilled
    state.  Promises that are rejected have a rejection reason and are in the
    rejected state.  A fulfillment value is never a thenable.
  
    Promises can also be said to *resolve* a value.  If this value is also a
    promise, then the original promise's settled state will match the value's
    settled state.  So a promise that *resolves* a promise that rejects will
    itself reject, and a promise that *resolves* a promise that fulfills will
    itself fulfill.
  
  
    Basic Usage:
    ------------
  
    ```js
    let promise = new Promise(function(resolve, reject) {
      // on success
      resolve(value);
  
      // on failure
      reject(reason);
    });
  
    promise.then(function(value) {
      // on fulfillment
    }, function(reason) {
      // on rejection
    });
    ```
  
    Advanced Usage:
    ---------------
  
    Promises shine when abstracting away asynchronous interactions such as
    `XMLHttpRequest`s.
  
    ```js
    function getJSON(url) {
      return new Promise(function(resolve, reject){
        let xhr = new XMLHttpRequest();
  
        xhr.open('GET', url);
        xhr.onreadystatechange = handler;
        xhr.responseType = 'json';
        xhr.setRequestHeader('Accept', 'application/json');
        xhr.send();
  
        function handler() {
          if (this.readyState === this.DONE) {
            if (this.status === 200) {
              resolve(this.response);
            } else {
              reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
            }
          }
        };
      });
    }
  
    getJSON('/posts.json').then(function(json) {
      // on fulfillment
    }, function(reason) {
      // on rejection
    });
    ```
  
    Unlike callbacks, promises are great composable primitives.
  
    ```js
    Promise.all([
      getJSON('/posts'),
      getJSON('/comments')
    ]).then(function(values){
      values[0] // => postsJSON
      values[1] // => commentsJSON
  
      return values;
    });
    ```
  
    @class Promise
    @param {Function} resolver
    Useful for tooling.
    @constructor
  */
  
  var Promise$2 = function () {
    function Promise(resolver) {
      this[PROMISE_ID] = nextId();
      this._result = this._state = undefined;
      this._subscribers = [];
  
      if (noop !== resolver) {
        typeof resolver !== 'function' && needsResolver();
        this instanceof Promise ? initializePromise(this, resolver) : needsNew();
      }
    }
  
    /**
    The primary way of interacting with a promise is through its `then` method,
    which registers callbacks to receive either a promise's eventual value or the
    reason why the promise cannot be fulfilled.
     ```js
    findUser().then(function(user){
      // user is available
    }, function(reason){
      // user is unavailable, and you are given the reason why
    });
    ```
     Chaining
    --------
     The return value of `then` is itself a promise.  This second, 'downstream'
    promise is resolved with the return value of the first promise's fulfillment
    or rejection handler, or rejected if the handler throws an exception.
     ```js
    findUser().then(function (user) {
      return user.name;
    }, function (reason) {
      return 'default name';
    }).then(function (userName) {
      // If `findUser` fulfilled, `userName` will be the user's name, otherwise it
      // will be `'default name'`
    });
     findUser().then(function (user) {
      throw new Error('Found user, but still unhappy');
    }, function (reason) {
      throw new Error('`findUser` rejected and we're unhappy');
    }).then(function (value) {
      // never reached
    }, function (reason) {
      // if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
      // If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
    });
    ```
    If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
     ```js
    findUser().then(function (user) {
      throw new PedagogicalException('Upstream error');
    }).then(function (value) {
      // never reached
    }).then(function (value) {
      // never reached
    }, function (reason) {
      // The `PedgagocialException` is propagated all the way down to here
    });
    ```
     Assimilation
    ------------
     Sometimes the value you want to propagate to a downstream promise can only be
    retrieved asynchronously. This can be achieved by returning a promise in the
    fulfillment or rejection handler. The downstream promise will then be pending
    until the returned promise is settled. This is called *assimilation*.
     ```js
    findUser().then(function (user) {
      return findCommentsByAuthor(user);
    }).then(function (comments) {
      // The user's comments are now available
    });
    ```
     If the assimliated promise rejects, then the downstream promise will also reject.
     ```js
    findUser().then(function (user) {
      return findCommentsByAuthor(user);
    }).then(function (comments) {
      // If `findCommentsByAuthor` fulfills, we'll have the value here
    }, function (reason) {
      // If `findCommentsByAuthor` rejects, we'll have the reason here
    });
    ```
     Simple Example
    --------------
     Synchronous Example
     ```javascript
    let result;
     try {
      result = findResult();
      // success
    } catch(reason) {
      // failure
    }
    ```
     Errback Example
     ```js
    findResult(function(result, err){
      if (err) {
        // failure
      } else {
        // success
      }
    });
    ```
     Promise Example;
     ```javascript
    findResult().then(function(result){
      // success
    }, function(reason){
      // failure
    });
    ```
     Advanced Example
    --------------
     Synchronous Example
     ```javascript
    let author, books;
     try {
      author = findAuthor();
      books  = findBooksByAuthor(author);
      // success
    } catch(reason) {
      // failure
    }
    ```
     Errback Example
     ```js
     function foundBooks(books) {
     }
     function failure(reason) {
     }
     findAuthor(function(author, err){
      if (err) {
        failure(err);
        // failure
      } else {
        try {
          findBoooksByAuthor(author, function(books, err) {
            if (err) {
              failure(err);
            } else {
              try {
                foundBooks(books);
              } catch(reason) {
                failure(reason);
              }
            }
          });
        } catch(error) {
          failure(err);
        }
        // success
      }
    });
    ```
     Promise Example;
     ```javascript
    findAuthor().
      then(findBooksByAuthor).
      then(function(books){
        // found books
    }).catch(function(reason){
      // something went wrong
    });
    ```
     @method then
    @param {Function} onFulfilled
    @param {Function} onRejected
    Useful for tooling.
    @return {Promise}
    */
  
    /**
    `catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
    as the catch block of a try/catch statement.
    ```js
    function findAuthor(){
    throw new Error('couldn't find that author');
    }
    // synchronous
    try {
    findAuthor();
    } catch(reason) {
    // something went wrong
    }
    // async with promises
    findAuthor().catch(function(reason){
    // something went wrong
    });
    ```
    @method catch
    @param {Function} onRejection
    Useful for tooling.
    @return {Promise}
    */
  
  
    Promise.prototype.catch = function _catch(onRejection) {
      return this.then(null, onRejection);
    };
  
    /**
      `finally` will be invoked regardless of the promise's fate just as native
      try/catch/finally behaves
  
      Synchronous example:
  
      ```js
      findAuthor() {
        if (Math.random() > 0.5) {
          throw new Error();
        }
        return new Author();
      }
  
      try {
        return findAuthor(); // succeed or fail
      } catch(error) {
        return findOtherAuther();
      } finally {
        // always runs
        // doesn't affect the return value
      }
      ```
  
      Asynchronous example:
  
      ```js
      findAuthor().catch(function(reason){
        return findOtherAuther();
      }).finally(function(){
        // author was either found, or not
      });
      ```
  
      @method finally
      @param {Function} callback
      @return {Promise}
    */
  
  
    Promise.prototype.finally = function _finally(callback) {
      var promise = this;
      var constructor = promise.constructor;
  
      // ##### BEGIN: MODIFIED BY SAP
      // According to the spec, 'callback' is optional, it might not be callable
      // see https://tc39.github.io/proposal-promise-finally/
      if ( isFunction(callback) ) {
      // ##### END: MODIFIED BY SAP
  
        return promise.then(function (value) {
          return constructor.resolve(callback()).then(function () {
            return value;
          });
        }, function (reason) {
          return constructor.resolve(callback()).then(function () {
            throw reason;
          });
        });
  
      // ##### BEGIN: MODIFIED BY SAP
      }
  
  	return promise.then(callback, callback);
      // ##### END: MODIFIED BY SAP
  
    };
  
    return Promise;
  }();
  
  Promise$2.prototype.then = then;
  Promise$2.all = all;
  Promise$2.race = race;
  Promise$2.resolve = resolve$1;
  Promise$2.reject = reject$1;
  Promise$2._setScheduler = setScheduler;
  Promise$2._setAsap = setAsap;
  Promise$2._asap = asap;
  
  /*global self*/
  function polyfill() {
    var local = void 0;
  
    if (typeof global !== 'undefined') {
      local = global;
    } else if (typeof self !== 'undefined') {
      local = self;
    } else {
      try {
        local = Function('return this')();
      } catch (e) {
        throw new Error('polyfill failed because global object is unavailable in this environment');
      }
    }
  
    var P = local.Promise;
  
    if (P) {
      var promiseToString = null;
      try {
        promiseToString = Object.prototype.toString.call(P.resolve());
      } catch (e) {
        // silently ignored
      }
  
      if (promiseToString === '[object Promise]' && !P.cast) {
        // ##### BEGIN: MODIFIED BY SAP
        // apply polyfill for finally when missing
        if ( typeof P.prototype.finally !== "function" ) {
          P.prototype.finally = Promise$2.prototype.finally;
        }
        // ##### END: MODIFIED BY SAP
        return;
      }
    }
  
    local.Promise = Promise$2;
  }
  
  // Strange compat..
  Promise$2.polyfill = polyfill;
  Promise$2.Promise = Promise$2;
  
  Promise$2.polyfill();
  
  return Promise$2;
  
  })));
  //@ui5-bundle-raw-include sap/ui/thirdparty/es6-shim-nopromise.js
  /*!
   * https://github.com/paulmillr/es6-shim
   * @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)
   *   and contributors,  MIT License
   * es6-shim: v0.35.4
   * see https://github.com/paulmillr/es6-shim/blob/0.35.3/LICENSE
   * Details and documentation:
   * https://github.com/paulmillr/es6-shim/
   */
  
  // UMD (Universal Module Definition)
  // see https://github.com/umdjs/umd/blob/master/returnExports.js
  (function (root, factory) {
    /*global define, module, exports */
    if (typeof define === 'function' && define.amd) {
      // ##### BEGIN: MODIFIED BY SAP
      // Original lines:
      // AMD. Register as an anonymous module.
      //define(factory);
      // Modified lines:
      var exports = factory(); // immediately execute to configure global
      define('sap/ui/thirdparty/es6-shim-nopromise', exports);
      // ##### END: MODIFIED BY SAP
    } else if (typeof exports === 'object') {
      // Node. Does not work with strict CommonJS, but
      // only CommonJS-like environments that support module.exports,
      // like Node.
      module.exports = factory();
    } else {
      // Browser globals (root is window)
      root.returnExports = factory();
    }
  }(this, function () {
    'use strict';
  
    // ##### BEGIN: MODIFIED BY SAP
    // moved up due to initial usage
    var getGlobal = function () {
      /* global self, window, global */
      // the only reliable means to get the global object is
      // `Function('return this')()`
      // However, this causes CSP violations in Chrome apps.
      if (typeof self !== 'undefined') { return self; }
      if (typeof window !== 'undefined') { return window; }
      if (typeof global !== 'undefined') { return global; }
      throw new Error('unable to locate global object');
    };
  
    // do not execute for modern browsers
    if (!/(trident)\/[\w.]+;.*rv:([\w.]+)/i.test(window.navigator.userAgent)) {
      return getGlobal();
    }
    // ##### END: MODIFIED BY SAP
  
    var _apply = Function.call.bind(Function.apply);
    var _call = Function.call.bind(Function.call);
    var isArray = Array.isArray;
    var keys = Object.keys;
  
    var not = function notThunker(func) {
      return function notThunk() {
        return !_apply(func, this, arguments);
      };
    };
    var throwsError = function (func) {
      try {
        func();
        return false;
      } catch (e) {
        return true;
      }
    };
    var valueOrFalseIfThrows = function valueOrFalseIfThrows(func) {
      try {
        return func();
      } catch (e) {
        return false;
      }
    };
  
    var isCallableWithoutNew = not(throwsError);
    var arePropertyDescriptorsSupported = function () {
      // if Object.defineProperty exists but throws, it's IE 8
      return !throwsError(function () {
        return Object.defineProperty({}, 'x', { get: function () { } }); // eslint-disable-line getter-return
      });
    };
    var supportsDescriptors = !!Object.defineProperty && arePropertyDescriptorsSupported();
    var functionsHaveNames = (function foo() {}).name === 'foo'; // eslint-disable-line no-extra-parens
  
    var _forEach = Function.call.bind(Array.prototype.forEach);
    var _reduce = Function.call.bind(Array.prototype.reduce);
    var _filter = Function.call.bind(Array.prototype.filter);
    var _some = Function.call.bind(Array.prototype.some);
  
    var defineProperty = function (object, name, value, force) {
      if (!force && name in object) { return; }
      if (supportsDescriptors) {
        Object.defineProperty(object, name, {
          configurable: true,
          enumerable: false,
          writable: true,
          value: value
        });
      } else {
        object[name] = value;
      }
    };
  
    // Define configurable, writable and non-enumerable props
    // if they don’t exist.
    var defineProperties = function (object, map, forceOverride) {
      _forEach(keys(map), function (name) {
        var method = map[name];
        defineProperty(object, name, method, !!forceOverride);
      });
    };
  
    var _toString = Function.call.bind(Object.prototype.toString);
    var isCallable = typeof /abc/ === 'function' ? function IsCallableSlow(x) {
      // Some old browsers (IE, FF) say that typeof /abc/ === 'function'
      return typeof x === 'function' && _toString(x) === '[object Function]';
    } : function IsCallableFast(x) { return typeof x === 'function'; };
  
    var Value = {
      getter: function (object, name, getter) {
        if (!supportsDescriptors) {
          throw new TypeError('getters require true ES5 support');
        }
        Object.defineProperty(object, name, {
          configurable: true,
          enumerable: false,
          get: getter
        });
      },
      proxy: function (originalObject, key, targetObject) {
        if (!supportsDescriptors) {
          throw new TypeError('getters require true ES5 support');
        }
        var originalDescriptor = Object.getOwnPropertyDescriptor(originalObject, key);
        Object.defineProperty(targetObject, key, {
          configurable: originalDescriptor.configurable,
          enumerable: originalDescriptor.enumerable,
          get: function getKey() { return originalObject[key]; },
          set: function setKey(value) { originalObject[key] = value; }
        });
      },
      redefine: function (object, property, newValue) {
        if (supportsDescriptors) {
          var descriptor = Object.getOwnPropertyDescriptor(object, property);
          descriptor.value = newValue;
          Object.defineProperty(object, property, descriptor);
        } else {
          object[property] = newValue;
        }
      },
      defineByDescriptor: function (object, property, descriptor) {
        if (supportsDescriptors) {
          Object.defineProperty(object, property, descriptor);
        } else if ('value' in descriptor) {
          object[property] = descriptor.value;
        }
      },
      preserveToString: function (target, source) {
        if (source && isCallable(source.toString)) {
          defineProperty(target, 'toString', source.toString.bind(source), true);
        }
      }
    };
  
    // Simple shim for Object.create on ES3 browsers
    // (unlike real shim, no attempt to support `prototype === null`)
    var create = Object.create || function (prototype, properties) {
      var Prototype = function Prototype() {};
      Prototype.prototype = prototype;
      var object = new Prototype();
      if (typeof properties !== 'undefined') {
        keys(properties).forEach(function (key) {
          Value.defineByDescriptor(object, key, properties[key]);
        });
      }
      return object;
    };
  
    var supportsSubclassing = function (C, f) {
      if (!Object.setPrototypeOf) { return false; /* skip test on IE < 11 */ }
      return valueOrFalseIfThrows(function () {
        var Sub = function Subclass(arg) {
          var o = new C(arg);
          Object.setPrototypeOf(o, Subclass.prototype);
          return o;
        };
        Object.setPrototypeOf(Sub, C);
        Sub.prototype = create(C.prototype, {
          constructor: { value: Sub }
        });
        return f(Sub);
      });
    };
  
    var globals = getGlobal();
    var globalIsFinite = globals.isFinite;
    var _indexOf = Function.call.bind(String.prototype.indexOf);
    var _arrayIndexOfApply = Function.apply.bind(Array.prototype.indexOf);
    var _concat = Function.call.bind(Array.prototype.concat);
    // var _sort = Function.call.bind(Array.prototype.sort);
    var _strSlice = Function.call.bind(String.prototype.slice);
    var _push = Function.call.bind(Array.prototype.push);
    var _pushApply = Function.apply.bind(Array.prototype.push);
    var _shift = Function.call.bind(Array.prototype.shift);
    var _max = Math.max;
    var _min = Math.min;
    var _floor = Math.floor;
    var _abs = Math.abs;
    var _exp = Math.exp;
    var _log = Math.log;
    var _sqrt = Math.sqrt;
    var _hasOwnProperty = Function.call.bind(Object.prototype.hasOwnProperty);
    var ArrayIterator; // make our implementation private
    var noop = function () {};
  
    var OrigMap = globals.Map;
    var origMapDelete = OrigMap && OrigMap.prototype['delete'];
    var origMapGet = OrigMap && OrigMap.prototype.get;
    var origMapHas = OrigMap && OrigMap.prototype.has;
    var origMapSet = OrigMap && OrigMap.prototype.set;
  
    var Symbol = globals.Symbol || {};
    var symbolSpecies = Symbol.species || '@@species';
  
    var numberIsNaN = Number.isNaN || function isNaN(value) {
      // NaN !== NaN, but they are identical.
      // NaNs are the only non-reflexive value, i.e., if x !== x,
      // then x is NaN.
      // isNaN is broken: it converts its argument to number, so
      // isNaN('foo') => true
      return value !== value;
    };
    var numberIsFinite = Number.isFinite || function isFinite(value) {
      return typeof value === 'number' && globalIsFinite(value);
    };
    var _sign = isCallable(Math.sign) ? Math.sign : function sign(value) {
      var number = Number(value);
      if (number === 0) { return number; }
      if (numberIsNaN(number)) { return number; }
      return number < 0 ? -1 : 1;
    };
    var _log1p = function log1p(value) {
      var x = Number(value);
      if (x < -1 || numberIsNaN(x)) { return NaN; }
      if (x === 0 || x === Infinity) { return x; }
      if (x === -1) { return -Infinity; }
  
      return (1 + x) - 1 === 0 ? x : x * (_log(1 + x) / ((1 + x) - 1));
    };
  
    // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js
    // can be replaced with require('is-arguments') if we ever use a build process instead
    var isStandardArguments = function isArguments(value) {
      return _toString(value) === '[object Arguments]';
    };
    var isLegacyArguments = function isArguments(value) {
      return value !== null &&
        typeof value === 'object' &&
        typeof value.length === 'number' &&
        value.length >= 0 &&
        _toString(value) !== '[object Array]' &&
        _toString(value.callee) === '[object Function]';
    };
    var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments;
  
    var Type = {
      primitive: function (x) { return x === null || (typeof x !== 'function' && typeof x !== 'object'); },
      string: function (x) { return _toString(x) === '[object String]'; },
      regex: function (x) { return _toString(x) === '[object RegExp]'; },
      symbol: function (x) {
        return typeof globals.Symbol === 'function' && typeof x === 'symbol';
      }
    };
  
    var overrideNative = function overrideNative(object, property, replacement) {
      var original = object[property];
      defineProperty(object, property, replacement, true);
      Value.preserveToString(object[property], original);
    };
  
    // eslint-disable-next-line no-restricted-properties
    var hasSymbols = typeof Symbol === 'function' && typeof Symbol['for'] === 'function' && Type.symbol(Symbol());
  
    // This is a private name in the es6 spec, equal to '[Symbol.iterator]'
    // we're going to use an arbitrary _-prefixed name to make our shims
    // work properly with each other, even though we don't have full Iterator
    // support.  That is, `Array.from(map.keys())` will work, but we don't
    // pretend to export a "real" Iterator interface.
    var $iterator$ = Type.symbol(Symbol.iterator) ? Symbol.iterator : '_es6-shim iterator_';
    // Firefox ships a partial implementation using the name @@iterator.
    // https://bugzilla.mozilla.org/show_bug.cgi?id=907077#c14
    // So use that name if we detect it.
    if (globals.Set && typeof new globals.Set()['@@iterator'] === 'function') {
      $iterator$ = '@@iterator';
    }
  
    // Reflect
    if (!globals.Reflect) {
      defineProperty(globals, 'Reflect', {}, true);
    }
    var Reflect = globals.Reflect;
  
    var $String = String;
  
    /* global document */
    var domAll = (typeof document === 'undefined' || !document) ? null : document.all;
    /* jshint eqnull:true */
    var isNullOrUndefined = domAll == null ? function isNullOrUndefined(x) {
      /* jshint eqnull:true */
      return x == null;
    } : function isNullOrUndefinedAndNotDocumentAll(x) {
      /* jshint eqnull:true */
      return x == null && x !== domAll;
    };
  
    var ES = {
      // http://www.ecma-international.org/ecma-262/6.0/#sec-call
      Call: function Call(F, V) {
        var args = arguments.length > 2 ? arguments[2] : [];
        if (!ES.IsCallable(F)) {
          throw new TypeError(F + ' is not a function');
        }
        return _apply(F, V, args);
      },
  
      RequireObjectCoercible: function (x, optMessage) {
        if (isNullOrUndefined(x)) {
          throw new TypeError(optMessage || 'Cannot call method on ' + x);
        }
        return x;
      },
  
      // This might miss the "(non-standard exotic and does not implement
      // [[Call]])" case from
      // http://www.ecma-international.org/ecma-262/6.0/#sec-typeof-operator-runtime-semantics-evaluation
      // but we can't find any evidence these objects exist in practice.
      // If we find some in the future, you could test `Object(x) === x`,
      // which is reliable according to
      // http://www.ecma-international.org/ecma-262/6.0/#sec-toobject
      // but is not well optimized by runtimes and creates an object
      // whenever it returns false, and thus is very slow.
      TypeIsObject: function (x) {
        if (x === void 0 || x === null || x === true || x === false) {
          return false;
        }
        return typeof x === 'function' || typeof x === 'object' || x === domAll;
      },
  
      ToObject: function (o, optMessage) {
        return Object(ES.RequireObjectCoercible(o, optMessage));
      },
  
      IsCallable: isCallable,
  
      IsConstructor: function (x) {
        // We can't tell callables from constructors in ES5
        return ES.IsCallable(x);
      },
  
      ToInt32: function (x) {
        return ES.ToNumber(x) >> 0;
      },
  
      ToUint32: function (x) {
        return ES.ToNumber(x) >>> 0;
      },
  
      ToNumber: function (value) {
        if (_toString(value) === '[object Symbol]') {
          throw new TypeError('Cannot convert a Symbol value to a number');
        }
        return +value;
      },
  
      ToInteger: function (value) {
        var number = ES.ToNumber(value);
        if (numberIsNaN(number)) { return 0; }
        if (number === 0 || !numberIsFinite(number)) { return number; }
        return (number > 0 ? 1 : -1) * _floor(_abs(number));
      },
  
      ToLength: function (value) {
        var len = ES.ToInteger(value);
        if (len <= 0) { return 0; } // includes converting -0 to +0
        if (len > Number.MAX_SAFE_INTEGER) { return Number.MAX_SAFE_INTEGER; }
        return len;
      },
  
      SameValue: function (a, b) {
        if (a === b) {
          // 0 === -0, but they are not identical.
          if (a === 0) { return 1 / a === 1 / b; }
          return true;
        }
        return numberIsNaN(a) && numberIsNaN(b);
      },
  
      SameValueZero: function (a, b) {
        // same as SameValue except for SameValueZero(+0, -0) == true
        return (a === b) || (numberIsNaN(a) && numberIsNaN(b));
      },
  
      IsIterable: function (o) {
        return ES.TypeIsObject(o) && (typeof o[$iterator$] !== 'undefined' || isArguments(o));
      },
  
      GetIterator: function (o) {
        if (isArguments(o)) {
          // special case support for `arguments`
          return new ArrayIterator(o, 'value');
        }
        var itFn = ES.GetMethod(o, $iterator$);
        if (!ES.IsCallable(itFn)) {
          // Better diagnostics if itFn is null or undefined
          throw new TypeError('value is not an iterable');
        }
        var it = ES.Call(itFn, o);
        if (!ES.TypeIsObject(it)) {
          throw new TypeError('bad iterator');
        }
        return it;
      },
  
      GetMethod: function (o, p) {
        var func = ES.ToObject(o)[p];
        if (isNullOrUndefined(func)) {
          return void 0;
        }
        if (!ES.IsCallable(func)) {
          throw new TypeError('Method not callable: ' + p);
        }
        return func;
      },
  
      IteratorComplete: function (iterResult) {
        return !!iterResult.done;
      },
  
      IteratorClose: function (iterator, completionIsThrow) {
        var returnMethod = ES.GetMethod(iterator, 'return');
        if (returnMethod === void 0) {
          return;
        }
        var innerResult, innerException;
        try {
          innerResult = ES.Call(returnMethod, iterator);
        } catch (e) {
          innerException = e;
        }
        if (completionIsThrow) {
          return;
        }
        if (innerException) {
          throw innerException;
        }
        if (!ES.TypeIsObject(innerResult)) {
          throw new TypeError("Iterator's return method returned a non-object.");
        }
      },
  
      IteratorNext: function (it) {
        var result = arguments.length > 1 ? it.next(arguments[1]) : it.next();
        if (!ES.TypeIsObject(result)) {
          throw new TypeError('bad iterator');
        }
        return result;
      },
  
      IteratorStep: function (it) {
        var result = ES.IteratorNext(it);
        var done = ES.IteratorComplete(result);
        return done ? false : result;
      },
  
      Construct: function (C, args, newTarget, isES6internal) {
        var target = typeof newTarget === 'undefined' ? C : newTarget;
  
        if (!isES6internal && Reflect.construct) {
          // Try to use Reflect.construct if available
          return Reflect.construct(C, args, target);
        }
        // OK, we have to fake it.  This will only work if the
        // C.[[ConstructorKind]] == "base" -- but that's the only
        // kind we can make in ES5 code anyway.
  
        // OrdinaryCreateFromConstructor(target, "%ObjectPrototype%")
        var proto = target.prototype;
        if (!ES.TypeIsObject(proto)) {
          proto = Object.prototype;
        }
        var obj = create(proto);
        // Call the constructor.
        var result = ES.Call(C, obj, args);
        return ES.TypeIsObject(result) ? result : obj;
      },
  
      SpeciesConstructor: function (O, defaultConstructor) {
        var C = O.constructor;
        if (C === void 0) {
          return defaultConstructor;
        }
        if (!ES.TypeIsObject(C)) {
          throw new TypeError('Bad constructor');
        }
        var S = C[symbolSpecies];
        if (isNullOrUndefined(S)) {
          return defaultConstructor;
        }
        if (!ES.IsConstructor(S)) {
          throw new TypeError('Bad @@species');
        }
        return S;
      },
  
      CreateHTML: function (string, tag, attribute, value) {
        var S = ES.ToString(string);
        var p1 = '<' + tag;
        if (attribute !== '') {
          var V = ES.ToString(value);
          var escapedV = V.replace(/"/g, '&quot;');
          p1 += ' ' + attribute + '="' + escapedV + '"';
        }
        var p2 = p1 + '>';
        var p3 = p2 + S;
        return p3 + '</' + tag + '>';
      },
  
      IsRegExp: function IsRegExp(argument) {
        if (!ES.TypeIsObject(argument)) {
          return false;
        }
        var isRegExp = argument[Symbol.match];
        if (typeof isRegExp !== 'undefined') {
          return !!isRegExp;
        }
        return Type.regex(argument);
      },
  
      ToString: function ToString(string) {
        return $String(string);
      }
    };
  
    // Well-known Symbol shims
    if (supportsDescriptors && hasSymbols) {
      var defineWellKnownSymbol = function defineWellKnownSymbol(name) {
        if (Type.symbol(Symbol[name])) {
          return Symbol[name];
        }
        // eslint-disable-next-line no-restricted-properties
        var sym = Symbol['for']('Symbol.' + name);
        Object.defineProperty(Symbol, name, {
          configurable: false,
          enumerable: false,
          writable: false,
          value: sym
        });
        return sym;
      };
      if (!Type.symbol(Symbol.search)) {
        var symbolSearch = defineWellKnownSymbol('search');
        var originalSearch = String.prototype.search;
        defineProperty(RegExp.prototype, symbolSearch, function search(string) {
          return ES.Call(originalSearch, string, [this]);
        });
        var searchShim = function search(regexp) {
          var O = ES.RequireObjectCoercible(this);
          if (!isNullOrUndefined(regexp)) {
            var searcher = ES.GetMethod(regexp, symbolSearch);
            if (typeof searcher !== 'undefined') {
              return ES.Call(searcher, regexp, [O]);
            }
          }
          return ES.Call(originalSearch, O, [ES.ToString(regexp)]);
        };
        overrideNative(String.prototype, 'search', searchShim);
      }
      if (!Type.symbol(Symbol.replace)) {
        var symbolReplace = defineWellKnownSymbol('replace');
        var originalReplace = String.prototype.replace;
        defineProperty(RegExp.prototype, symbolReplace, function replace(string, replaceValue) {
          return ES.Call(originalReplace, string, [this, replaceValue]);
        });
        var replaceShim = function replace(searchValue, replaceValue) {
          var O = ES.RequireObjectCoercible(this);
          if (!isNullOrUndefined(searchValue)) {
            var replacer = ES.GetMethod(searchValue, symbolReplace);
            if (typeof replacer !== 'undefined') {
              return ES.Call(replacer, searchValue, [O, replaceValue]);
            }
          }
          return ES.Call(originalReplace, O, [ES.ToString(searchValue), replaceValue]);
        };
        overrideNative(String.prototype, 'replace', replaceShim);
      }
      if (!Type.symbol(Symbol.split)) {
        var symbolSplit = defineWellKnownSymbol('split');
        var originalSplit = String.prototype.split;
        defineProperty(RegExp.prototype, symbolSplit, function split(string, limit) {
          return ES.Call(originalSplit, string, [this, limit]);
        });
        var splitShim = function split(separator, limit) {
          var O = ES.RequireObjectCoercible(this);
          if (!isNullOrUndefined(separator)) {
            var splitter = ES.GetMethod(separator, symbolSplit);
            if (typeof splitter !== 'undefined') {
              return ES.Call(splitter, separator, [O, limit]);
            }
          }
          return ES.Call(originalSplit, O, [ES.ToString(separator), limit]);
        };
        overrideNative(String.prototype, 'split', splitShim);
      }
      var symbolMatchExists = Type.symbol(Symbol.match);
      var stringMatchIgnoresSymbolMatch = symbolMatchExists && (function () {
        // Firefox 41, through Nightly 45 has Symbol.match, but String#match ignores it.
        // Firefox 40 and below have Symbol.match but String#match works fine.
        var o = {};
        o[Symbol.match] = function () { return 42; };
        return 'a'.match(o) !== 42;
      }());
      if (!symbolMatchExists || stringMatchIgnoresSymbolMatch) {
        var symbolMatch = defineWellKnownSymbol('match');
  
        var originalMatch = String.prototype.match;
        defineProperty(RegExp.prototype, symbolMatch, function match(string) {
          return ES.Call(originalMatch, string, [this]);
        });
  
        var matchShim = function match(regexp) {
          var O = ES.RequireObjectCoercible(this);
          if (!isNullOrUndefined(regexp)) {
            var matcher = ES.GetMethod(regexp, symbolMatch);
            if (typeof matcher !== 'undefined') {
              return ES.Call(matcher, regexp, [O]);
            }
          }
          return ES.Call(originalMatch, O, [ES.ToString(regexp)]);
        };
        overrideNative(String.prototype, 'match', matchShim);
      }
    }
  
    var wrapConstructor = function wrapConstructor(original, replacement, keysToSkip) {
      Value.preserveToString(replacement, original);
      if (Object.setPrototypeOf) {
        // sets up proper prototype chain where possible
        Object.setPrototypeOf(original, replacement);
      }
      if (supportsDescriptors) {
        _forEach(Object.getOwnPropertyNames(original), function (key) {
          if (key in noop || keysToSkip[key]) { return; }
          Value.proxy(original, key, replacement);
        });
      } else {
        _forEach(Object.keys(original), function (key) {
          if (key in noop || keysToSkip[key]) { return; }
          replacement[key] = original[key];
        });
      }
      replacement.prototype = original.prototype;
      Value.redefine(original.prototype, 'constructor', replacement);
    };
  
    var defaultSpeciesGetter = function () { return this; };
    var addDefaultSpecies = function (C) {
      if (supportsDescriptors && !_hasOwnProperty(C, symbolSpecies)) {
        Value.getter(C, symbolSpecies, defaultSpeciesGetter);
      }
    };
  
    var addIterator = function (prototype, impl) {
      var implementation = impl || function iterator() { return this; };
      defineProperty(prototype, $iterator$, implementation);
      if (!prototype[$iterator$] && Type.symbol($iterator$)) {
        // implementations are buggy when $iterator$ is a Symbol
        prototype[$iterator$] = implementation;
      }
    };
  
    var createDataProperty = function createDataProperty(object, name, value) {
      if (supportsDescriptors) {
        Object.defineProperty(object, name, {
          configurable: true,
          enumerable: true,
          writable: true,
          value: value
        });
      } else {
        object[name] = value;
      }
    };
    var createDataPropertyOrThrow = function createDataPropertyOrThrow(object, name, value) {
      createDataProperty(object, name, value);
      if (!ES.SameValue(object[name], value)) {
        throw new TypeError('property is nonconfigurable');
      }
    };
  
    var emulateES6construct = function (o, defaultNewTarget, defaultProto, slots) {
      // This is an es5 approximation to es6 construct semantics.  in es6,
      // 'new Foo' invokes Foo.[[Construct]] which (for almost all objects)
      // just sets the internal variable NewTarget (in es6 syntax `new.target`)
      // to Foo and then returns Foo().
  
      // Many ES6 object then have constructors of the form:
      // 1. If NewTarget is undefined, throw a TypeError exception
      // 2. Let xxx by OrdinaryCreateFromConstructor(NewTarget, yyy, zzz)
  
      // So we're going to emulate those first two steps.
      if (!ES.TypeIsObject(o)) {
        throw new TypeError('Constructor requires `new`: ' + defaultNewTarget.name);
      }
      var proto = defaultNewTarget.prototype;
      if (!ES.TypeIsObject(proto)) {
        proto = defaultProto;
      }
      var obj = create(proto);
      for (var name in slots) {
        if (_hasOwnProperty(slots, name)) {
          var value = slots[name];
          defineProperty(obj, name, value, true);
        }
      }
      return obj;
    };
  
    // Firefox 31 reports this function's length as 0
    // https://bugzilla.mozilla.org/show_bug.cgi?id=1062484
    if (String.fromCodePoint && String.fromCodePoint.length !== 1) {
      var originalFromCodePoint = String.fromCodePoint;
      overrideNative(String, 'fromCodePoint', function fromCodePoint(codePoints) {
        return ES.Call(originalFromCodePoint, this, arguments);
      });
    }
  
    var StringShims = {
      fromCodePoint: function fromCodePoint(codePoints) {
        var result = [];
        var next;
        for (var i = 0, length = arguments.length; i < length; i++) {
          next = Number(arguments[i]);
          if (!ES.SameValue(next, ES.ToInteger(next)) || next < 0 || next > 0x10FFFF) {
            throw new RangeError('Invalid code point ' + next);
          }
  
          if (next < 0x10000) {
            _push(result, String.fromCharCode(next));
          } else {
            next -= 0x10000;
            _push(result, String.fromCharCode((next >> 10) + 0xD800));
            _push(result, String.fromCharCode((next % 0x400) + 0xDC00));
          }
        }
        return result.join('');
      },
  
      raw: function raw(callSite) {
        var cooked = ES.ToObject(callSite, 'bad callSite');
        var rawString = ES.ToObject(cooked.raw, 'bad raw value');
        var len = rawString.length;
        var literalsegments = ES.ToLength(len);
        if (literalsegments <= 0) {
          return '';
        }
  
        var stringElements = [];
        var nextIndex = 0;
        var nextKey, next, nextSeg, nextSub;
        while (nextIndex < literalsegments) {
          nextKey = ES.ToString(nextIndex);
          nextSeg = ES.ToString(rawString[nextKey]);
          _push(stringElements, nextSeg);
          if (nextIndex + 1 >= literalsegments) {
            break;
          }
          next = nextIndex + 1 < arguments.length ? arguments[nextIndex + 1] : '';
          nextSub = ES.ToString(next);
          _push(stringElements, nextSub);
          nextIndex += 1;
        }
        return stringElements.join('');
      }
    };
    if (String.raw && String.raw({ raw: { 0: 'x', 1: 'y', length: 2 } }) !== 'xy') {
      // IE 11 TP has a broken String.raw implementation
      overrideNative(String, 'raw', StringShims.raw);
    }
    defineProperties(String, StringShims);
  
    // Fast repeat, uses the `Exponentiation by squaring` algorithm.
    // Perf: http://jsperf.com/string-repeat2/2
    var stringRepeat = function repeat(s, times) {
      if (times < 1) { return ''; }
      if (times % 2) { return repeat(s, times - 1) + s; }
      var half = repeat(s, times / 2);
      return half + half;
    };
    var stringMaxLength = Infinity;
  
    var StringPrototypeShims = {
      repeat: function repeat(times) {
        var thisStr = ES.ToString(ES.RequireObjectCoercible(this));
        var numTimes = ES.ToInteger(times);
        if (numTimes < 0 || numTimes >= stringMaxLength) {
          throw new RangeError('repeat count must be less than infinity and not overflow maximum string size');
        }
        return stringRepeat(thisStr, numTimes);
      },
  
      startsWith: function startsWith(searchString) {
        var S = ES.ToString(ES.RequireObjectCoercible(this));
        if (ES.IsRegExp(searchString)) {
          throw new TypeError('Cannot call method "startsWith" with a regex');
        }
        var searchStr = ES.ToString(searchString);
        var position;
        if (arguments.length > 1) {
          position = arguments[1];
        }
        var start = _max(ES.ToInteger(position), 0);
        return _strSlice(S, start, start + searchStr.length) === searchStr;
      },
  
      endsWith: function endsWith(searchString) {
        var S = ES.ToString(ES.RequireObjectCoercible(this));
        if (ES.IsRegExp(searchString)) {
          throw new TypeError('Cannot call method "endsWith" with a regex');
        }
        var searchStr = ES.ToString(searchString);
        var len = S.length;
        var endPosition;
        if (arguments.length > 1) {
          endPosition = arguments[1];
        }
        var pos = typeof endPosition === 'undefined' ? len : ES.ToInteger(endPosition);
        var end = _min(_max(pos, 0), len);
        return _strSlice(S, end - searchStr.length, end) === searchStr;
      },
  
      includes: function includes(searchString) {
        if (ES.IsRegExp(searchString)) {
          throw new TypeError('"includes" does not accept a RegExp');
        }
        var searchStr = ES.ToString(searchString);
        var position;
        if (arguments.length > 1) {
          position = arguments[1];
        }
        // Somehow this trick makes method 100% compat with the spec.
        return _indexOf(this, searchStr, position) !== -1;
      },
  
      codePointAt: function codePointAt(pos) {
        var thisStr = ES.ToString(ES.RequireObjectCoercible(this));
        var position = ES.ToInteger(pos);
        var length = thisStr.length;
        if (position >= 0 && position < length) {
          var first = thisStr.charCodeAt(position);
          var isEnd = position + 1 === length;
          if (first < 0xD800 || first > 0xDBFF || isEnd) { return first; }
          var second = thisStr.charCodeAt(position + 1);
          if (second < 0xDC00 || second > 0xDFFF) { return first; }
          return ((first - 0xD800) * 1024) + (second - 0xDC00) + 0x10000;
        }
      },
  
      // ##### BEGIN: MODIFIED BY SAP
      /** @license
       * String.prototype.padStart <https://github.com/uxitten/polyfill>
       * MIT License
       * @author Behnam Mohammadi
       * @version v1.0.1
       */
      padStart: function padStart(targetLength, padString) {
          targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
          padString = String((typeof padString !== 'undefined' ? padString : ' '));
          if (this.length > targetLength) {
              return String(this);
          }
          else {
              targetLength = targetLength - this.length;
              if (targetLength > padString.length) {
                  padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
              }
              return padString.slice(0, targetLength) + String(this);
          }
      },
  
      /** @license
       * String.prototype.padEnd <https://github.com/uxitten/polyfill>
       * MIT License
       * @author Behnam Mohammadi
       * @version v1.0.1
       */
      padEnd: function padEnd(targetLength, padString) {
          targetLength = targetLength >> 0; //floor if number or convert non-number to 0;
          padString = String((typeof padString !== 'undefined' ? padString : ' '));
          if (this.length > targetLength) {
              return String(this);
          }
          else {
              targetLength = targetLength - this.length;
              if (targetLength > padString.length) {
                  padString += padString.repeat(targetLength / padString.length); //append to original to ensure we are longer than needed
              }
              return String(this) + padString.slice(0, targetLength);
          }
      }
      // ##### END: MODIFIED BY SAP
  
    };
    if (String.prototype.includes && 'a'.includes('a', Infinity) !== false) {
      overrideNative(String.prototype, 'includes', StringPrototypeShims.includes);
    }
  
    if (String.prototype.startsWith && String.prototype.endsWith) {
      var startsWithRejectsRegex = throwsError(function () {
        /* throws if spec-compliant */
        return '/a/'.startsWith(/a/);
      });
      var startsWithHandlesInfinity = valueOrFalseIfThrows(function () {
        return 'abc'.startsWith('a', Infinity) === false;
      });
      if (!startsWithRejectsRegex || !startsWithHandlesInfinity) {
        // Firefox (< 37?) and IE 11 TP have a noncompliant startsWith implementation
        overrideNative(String.prototype, 'startsWith', StringPrototypeShims.startsWith);
        overrideNative(String.prototype, 'endsWith', StringPrototypeShims.endsWith);
      }
    }
    if (hasSymbols) {
      var startsWithSupportsSymbolMatch = valueOrFalseIfThrows(function () {
        var re = /a/;
        re[Symbol.match] = false;
        return '/a/'.startsWith(re);
      });
      if (!startsWithSupportsSymbolMatch) {
        overrideNative(String.prototype, 'startsWith', StringPrototypeShims.startsWith);
      }
      var endsWithSupportsSymbolMatch = valueOrFalseIfThrows(function () {
        var re = /a/;
        re[Symbol.match] = false;
        return '/a/'.endsWith(re);
      });
      if (!endsWithSupportsSymbolMatch) {
        overrideNative(String.prototype, 'endsWith', StringPrototypeShims.endsWith);
      }
      var includesSupportsSymbolMatch = valueOrFalseIfThrows(function () {
        var re = /a/;
        re[Symbol.match] = false;
        return '/a/'.includes(re);
      });
      if (!includesSupportsSymbolMatch) {
        overrideNative(String.prototype, 'includes', StringPrototypeShims.includes);
      }
    }
  
    defineProperties(String.prototype, StringPrototypeShims);
  
    // whitespace from: http://es5.github.io/#x15.5.4.20
    // implementation from https://github.com/es-shims/es5-shim/blob/v3.4.0/es5-shim.js#L1304-L1324
    var ws = [
      '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003',
      '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028',
      '\u2029\uFEFF'
    ].join('');
    var trimRegexp = new RegExp('(^[' + ws + ']+)|([' + ws + ']+$)', 'g');
    var trimShim = function trim() {
      return ES.ToString(ES.RequireObjectCoercible(this)).replace(trimRegexp, '');
    };
    var nonWS = ['\u0085', '\u200b', '\ufffe'].join('');
    var nonWSregex = new RegExp('[' + nonWS + ']', 'g');
    var isBadHexRegex = /^[-+]0x[0-9a-f]+$/i;
    var hasStringTrimBug = nonWS.trim().length !== nonWS.length;
    defineProperty(String.prototype, 'trim', trimShim, hasStringTrimBug);
  
    // Given an argument x, it will return an IteratorResult object,
    // with value set to x and done to false.
    // Given no arguments, it will return an iterator completion object.
    var iteratorResult = function (x) {
      return { value: x, done: arguments.length === 0 };
    };
  
    // see http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype-@@iterator
    var StringIterator = function (s) {
      ES.RequireObjectCoercible(s);
      this._s = ES.ToString(s);
      this._i = 0;
    };
    StringIterator.prototype.next = function () {
      var s = this._s;
      var i = this._i;
      if (typeof s === 'undefined' || i >= s.length) {
        this._s = void 0;
        return iteratorResult();
      }
      var first = s.charCodeAt(i);
      var second, len;
      if (first < 0xD800 || first > 0xDBFF || (i + 1) === s.length) {
        len = 1;
      } else {
        second = s.charCodeAt(i + 1);
        len = (second < 0xDC00 || second > 0xDFFF) ? 1 : 2;
      }
      this._i = i + len;
      return iteratorResult(s.substr(i, len));
    };
    addIterator(StringIterator.prototype);
    addIterator(String.prototype, function () {
      return new StringIterator(this);
    });
  
    var ArrayShims = {
      from: function from(items) {
        var C = this;
        var mapFn;
        if (arguments.length > 1) {
          mapFn = arguments[1];
        }
        var mapping, T;
        if (typeof mapFn === 'undefined') {
          mapping = false;
        } else {
          if (!ES.IsCallable(mapFn)) {
            throw new TypeError('Array.from: when provided, the second argument must be a function');
          }
          if (arguments.length > 2) {
            T = arguments[2];
          }
          mapping = true;
        }
  
        // Note that that Arrays will use ArrayIterator:
        // https://bugs.ecmascript.org/show_bug.cgi?id=2416
        var usingIterator = typeof (isArguments(items) || ES.GetMethod(items, $iterator$)) !== 'undefined';
  
        var length, result, i;
        if (usingIterator) {
          result = ES.IsConstructor(C) ? Object(new C()) : [];
          var iterator = ES.GetIterator(items);
          var next, nextValue;
  
          i = 0;
          while (true) {
            next = ES.IteratorStep(iterator);
            if (next === false) {
              break;
            }
            nextValue = next.value;
            try {
              if (mapping) {
                nextValue = typeof T === 'undefined' ? mapFn(nextValue, i) : _call(mapFn, T, nextValue, i);
              }
              result[i] = nextValue;
            } catch (e) {
              ES.IteratorClose(iterator, true);
              throw e;
            }
            i += 1;
          }
          length = i;
        } else {
          var arrayLike = ES.ToObject(items);
          length = ES.ToLength(arrayLike.length);
          result = ES.IsConstructor(C) ? Object(new C(length)) : new Array(length);
          var value;
          for (i = 0; i < length; ++i) {
            value = arrayLike[i];
            if (mapping) {
              value = typeof T === 'undefined' ? mapFn(value, i) : _call(mapFn, T, value, i);
            }
            createDataPropertyOrThrow(result, i, value);
          }
        }
  
        result.length = length;
        return result;
      },
  
      of: function of() {
        var len = arguments.length;
        var C = this;
        var A = isArray(C) || !ES.IsCallable(C) ? new Array(len) : ES.Construct(C, [len]);
        for (var k = 0; k < len; ++k) {
          createDataPropertyOrThrow(A, k, arguments[k]);
        }
        A.length = len;
        return A;
      }
    };
    defineProperties(Array, ArrayShims);
    addDefaultSpecies(Array);
  
    // Our ArrayIterator is private; see
    // https://github.com/paulmillr/es6-shim/issues/252
    ArrayIterator = function (array, kind) {
      this.i = 0;
      this.array = array;
      this.kind = kind;
    };
  
    defineProperties(ArrayIterator.prototype, {
      next: function () {
        var i = this.i;
        var array = this.array;
        if (!(this instanceof ArrayIterator)) {
          throw new TypeError('Not an ArrayIterator');
        }
        if (typeof array !== 'undefined') {
          var len = ES.ToLength(array.length);
          for (; i < len; i++) {
            var kind = this.kind;
            var retval;
            if (kind === 'key') {
              retval = i;
            } else if (kind === 'value') {
              retval = array[i];
            } else if (kind === 'entry') {
              retval = [i, array[i]];
            }
            this.i = i + 1;
            return iteratorResult(retval);
          }
        }
        this.array = void 0;
        return iteratorResult();
      }
    });
    addIterator(ArrayIterator.prototype);
  
    /*
    var orderKeys = function orderKeys(a, b) {
      var aNumeric = String(ES.ToInteger(a)) === a;
      var bNumeric = String(ES.ToInteger(b)) === b;
      if (aNumeric && bNumeric) {
        return b - a;
      } else if (aNumeric && !bNumeric) {
        return -1;
      } else if (!aNumeric && bNumeric) {
        return 1;
      } else {
        return a.localeCompare(b);
      }
    };
  
    var getAllKeys = function getAllKeys(object) {
      var ownKeys = [];
      var keys = [];
  
      for (var key in object) {
        _push(_hasOwnProperty(object, key) ? ownKeys : keys, key);
      }
      _sort(ownKeys, orderKeys);
      _sort(keys, orderKeys);
  
      return _concat(ownKeys, keys);
    };
    */
  
    // note: this is positioned here because it depends on ArrayIterator
    var arrayOfSupportsSubclassing = Array.of === ArrayShims.of || (function () {
      // Detects a bug in Webkit nightly r181886
      var Foo = function Foo(len) { this.length = len; };
      Foo.prototype = [];
      var fooArr = Array.of.apply(Foo, [1, 2]);
      return fooArr instanceof Foo && fooArr.length === 2;
    }());
    if (!arrayOfSupportsSubclassing) {
      overrideNative(Array, 'of', ArrayShims.of);
    }
  
    var ArrayPrototypeShims = {
      copyWithin: function copyWithin(target, start) {
        var o = ES.ToObject(this);
        var len = ES.ToLength(o.length);
        var relativeTarget = ES.ToInteger(target);
        var relativeStart = ES.ToInteger(start);
        var to = relativeTarget < 0 ? _max(len + relativeTarget, 0) : _min(relativeTarget, len);
        var from = relativeStart < 0 ? _max(len + relativeStart, 0) : _min(relativeStart, len);
        var end;
        if (arguments.length > 2) {
          end = arguments[2];
        }
        var relativeEnd = typeof end === 'undefined' ? len : ES.ToInteger(end);
        var finalItem = relativeEnd < 0 ? _max(len + relativeEnd, 0) : _min(relativeEnd, len);
        var count = _min(finalItem - from, len - to);
        var direction = 1;
        if (from < to && to < (from + count)) {
          direction = -1;
          from += count - 1;
          to += count - 1;
        }
        while (count > 0) {
          if (from in o) {
            o[to] = o[from];
          } else {
            delete o[to];
          }
          from += direction;
          to += direction;
          count -= 1;
        }
        return o;
      },
  
      fill: function fill(value) {
        var start;
        if (arguments.length > 1) {
          start = arguments[1];
        }
        var end;
        if (arguments.length > 2) {
          end = arguments[2];
        }
        var O = ES.ToObject(this);
        var len = ES.ToLength(O.length);
        start = ES.ToInteger(typeof start === 'undefined' ? 0 : start);
        end = ES.ToInteger(typeof end === 'undefined' ? len : end);
  
        var relativeStart = start < 0 ? _max(len + start, 0) : _min(start, len);
        var relativeEnd = end < 0 ? len + end : end;
  
        for (var i = relativeStart; i < len && i < relativeEnd; ++i) {
          O[i] = value;
        }
        return O;
      },
  
      find: function find(predicate) {
        var list = ES.ToObject(this);
        var length = ES.ToLength(list.length);
        if (!ES.IsCallable(predicate)) {
          throw new TypeError('Array#find: predicate must be a function');
        }
        var thisArg = arguments.length > 1 ? arguments[1] : null;
        for (var i = 0, value; i < length; i++) {
          value = list[i];
          if (thisArg) {
            if (_call(predicate, thisArg, value, i, list)) {
              return value;
            }
          } else if (predicate(value, i, list)) {
            return value;
          }
        }
      },
  
      findIndex: function findIndex(predicate) {
        var list = ES.ToObject(this);
        var length = ES.ToLength(list.length);
        if (!ES.IsCallable(predicate)) {
          throw new TypeError('Array#findIndex: predicate must be a function');
        }
        var thisArg = arguments.length > 1 ? arguments[1] : null;
        for (var i = 0; i < length; i++) {
          if (thisArg) {
            if (_call(predicate, thisArg, list[i], i, list)) {
              return i;
            }
          } else if (predicate(list[i], i, list)) {
            return i;
          }
        }
        return -1;
      },
  
      keys: function keys() {
        return new ArrayIterator(this, 'key');
      },
  
      values: function values() {
        return new ArrayIterator(this, 'value');
      },
  
      entries: function entries() {
        return new ArrayIterator(this, 'entry');
      }
    };
    // Safari 7.1 defines Array#keys and Array#entries natively,
    // but the resulting ArrayIterator objects don't have a "next" method.
    if (Array.prototype.keys && !ES.IsCallable([1].keys().next)) {
      delete Array.prototype.keys;
    }
    if (Array.prototype.entries && !ES.IsCallable([1].entries().next)) {
      delete Array.prototype.entries;
    }
  
    // Chrome 38 defines Array#keys and Array#entries, and Array#@@iterator, but not Array#values
    if (Array.prototype.keys && Array.prototype.entries && !Array.prototype.values && Array.prototype[$iterator$]) {
      defineProperties(Array.prototype, {
        values: Array.prototype[$iterator$]
      });
      if (Type.symbol(Symbol.unscopables)) {
        Array.prototype[Symbol.unscopables].values = true;
      }
    }
    // Chrome 40 defines Array#values with the incorrect name, although Array#{keys,entries} have the correct name
    if (functionsHaveNames && Array.prototype.values && Array.prototype.values.name !== 'values') {
      var originalArrayPrototypeValues = Array.prototype.values;
      overrideNative(Array.prototype, 'values', function values() { return ES.Call(originalArrayPrototypeValues, this, arguments); });
      defineProperty(Array.prototype, $iterator$, Array.prototype.values, true);
    }
    defineProperties(Array.prototype, ArrayPrototypeShims);
  
    if (1 / [true].indexOf(true, -0) < 0) {
      // indexOf when given a position arg of -0 should return +0.
      // https://github.com/tc39/ecma262/pull/316
      defineProperty(Array.prototype, 'indexOf', function indexOf(searchElement) {
        var value = _arrayIndexOfApply(this, arguments);
        if (value === 0 && (1 / value) < 0) {
          return 0;
        }
        return value;
      }, true);
    }
  
    addIterator(Array.prototype, function () { return this.values(); });
    // Chrome defines keys/values/entries on Array, but doesn't give us
    // any way to identify its iterator.  So add our own shimmed field.
    if (Object.getPrototypeOf) {
      addIterator(Object.getPrototypeOf([].values()));
    }
  
    // note: this is positioned here because it relies on Array#entries
    var arrayFromSwallowsNegativeLengths = (function () {
      // Detects a Firefox bug in v32
      // https://bugzilla.mozilla.org/show_bug.cgi?id=1063993
      return valueOrFalseIfThrows(function () {
        return Array.from({ length: -1 }).length === 0;
      });
    }());
    var arrayFromHandlesIterables = (function () {
      // Detects a bug in Webkit nightly r181886
      var arr = Array.from([0].entries());
      return arr.length === 1 && isArray(arr[0]) && arr[0][0] === 0 && arr[0][1] === 0;
    }());
    if (!arrayFromSwallowsNegativeLengths || !arrayFromHandlesIterables) {
      overrideNative(Array, 'from', ArrayShims.from);
    }
    var arrayFromHandlesUndefinedMapFunction = (function () {
      // Microsoft Edge v0.11 throws if the mapFn argument is *provided* but undefined,
      // but the spec doesn't care if it's provided or not - undefined doesn't throw.
      return valueOrFalseIfThrows(function () {
        return Array.from([0], void 0);
      });
    }());
    if (!arrayFromHandlesUndefinedMapFunction) {
      var origArrayFrom = Array.from;
      overrideNative(Array, 'from', function from(items) {
        if (arguments.length > 1 && typeof arguments[1] !== 'undefined') {
          return ES.Call(origArrayFrom, this, arguments);
        } else {
          return _call(origArrayFrom, this, items);
        }
      });
    }
  
    var int32sAsOne = -(Math.pow(2, 32) - 1);
    var toLengthsCorrectly = function (method, reversed) {
      var obj = { length: int32sAsOne };
      obj[reversed ? (obj.length >>> 0) - 1 : 0] = true;
      return valueOrFalseIfThrows(function () {
        _call(method, obj, function () {
          // note: in nonconforming browsers, this will be called
          // -1 >>> 0 times, which is 4294967295, so the throw matters.
          throw new RangeError('should not reach here');
        }, []);
        return true;
      });
    };
    if (!toLengthsCorrectly(Array.prototype.forEach)) {
      var originalForEach = Array.prototype.forEach;
      overrideNative(Array.prototype, 'forEach', function forEach(callbackFn) {
        return ES.Call(originalForEach, this.length >= 0 ? this : [], arguments);
      }, true);
    }
    if (!toLengthsCorrectly(Array.prototype.map)) {
      var originalMap = Array.prototype.map;
      overrideNative(Array.prototype, 'map', function map(callbackFn) {
        return ES.Call(originalMap, this.length >= 0 ? this : [], arguments);
      }, true);
    }
    if (!toLengthsCorrectly(Array.prototype.filter)) {
      var originalFilter = Array.prototype.filter;
      overrideNative(Array.prototype, 'filter', function filter(callbackFn) {
        return ES.Call(originalFilter, this.length >= 0 ? this : [], arguments);
      }, true);
    }
    if (!toLengthsCorrectly(Array.prototype.some)) {
      var originalSome = Array.prototype.some;
      overrideNative(Array.prototype, 'some', function some(callbackFn) {
        return ES.Call(originalSome, this.length >= 0 ? this : [], arguments);
      }, true);
    }
    if (!toLengthsCorrectly(Array.prototype.every)) {
      var originalEvery = Array.prototype.every;
      overrideNative(Array.prototype, 'every', function every(callbackFn) {
        return ES.Call(originalEvery, this.length >= 0 ? this : [], arguments);
      }, true);
    }
    if (!toLengthsCorrectly(Array.prototype.reduce)) {
      var originalReduce = Array.prototype.reduce;
      overrideNative(Array.prototype, 'reduce', function reduce(callbackFn) {
        return ES.Call(originalReduce, this.length >= 0 ? this : [], arguments);
      }, true);
    }
    if (!toLengthsCorrectly(Array.prototype.reduceRight, true)) {
      var originalReduceRight = Array.prototype.reduceRight;
      overrideNative(Array.prototype, 'reduceRight', function reduceRight(callbackFn) {
        return ES.Call(originalReduceRight, this.length >= 0 ? this : [], arguments);
      }, true);
    }
  
    var lacksOctalSupport = Number('0o10') !== 8;
    var lacksBinarySupport = Number('0b10') !== 2;
    var trimsNonWhitespace = _some(nonWS, function (c) {
      return Number(c + 0 + c) === 0;
    });
    if (lacksOctalSupport || lacksBinarySupport || trimsNonWhitespace) {
      var OrigNumber = Number;
      var binaryRegex = /^0b[01]+$/i;
      var octalRegex = /^0o[0-7]+$/i;
      // Note that in IE 8, RegExp.prototype.test doesn't seem to exist: ie, "test" is an own property of regexes. wtf.
      var isBinary = binaryRegex.test.bind(binaryRegex);
      var isOctal = octalRegex.test.bind(octalRegex);
      var toPrimitive = function (O) { // need to replace this with `es-to-primitive/es6`
        var result;
        if (typeof O.valueOf === 'function') {
          result = O.valueOf();
          if (Type.primitive(result)) {
            return result;
          }
        }
        if (typeof O.toString === 'function') {
          result = O.toString();
          if (Type.primitive(result)) {
            return result;
          }
        }
        throw new TypeError('No default value');
      };
      var hasNonWS = nonWSregex.test.bind(nonWSregex);
      var isBadHex = isBadHexRegex.test.bind(isBadHexRegex);
      var NumberShim = (function () {
        // this is wrapped in an IIFE because of IE 6-8's wacky scoping issues with named function expressions.
        var NumberShim = function Number(value) {
          var primValue;
          if (arguments.length > 0) {
            primValue = Type.primitive(value) ? value : toPrimitive(value, 'number');
          } else {
            primValue = 0;
          }
          if (typeof primValue === 'string') {
            primValue = ES.Call(trimShim, primValue);
            if (isBinary(primValue)) {
              primValue = parseInt(_strSlice(primValue, 2), 2);
            } else if (isOctal(primValue)) {
              primValue = parseInt(_strSlice(primValue, 2), 8);
            } else if (hasNonWS(primValue) || isBadHex(primValue)) {
              primValue = NaN;
            }
          }
          var receiver = this;
          var valueOfSucceeds = valueOrFalseIfThrows(function () {
            OrigNumber.prototype.valueOf.call(receiver);
            return true;
          });
          if (receiver instanceof NumberShim && !valueOfSucceeds) {
            return new OrigNumber(primValue);
          }
          /* jshint newcap: false */
          return OrigNumber(primValue);
          /* jshint newcap: true */
        };
        return NumberShim;
      }());
      wrapConstructor(OrigNumber, NumberShim, {});
      // this is necessary for ES3 browsers, where these properties are non-enumerable.
      defineProperties(NumberShim, {
        NaN: OrigNumber.NaN,
        MAX_VALUE: OrigNumber.MAX_VALUE,
        MIN_VALUE: OrigNumber.MIN_VALUE,
        NEGATIVE_INFINITY: OrigNumber.NEGATIVE_INFINITY,
        POSITIVE_INFINITY: OrigNumber.POSITIVE_INFINITY
      });
      /* globals Number: true */
      /* eslint-disable no-undef, no-global-assign */
      /* jshint -W020 */
      Number = NumberShim;
      Value.redefine(globals, 'Number', NumberShim);
      /* jshint +W020 */
      /* eslint-enable no-undef, no-global-assign */
      /* globals Number: false */
    }
  
    var maxSafeInteger = Math.pow(2, 53) - 1;
    defineProperties(Number, {
      MAX_SAFE_INTEGER: maxSafeInteger,
      MIN_SAFE_INTEGER: -maxSafeInteger,
      EPSILON: 2.220446049250313e-16,
  
      parseInt: globals.parseInt,
      parseFloat: globals.parseFloat,
  
      isFinite: numberIsFinite,
  
      isInteger: function isInteger(value) {
        return numberIsFinite(value) && ES.ToInteger(value) === value;
      },
  
      isSafeInteger: function isSafeInteger(value) {
        return Number.isInteger(value) && _abs(value) <= Number.MAX_SAFE_INTEGER;
      },
  
      isNaN: numberIsNaN
    });
    // Firefox 37 has a conforming Number.parseInt, but it's not === to the global parseInt (fixed in v40)
    defineProperty(Number, 'parseInt', globals.parseInt, Number.parseInt !== globals.parseInt);
  
    // Work around bugs in Array#find and Array#findIndex -- early
    // implementations skipped holes in sparse arrays. (Note that the
    // implementations of find/findIndex indirectly use shimmed
    // methods of Number, so this test has to happen down here.)
    /*jshint elision: true */
    /* eslint-disable no-sparse-arrays */
    if ([, 1].find(function () { return true; }) === 1) {
      overrideNative(Array.prototype, 'find', ArrayPrototypeShims.find);
    }
    if ([, 1].findIndex(function () { return true; }) !== 0) {
      overrideNative(Array.prototype, 'findIndex', ArrayPrototypeShims.findIndex);
    }
    /* eslint-enable no-sparse-arrays */
    /*jshint elision: false */
  
    var isEnumerableOn = Function.bind.call(Function.bind, Object.prototype.propertyIsEnumerable);
    var ensureEnumerable = function ensureEnumerable(obj, prop) {
      if (supportsDescriptors && isEnumerableOn(obj, prop)) {
        Object.defineProperty(obj, prop, { enumerable: false });
      }
    };
    var sliceArgs = function sliceArgs() {
      // per https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#32-leaking-arguments
      // and https://gist.github.com/WebReflection/4327762cb87a8c634a29
      var initial = Number(this);
      var len = arguments.length;
      var desiredArgCount = len - initial;
      var args = new Array(desiredArgCount < 0 ? 0 : desiredArgCount);
      for (var i = initial; i < len; ++i) {
        args[i - initial] = arguments[i];
      }
      return args;
    };
    var assignTo = function assignTo(source) {
      return function assignToSource(target, key) {
        target[key] = source[key];
        return target;
      };
    };
    var assignReducer = function (target, source) {
      var sourceKeys = keys(Object(source));
      var symbols;
      if (ES.IsCallable(Object.getOwnPropertySymbols)) {
        symbols = _filter(Object.getOwnPropertySymbols(Object(source)), isEnumerableOn(source));
      }
      return _reduce(_concat(sourceKeys, symbols || []), assignTo(source), target);
    };
  
    var ObjectShims = {
      // 19.1.3.1
      assign: function (target, source) {
        var to = ES.ToObject(target, 'Cannot convert undefined or null to object');
        return _reduce(ES.Call(sliceArgs, 1, arguments), assignReducer, to);
      },
  
      // Added in WebKit in https://bugs.webkit.org/show_bug.cgi?id=143865
      is: function is(a, b) {
        return ES.SameValue(a, b);
      }
    };
    var assignHasPendingExceptions = Object.assign && Object.preventExtensions && (function () {
      // Firefox 37 still has "pending exception" logic in its Object.assign implementation,
      // which is 72% slower than our shim, and Firefox 40's native implementation.
      var thrower = Object.preventExtensions({ 1: 2 });
      try {
        Object.assign(thrower, 'xy');
      } catch (e) {
        return thrower[1] === 'y';
      }
    }());
    if (assignHasPendingExceptions) {
      overrideNative(Object, 'assign', ObjectShims.assign);
    }
    defineProperties(Object, ObjectShims);
  
    if (supportsDescriptors) {
      var ES5ObjectShims = {
        // 19.1.3.9
        // shim from https://gist.github.com/WebReflection/5593554
        setPrototypeOf: (function (Object, magic) {
          var set;
  
          var checkArgs = function (O, proto) {
            if (!ES.TypeIsObject(O)) {
              throw new TypeError('cannot set prototype on a non-object');
            }
            if (!(proto === null || ES.TypeIsObject(proto))) {
              throw new TypeError('can only set prototype to an object or null' + proto);
            }
          };
  
          var setPrototypeOf = function (O, proto) {
            checkArgs(O, proto);
            _call(set, O, proto);
            return O;
          };
  
          try {
            // this works already in Firefox and Safari
            set = Object.getOwnPropertyDescriptor(Object.prototype, magic).set;
            _call(set, {}, null);
          } catch (e) {
            if (Object.prototype !== {}[magic]) {
              // IE < 11 cannot be shimmed
              return;
            }
            // probably Chrome or some old Mobile stock browser
            set = function (proto) {
              this[magic] = proto;
            };
            // please note that this will **not** work
            // in those browsers that do not inherit
            // __proto__ by mistake from Object.prototype
            // in these cases we should probably throw an error
            // or at least be informed about the issue
            setPrototypeOf.polyfill = setPrototypeOf(
              setPrototypeOf({}, null),
              Object.prototype
            ) instanceof Object;
            // setPrototypeOf.polyfill === true means it works as meant
            // setPrototypeOf.polyfill === false means it's not 100% reliable
            // setPrototypeOf.polyfill === undefined
            // or
            // setPrototypeOf.polyfill ==  null means it's not a polyfill
            // which means it works as expected
            // we can even delete Object.prototype.__proto__;
          }
          return setPrototypeOf;
        }(Object, '__proto__'))
      };
  
      defineProperties(Object, ES5ObjectShims);
    }
  
    // Workaround bug in Opera 12 where setPrototypeOf(x, null) doesn't work,
    // but Object.create(null) does.
    if (Object.setPrototypeOf && Object.getPrototypeOf &&
        Object.getPrototypeOf(Object.setPrototypeOf({}, null)) !== null &&
        Object.getPrototypeOf(Object.create(null)) === null) {
      (function () {
        var FAKENULL = Object.create(null);
        var gpo = Object.getPrototypeOf;
        var spo = Object.setPrototypeOf;
        Object.getPrototypeOf = function (o) {
          var result = gpo(o);
          return result === FAKENULL ? null : result;
        };
        Object.setPrototypeOf = function (o, p) {
          var proto = p === null ? FAKENULL : p;
          return spo(o, proto);
        };
        Object.setPrototypeOf.polyfill = false;
      }());
    }
  
    var objectKeysAcceptsPrimitives = !throwsError(function () { return Object.keys('foo'); });
    if (!objectKeysAcceptsPrimitives) {
      var originalObjectKeys = Object.keys;
      overrideNative(Object, 'keys', function keys(value) {
        return originalObjectKeys(ES.ToObject(value));
      });
      keys = Object.keys;
    }
    var objectKeysRejectsRegex = throwsError(function () { return Object.keys(/a/g); });
    if (objectKeysRejectsRegex) {
      var regexRejectingObjectKeys = Object.keys;
      overrideNative(Object, 'keys', function keys(value) {
        if (Type.regex(value)) {
          var regexKeys = [];
          for (var k in value) {
            if (_hasOwnProperty(value, k)) {
              _push(regexKeys, k);
            }
          }
          return regexKeys;
        }
        return regexRejectingObjectKeys(value);
      });
      keys = Object.keys;
    }
  
    if (Object.getOwnPropertyNames) {
      var objectGOPNAcceptsPrimitives = !throwsError(function () { return Object.getOwnPropertyNames('foo'); });
      if (!objectGOPNAcceptsPrimitives) {
        var cachedWindowNames = typeof window === 'object' ? Object.getOwnPropertyNames(window) : [];
        var originalObjectGetOwnPropertyNames = Object.getOwnPropertyNames;
        overrideNative(Object, 'getOwnPropertyNames', function getOwnPropertyNames(value) {
          var val = ES.ToObject(value);
          if (_toString(val) === '[object Window]') {
            try {
              return originalObjectGetOwnPropertyNames(val);
            } catch (e) {
              // IE bug where layout engine calls userland gOPN for cross-domain `window` objects
              return _concat([], cachedWindowNames);
            }
          }
          return originalObjectGetOwnPropertyNames(val);
        });
      }
    }
    if (Object.getOwnPropertyDescriptor) {
      var objectGOPDAcceptsPrimitives = !throwsError(function () { return Object.getOwnPropertyDescriptor('foo', 'bar'); });
      if (!objectGOPDAcceptsPrimitives) {
        var originalObjectGetOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
        overrideNative(Object, 'getOwnPropertyDescriptor', function getOwnPropertyDescriptor(value, property) {
          return originalObjectGetOwnPropertyDescriptor(ES.ToObject(value), property);
        });
      }
    }
    if (Object.seal) {
      var objectSealAcceptsPrimitives = !throwsError(function () { return Object.seal('foo'); });
      if (!objectSealAcceptsPrimitives) {
        var originalObjectSeal = Object.seal;
        overrideNative(Object, 'seal', function seal(value) {
          if (!ES.TypeIsObject(value)) { return value; }
          return originalObjectSeal(value);
        });
      }
    }
    if (Object.isSealed) {
      var objectIsSealedAcceptsPrimitives = !throwsError(function () { return Object.isSealed('foo'); });
      if (!objectIsSealedAcceptsPrimitives) {
        var originalObjectIsSealed = Object.isSealed;
        overrideNative(Object, 'isSealed', function isSealed(value) {
          if (!ES.TypeIsObject(value)) { return true; }
          return originalObjectIsSealed(value);
        });
      }
    }
    if (Object.freeze) {
      var objectFreezeAcceptsPrimitives = !throwsError(function () { return Object.freeze('foo'); });
      if (!objectFreezeAcceptsPrimitives) {
        var originalObjectFreeze = Object.freeze;
        overrideNative(Object, 'freeze', function freeze(value) {
          if (!ES.TypeIsObject(value)) { return value; }
          return originalObjectFreeze(value);
        });
      }
    }
    if (Object.isFrozen) {
      var objectIsFrozenAcceptsPrimitives = !throwsError(function () { return Object.isFrozen('foo'); });
      if (!objectIsFrozenAcceptsPrimitives) {
        var originalObjectIsFrozen = Object.isFrozen;
        overrideNative(Object, 'isFrozen', function isFrozen(value) {
          if (!ES.TypeIsObject(value)) { return true; }
          return originalObjectIsFrozen(value);
        });
      }
    }
    if (Object.preventExtensions) {
      var objectPreventExtensionsAcceptsPrimitives = !throwsError(function () { return Object.preventExtensions('foo'); });
      if (!objectPreventExtensionsAcceptsPrimitives) {
        var originalObjectPreventExtensions = Object.preventExtensions;
        overrideNative(Object, 'preventExtensions', function preventExtensions(value) {
          if (!ES.TypeIsObject(value)) { return value; }
          return originalObjectPreventExtensions(value);
        });
      }
    }
    if (Object.isExtensible) {
      var objectIsExtensibleAcceptsPrimitives = !throwsError(function () { return Object.isExtensible('foo'); });
      if (!objectIsExtensibleAcceptsPrimitives) {
        var originalObjectIsExtensible = Object.isExtensible;
        overrideNative(Object, 'isExtensible', function isExtensible(value) {
          if (!ES.TypeIsObject(value)) { return false; }
          return originalObjectIsExtensible(value);
        });
      }
    }
    if (Object.getPrototypeOf) {
      var objectGetProtoAcceptsPrimitives = !throwsError(function () { return Object.getPrototypeOf('foo'); });
      if (!objectGetProtoAcceptsPrimitives) {
        var originalGetProto = Object.getPrototypeOf;
        overrideNative(Object, 'getPrototypeOf', function getPrototypeOf(value) {
          return originalGetProto(ES.ToObject(value));
        });
      }
    }
  
    var hasFlags = supportsDescriptors && (function () {
      var desc = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags');
      return desc && ES.IsCallable(desc.get);
    }());
    if (supportsDescriptors && !hasFlags) {
      var regExpFlagsGetter = function flags() {
        if (!ES.TypeIsObject(this)) {
          throw new TypeError('Method called on incompatible type: must be an object.');
        }
        var result = '';
        if (this.global) {
          result += 'g';
        }
        if (this.ignoreCase) {
          result += 'i';
        }
        if (this.multiline) {
          result += 'm';
        }
        if (this.unicode) {
          result += 'u';
        }
        if (this.sticky) {
          result += 'y';
        }
        return result;
      };
  
      Value.getter(RegExp.prototype, 'flags', regExpFlagsGetter);
    }
  
    var regExpSupportsFlagsWithRegex = supportsDescriptors && valueOrFalseIfThrows(function () {
      return String(new RegExp(/a/g, 'i')) === '/a/i';
    });
    var regExpNeedsToSupportSymbolMatch = hasSymbols && supportsDescriptors && (function () {
      // Edge 0.12 supports flags fully, but does not support Symbol.match
      var regex = /./;
      regex[Symbol.match] = false;
      return RegExp(regex) === regex;
    }());
  
    var regexToStringIsGeneric = valueOrFalseIfThrows(function () {
      return RegExp.prototype.toString.call({ source: 'abc' }) === '/abc/';
    });
    var regexToStringSupportsGenericFlags = regexToStringIsGeneric && valueOrFalseIfThrows(function () {
      return RegExp.prototype.toString.call({ source: 'a', flags: 'b' }) === '/a/b';
    });
    if (!regexToStringIsGeneric || !regexToStringSupportsGenericFlags) {
      var origRegExpToString = RegExp.prototype.toString;
      defineProperty(RegExp.prototype, 'toString', function toString() {
        var R = ES.RequireObjectCoercible(this);
        if (Type.regex(R)) {
          return _call(origRegExpToString, R);
        }
        var pattern = $String(R.source);
        var flags = $String(R.flags);
        return '/' + pattern + '/' + flags;
      }, true);
      Value.preserveToString(RegExp.prototype.toString, origRegExpToString);
    }
  
    if (supportsDescriptors && (!regExpSupportsFlagsWithRegex || regExpNeedsToSupportSymbolMatch)) {
      var flagsGetter = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get;
      var sourceDesc = Object.getOwnPropertyDescriptor(RegExp.prototype, 'source') || {};
      var legacySourceGetter = function () {
        // prior to it being a getter, it's own + nonconfigurable
        return this.source;
      };
      var sourceGetter = ES.IsCallable(sourceDesc.get) ? sourceDesc.get : legacySourceGetter;
  
      var OrigRegExp = RegExp;
      var RegExpShim = (function () {
        return function RegExp(pattern, flags) {
          var patternIsRegExp = ES.IsRegExp(pattern);
          var calledWithNew = this instanceof RegExp;
          if (!calledWithNew && patternIsRegExp && typeof flags === 'undefined' && pattern.constructor === RegExp) {
            return pattern;
          }
  
          var P = pattern;
          var F = flags;
          if (Type.regex(pattern)) {
            P = ES.Call(sourceGetter, pattern);
            F = typeof flags === 'undefined' ? ES.Call(flagsGetter, pattern) : flags;
            return new RegExp(P, F);
          } else if (patternIsRegExp) {
            P = pattern.source;
            F = typeof flags === 'undefined' ? pattern.flags : flags;
          }
          return new OrigRegExp(pattern, flags);
        };
      }());
      wrapConstructor(OrigRegExp, RegExpShim, {
        $input: true // Chrome < v39 & Opera < 26 have a nonstandard "$input" property
      });
      /* globals RegExp: true */
      /* eslint-disable no-undef, no-global-assign */
      /* jshint -W020 */
      RegExp = RegExpShim;
      Value.redefine(globals, 'RegExp', RegExpShim);
      /* jshint +W020 */
      /* eslint-enable no-undef, no-global-assign */
      /* globals RegExp: false */
    }
  
    if (supportsDescriptors) {
      var regexGlobals = {
        input: '$_',
        lastMatch: '$&',
        lastParen: '$+',
        leftContext: '$`',
        rightContext: '$\''
      };
      _forEach(keys(regexGlobals), function (prop) {
        if (prop in RegExp && !(regexGlobals[prop] in RegExp)) {
          Value.getter(RegExp, regexGlobals[prop], function get() {
            return RegExp[prop];
          });
        }
      });
    }
    addDefaultSpecies(RegExp);
  
    var inverseEpsilon = 1 / Number.EPSILON;
    var roundTiesToEven = function roundTiesToEven(n) {
      // Even though this reduces down to `return n`, it takes advantage of built-in rounding.
      return (n + inverseEpsilon) - inverseEpsilon;
    };
    var BINARY_32_EPSILON = Math.pow(2, -23);
    var BINARY_32_MAX_VALUE = Math.pow(2, 127) * (2 - BINARY_32_EPSILON);
    var BINARY_32_MIN_VALUE = Math.pow(2, -126);
    var E = Math.E;
    var LOG2E = Math.LOG2E;
    var LOG10E = Math.LOG10E;
    var numberCLZ = Number.prototype.clz;
    delete Number.prototype.clz; // Safari 8 has Number#clz
  
    var MathShims = {
      acosh: function acosh(value) {
        var x = Number(value);
        if (numberIsNaN(x) || value < 1) { return NaN; }
        if (x === 1) { return 0; }
        if (x === Infinity) { return x; }
  
        var xInvSquared = 1 / (x * x);
        if (x < 2) {
          return _log1p(x - 1 + (_sqrt(1 - xInvSquared) * x));
        }
        var halfX = x / 2;
        return _log1p(halfX + (_sqrt(1 - xInvSquared) * halfX) - 1) + (1 / LOG2E);
      },
  
      asinh: function asinh(value) {
        var x = Number(value);
        if (x === 0 || !globalIsFinite(x)) {
          return x;
        }
  
        var a = _abs(x);
        var aSquared = a * a;
        var s = _sign(x);
        if (a < 1) {
          return s * _log1p(a + (aSquared / (_sqrt(aSquared + 1) + 1)));
        }
        return s * (_log1p((a / 2) + (_sqrt(1 + (1 / aSquared)) * a / 2) - 1) + (1 / LOG2E));
      },
  
      atanh: function atanh(value) {
        var x = Number(value);
  
        if (x === 0) { return x; }
        if (x === -1) { return -Infinity; }
        if (x === 1) { return Infinity; }
        if (numberIsNaN(x) || x < -1 || x > 1) {
          return NaN;
        }
  
        var a = _abs(x);
        return _sign(x) * _log1p(2 * a / (1 - a)) / 2;
      },
  
      cbrt: function cbrt(value) {
        var x = Number(value);
        if (x === 0) { return x; }
        var negate = x < 0;
        var result;
        if (negate) { x = -x; }
        if (x === Infinity) {
          result = Infinity;
        } else {
          result = _exp(_log(x) / 3);
          // from http://en.wikipedia.org/wiki/Cube_root#Numerical_methods
          result = ((x / (result * result)) + (2 * result)) / 3;
        }
        return negate ? -result : result;
      },
  
      clz32: function clz32(value) {
        // See https://bugs.ecmascript.org/show_bug.cgi?id=2465
        var x = Number(value);
        var number = ES.ToUint32(x);
        if (number === 0) {
          return 32;
        }
        return numberCLZ ? ES.Call(numberCLZ, number) : 31 - _floor(_log(number + 0.5) * LOG2E);
      },
  
      cosh: function cosh(value) {
        var x = Number(value);
        if (x === 0) { return 1; } // +0 or -0
        if (numberIsNaN(x)) { return NaN; }
        if (!globalIsFinite(x)) { return Infinity; }
  
        var t = _exp(_abs(x) - 1);
        return (t + (1 / (t * E * E))) * (E / 2);
      },
  
      expm1: function expm1(value) {
        var x = Number(value);
        if (x === -Infinity) { return -1; }
        if (!globalIsFinite(x) || x === 0) { return x; }
        if (_abs(x) > 0.5) {
          return _exp(x) - 1;
        }
        // A more precise approximation using Taylor series expansion
        // from https://github.com/paulmillr/es6-shim/issues/314#issuecomment-70293986
        var t = x;
        var sum = 0;
        var n = 1;
        while (sum + t !== sum) {
          sum += t;
          n += 1;
          t *= x / n;
        }
        return sum;
      },
  
      hypot: function hypot(x, y) {
        var result = 0;
        var largest = 0;
        for (var i = 0; i < arguments.length; ++i) {
          var value = _abs(Number(arguments[i]));
          if (largest < value) {
            result *= (largest / value) * (largest / value);
            result += 1;
            largest = value;
          } else {
            result += value > 0 ? (value / largest) * (value / largest) : value;
          }
        }
        return largest === Infinity ? Infinity : largest * _sqrt(result);
      },
  
      log2: function log2(value) {
        return _log(value) * LOG2E;
      },
  
      log10: function log10(value) {
        return _log(value) * LOG10E;
      },
  
      log1p: _log1p,
  
      sign: _sign,
  
      sinh: function sinh(value) {
        var x = Number(value);
        if (!globalIsFinite(x) || x === 0) { return x; }
  
        var a = _abs(x);
        if (a < 1) {
          var u = Math.expm1(a);
          return _sign(x) * u * (1 + (1 / (u + 1))) / 2;
        }
        var t = _exp(a - 1);
        return _sign(x) * (t - (1 / (t * E * E))) * (E / 2);
      },
  
      tanh: function tanh(value) {
        var x = Number(value);
        if (numberIsNaN(x) || x === 0) { return x; }
        // can exit early at +-20 as JS loses precision for true value at this integer
        if (x >= 20) { return 1; }
        if (x <= -20) { return -1; }
  
        return (Math.expm1(x) - Math.expm1(-x)) / (_exp(x) + _exp(-x));
      },
  
      trunc: function trunc(value) {
        var x = Number(value);
        return x < 0 ? -_floor(-x) : _floor(x);
      },
  
      imul: function imul(x, y) {
        // taken from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/imul
        var a = ES.ToUint32(x);
        var b = ES.ToUint32(y);
        var ah = (a >>> 16) & 0xffff;
        var al = a & 0xffff;
        var bh = (b >>> 16) & 0xffff;
        var bl = b & 0xffff;
        // the shift by 0 fixes the sign on the high part
        // the final |0 converts the unsigned value into a signed value
        return (al * bl) + ((((ah * bl) + (al * bh)) << 16) >>> 0) | 0;
      },
  
      fround: function fround(x) {
        var v = Number(x);
        if (v === 0 || v === Infinity || v === -Infinity || numberIsNaN(v)) {
          return v;
        }
        var sign = _sign(v);
        var abs = _abs(v);
        if (abs < BINARY_32_MIN_VALUE) {
          return sign * roundTiesToEven(abs / BINARY_32_MIN_VALUE / BINARY_32_EPSILON) * BINARY_32_MIN_VALUE * BINARY_32_EPSILON;
        }
        // Veltkamp's splitting (?)
        var a = (1 + (BINARY_32_EPSILON / Number.EPSILON)) * abs;
        var result = a - (a - abs);
        if (result > BINARY_32_MAX_VALUE || numberIsNaN(result)) {
          return sign * Infinity;
        }
        return sign * result;
      }
    };
  
    var withinULPDistance = function withinULPDistance(result, expected, distance) {
      return _abs(1 - (result / expected)) / Number.EPSILON < (distance || 8);
    };
  
    defineProperties(Math, MathShims);
    // Chrome < 40 sinh returns ∞ for large numbers
    defineProperty(Math, 'sinh', MathShims.sinh, Math.sinh(710) === Infinity);
    // Chrome < 40 cosh returns ∞ for large numbers
    defineProperty(Math, 'cosh', MathShims.cosh, Math.cosh(710) === Infinity);
    // IE 11 TP has an imprecise log1p: reports Math.log1p(-1e-17) as 0
    defineProperty(Math, 'log1p', MathShims.log1p, Math.log1p(-1e-17) !== -1e-17);
    // IE 11 TP has an imprecise asinh: reports Math.asinh(-1e7) as not exactly equal to -Math.asinh(1e7)
    defineProperty(Math, 'asinh', MathShims.asinh, Math.asinh(-1e7) !== -Math.asinh(1e7));
    // Chrome < 54 asinh returns ∞ for large numbers and should not
    defineProperty(Math, 'asinh', MathShims.asinh, Math.asinh(1e+300) === Infinity);
    // Chrome < 54 atanh incorrectly returns 0 for large numbers
    defineProperty(Math, 'atanh', MathShims.atanh, Math.atanh(1e-300) === 0);
    // Chrome 40 has an imprecise Math.tanh with very small numbers
    defineProperty(Math, 'tanh', MathShims.tanh, Math.tanh(-2e-17) !== -2e-17);
    // Chrome 40 loses Math.acosh precision with high numbers
    defineProperty(Math, 'acosh', MathShims.acosh, Math.acosh(Number.MAX_VALUE) === Infinity);
    // Chrome < 54 has an inaccurate acosh for EPSILON deltas
    defineProperty(Math, 'acosh', MathShims.acosh, !withinULPDistance(Math.acosh(1 + Number.EPSILON), Math.sqrt(2 * Number.EPSILON)));
    // Firefox 38 on Windows
    defineProperty(Math, 'cbrt', MathShims.cbrt, !withinULPDistance(Math.cbrt(1e-300), 1e-100));
    // node 0.11 has an imprecise Math.sinh with very small numbers
    defineProperty(Math, 'sinh', MathShims.sinh, Math.sinh(-2e-17) !== -2e-17);
    // FF 35 on Linux reports 22025.465794806725 for Math.expm1(10)
    var expm1OfTen = Math.expm1(10);
    defineProperty(Math, 'expm1', MathShims.expm1, expm1OfTen > 22025.465794806719 || expm1OfTen < 22025.4657948067165168);
  
    var origMathRound = Math.round;
    // breaks in e.g. Safari 8, Internet Explorer 11, Opera 12
    var roundHandlesBoundaryConditions = Math.round(0.5 - (Number.EPSILON / 4)) === 0 &&
      Math.round(-0.5 + (Number.EPSILON / 3.99)) === 1;
  
    // When engines use Math.floor(x + 0.5) internally, Math.round can be buggy for large integers.
    // This behavior should be governed by "round to nearest, ties to even mode"
    // see http://www.ecma-international.org/ecma-262/6.0/#sec-terms-and-definitions-number-type
    // These are the boundary cases where it breaks.
    var smallestPositiveNumberWhereRoundBreaks = inverseEpsilon + 1;
    var largestPositiveNumberWhereRoundBreaks = (2 * inverseEpsilon) - 1;
    var roundDoesNotIncreaseIntegers = [
      smallestPositiveNumberWhereRoundBreaks,
      largestPositiveNumberWhereRoundBreaks
    ].every(function (num) {
      return Math.round(num) === num;
    });
    defineProperty(Math, 'round', function round(x) {
      var floor = _floor(x);
      var ceil = floor === -1 ? -0 : floor + 1;
      return x - floor < 0.5 ? floor : ceil;
    }, !roundHandlesBoundaryConditions || !roundDoesNotIncreaseIntegers);
    Value.preserveToString(Math.round, origMathRound);
  
    var origImul = Math.imul;
    if (Math.imul(0xffffffff, 5) !== -5) {
      // Safari 6.1, at least, reports "0" for this value
      Math.imul = MathShims.imul;
      Value.preserveToString(Math.imul, origImul);
    }
    if (Math.imul.length !== 2) {
      // Safari 8.0.4 has a length of 1
      // fixed in https://bugs.webkit.org/show_bug.cgi?id=143658
      overrideNative(Math, 'imul', function imul(x, y) {
        return ES.Call(origImul, Math, arguments);
      });
    }
  
  // ##### BEGIN: MODIFIED BY SAP
  //   // Promises
  //   // Simplest possible implementation; use a 3rd-party library if you
  //   // want the best possible speed and/or long stack traces.
  //   var PromiseShim = (function () {
  //     var setTimeout = globals.setTimeout;
  //     // some environments don't have setTimeout - no way to shim here.
  //     if (typeof setTimeout !== 'function' && typeof setTimeout !== 'object') { return; }
  
  //     ES.IsPromise = function (promise) {
  //       if (!ES.TypeIsObject(promise)) {
  //         return false;
  //       }
  //       if (typeof promise._promise === 'undefined') {
  //         return false; // uninitialized, or missing our hidden field.
  //       }
  //       return true;
  //     };
  
  //     // "PromiseCapability" in the spec is what most promise implementations
  //     // call a "deferred".
  //     var PromiseCapability = function (C) {
  //       if (!ES.IsConstructor(C)) {
  //         throw new TypeError('Bad promise constructor');
  //       }
  //       var capability = this;
  //       var resolver = function (resolve, reject) {
  //         if (capability.resolve !== void 0 || capability.reject !== void 0) {
  //           throw new TypeError('Bad Promise implementation!');
  //         }
  //         capability.resolve = resolve;
  //         capability.reject = reject;
  //       };
  //       // Initialize fields to inform optimizers about the object shape.
  //       capability.resolve = void 0;
  //       capability.reject = void 0;
  //       capability.promise = new C(resolver);
  //       if (!(ES.IsCallable(capability.resolve) && ES.IsCallable(capability.reject))) {
  //         throw new TypeError('Bad promise constructor');
  //       }
  //     };
  
  //     // find an appropriate setImmediate-alike
  //     var makeZeroTimeout;
  //     /*global window */
  //     if (typeof window !== 'undefined' && ES.IsCallable(window.postMessage)) {
  //       makeZeroTimeout = function () {
  //         // from http://dbaron.org/log/20100309-faster-timeouts
  //         var timeouts = [];
  //         var messageName = 'zero-timeout-message';
  //         var setZeroTimeout = function (fn) {
  //           _push(timeouts, fn);
  //           window.postMessage(messageName, '*');
  //         };
  //         var handleMessage = function (event) {
  //           if (event.source === window && event.data === messageName) {
  //             event.stopPropagation();
  //             if (timeouts.length === 0) { return; }
  //             var fn = _shift(timeouts);
  //             fn();
  //           }
  //         };
  //         window.addEventListener('message', handleMessage, true);
  //         return setZeroTimeout;
  //       };
  //     }
  //     var makePromiseAsap = function () {
  //       // An efficient task-scheduler based on a pre-existing Promise
  //       // implementation, which we can use even if we override the
  //       // global Promise below (in order to workaround bugs)
  //       // https://github.com/Raynos/observ-hash/issues/2#issuecomment-35857671
  //       var P = globals.Promise;
  //       var pr = P && P.resolve && P.resolve();
  //       return pr && function (task) {
  //         return pr.then(task);
  //       };
  //     };
  //     /*global process */
  //     /* jscs:disable disallowMultiLineTernary */
  //     var enqueue = ES.IsCallable(globals.setImmediate) ?
  //       globals.setImmediate :
  //       typeof process === 'object' && process.nextTick ? process.nextTick : makePromiseAsap() ||
  //       (ES.IsCallable(makeZeroTimeout) ? makeZeroTimeout() : function (task) { setTimeout(task, 0); }); // fallback
  //     /* jscs:enable disallowMultiLineTernary */
  
  //     // Constants for Promise implementation
  //     var PROMISE_IDENTITY = function (x) { return x; };
  //     var PROMISE_THROWER = function (e) { throw e; };
  //     var PROMISE_PENDING = 0;
  //     var PROMISE_FULFILLED = 1;
  //     var PROMISE_REJECTED = 2;
  //     // We store fulfill/reject handlers and capabilities in a single array.
  //     var PROMISE_FULFILL_OFFSET = 0;
  //     var PROMISE_REJECT_OFFSET = 1;
  //     var PROMISE_CAPABILITY_OFFSET = 2;
  //     // This is used in an optimization for chaining promises via then.
  //     var PROMISE_FAKE_CAPABILITY = {};
  
  //     var enqueuePromiseReactionJob = function (handler, capability, argument) {
  //       enqueue(function () {
  //         promiseReactionJob(handler, capability, argument);
  //       });
  //     };
  
  //     var promiseReactionJob = function (handler, promiseCapability, argument) {
  //       var handlerResult, f;
  //       if (promiseCapability === PROMISE_FAKE_CAPABILITY) {
  //         // Fast case, when we don't actually need to chain through to a
  //         // (real) promiseCapability.
  //         return handler(argument);
  //       }
  //       try {
  //         handlerResult = handler(argument);
  //         f = promiseCapability.resolve;
  //       } catch (e) {
  //         handlerResult = e;
  //         f = promiseCapability.reject;
  //       }
  //       f(handlerResult);
  //     };
  
  //     var fulfillPromise = function (promise, value) {
  //       var _promise = promise._promise;
  //       var length = _promise.reactionLength;
  //       if (length > 0) {
  //         enqueuePromiseReactionJob(
  //           _promise.fulfillReactionHandler0,
  //           _promise.reactionCapability0,
  //           value
  //         );
  //         _promise.fulfillReactionHandler0 = void 0;
  //         _promise.rejectReactions0 = void 0;
  //         _promise.reactionCapability0 = void 0;
  //         if (length > 1) {
  //           for (var i = 1, idx = 0; i < length; i++, idx += 3) {
  //             enqueuePromiseReactionJob(
  //               _promise[idx + PROMISE_FULFILL_OFFSET],
  //               _promise[idx + PROMISE_CAPABILITY_OFFSET],
  //               value
  //             );
  //             promise[idx + PROMISE_FULFILL_OFFSET] = void 0;
  //             promise[idx + PROMISE_REJECT_OFFSET] = void 0;
  //             promise[idx + PROMISE_CAPABILITY_OFFSET] = void 0;
  //           }
  //         }
  //       }
  //       _promise.result = value;
  //       _promise.state = PROMISE_FULFILLED;
  //       _promise.reactionLength = 0;
  //     };
  
  //     var rejectPromise = function (promise, reason) {
  //       var _promise = promise._promise;
  //       var length = _promise.reactionLength;
  //       if (length > 0) {
  //         enqueuePromiseReactionJob(
  //           _promise.rejectReactionHandler0,
  //           _promise.reactionCapability0,
  //           reason
  //         );
  //         _promise.fulfillReactionHandler0 = void 0;
  //         _promise.rejectReactions0 = void 0;
  //         _promise.reactionCapability0 = void 0;
  //         if (length > 1) {
  //           for (var i = 1, idx = 0; i < length; i++, idx += 3) {
  //             enqueuePromiseReactionJob(
  //               _promise[idx + PROMISE_REJECT_OFFSET],
  //               _promise[idx + PROMISE_CAPABILITY_OFFSET],
  //               reason
  //             );
  //             promise[idx + PROMISE_FULFILL_OFFSET] = void 0;
  //             promise[idx + PROMISE_REJECT_OFFSET] = void 0;
  //             promise[idx + PROMISE_CAPABILITY_OFFSET] = void 0;
  //           }
  //         }
  //       }
  //       _promise.result = reason;
  //       _promise.state = PROMISE_REJECTED;
  //       _promise.reactionLength = 0;
  //     };
  
  //     var createResolvingFunctions = function (promise) {
  //       var alreadyResolved = false;
  //       var resolve = function (resolution) {
  //         var then;
  //         if (alreadyResolved) { return; }
  //         alreadyResolved = true;
  //         if (resolution === promise) {
  //           return rejectPromise(promise, new TypeError('Self resolution'));
  //         }
  //         if (!ES.TypeIsObject(resolution)) {
  //           return fulfillPromise(promise, resolution);
  //         }
  //         try {
  //           then = resolution.then;
  //         } catch (e) {
  //           return rejectPromise(promise, e);
  //         }
  //         if (!ES.IsCallable(then)) {
  //           return fulfillPromise(promise, resolution);
  //         }
  //         enqueue(function () {
  //           promiseResolveThenableJob(promise, resolution, then);
  //         });
  //       };
  //       var reject = function (reason) {
  //         if (alreadyResolved) { return; }
  //         alreadyResolved = true;
  //         return rejectPromise(promise, reason);
  //       };
  //       return { resolve: resolve, reject: reject };
  //     };
  
  //     var optimizedThen = function (then, thenable, resolve, reject) {
  //       // Optimization: since we discard the result, we can pass our
  //       // own then implementation a special hint to let it know it
  //       // doesn't have to create it.  (The PROMISE_FAKE_CAPABILITY
  //       // object is local to this implementation and unforgeable outside.)
  //       if (then === Promise$prototype$then) {
  //         _call(then, thenable, resolve, reject, PROMISE_FAKE_CAPABILITY);
  //       } else {
  //         _call(then, thenable, resolve, reject);
  //       }
  //     };
  //     var promiseResolveThenableJob = function (promise, thenable, then) {
  //       var resolvingFunctions = createResolvingFunctions(promise);
  //       var resolve = resolvingFunctions.resolve;
  //       var reject = resolvingFunctions.reject;
  //       try {
  //         optimizedThen(then, thenable, resolve, reject);
  //       } catch (e) {
  //         reject(e);
  //       }
  //     };
  
  //     var Promise$prototype, Promise$prototype$then;
  //     var Promise = (function () {
  //       var PromiseShim = function Promise(resolver) {
  //         if (!(this instanceof PromiseShim)) {
  //           throw new TypeError('Constructor Promise requires "new"');
  //         }
  //         if (this && this._promise) {
  //           throw new TypeError('Bad construction');
  //         }
  //         // see https://bugs.ecmascript.org/show_bug.cgi?id=2482
  //         if (!ES.IsCallable(resolver)) {
  //           throw new TypeError('not a valid resolver');
  //         }
  //         var promise = emulateES6construct(this, PromiseShim, Promise$prototype, {
  //           _promise: {
  //             result: void 0,
  //             state: PROMISE_PENDING,
  //             // The first member of the "reactions" array is inlined here,
  //             // since most promises only have one reaction.
  //             // We've also exploded the 'reaction' object to inline the
  //             // "handler" and "capability" fields, since both fulfill and
  //             // reject reactions share the same capability.
  //             reactionLength: 0,
  //             fulfillReactionHandler0: void 0,
  //             rejectReactionHandler0: void 0,
  //             reactionCapability0: void 0
  //           }
  //         });
  //         var resolvingFunctions = createResolvingFunctions(promise);
  //         var reject = resolvingFunctions.reject;
  //         try {
  //           resolver(resolvingFunctions.resolve, reject);
  //         } catch (e) {
  //           reject(e);
  //         }
  //         return promise;
  //       };
  //       return PromiseShim;
  //     }());
  //     Promise$prototype = Promise.prototype;
  
  //     var _promiseAllResolver = function (index, values, capability, remaining) {
  //       var alreadyCalled = false;
  //       return function (x) {
  //         if (alreadyCalled) { return; }
  //         alreadyCalled = true;
  //         values[index] = x;
  //         if ((--remaining.count) === 0) {
  //           var resolve = capability.resolve;
  //           resolve(values); // call w/ this===undefined
  //         }
  //       };
  //     };
  
  //     var performPromiseAll = function (iteratorRecord, C, resultCapability) {
  //       var it = iteratorRecord.iterator;
  //       var values = [];
  //       var remaining = { count: 1 };
  //       var next, nextValue;
  //       var index = 0;
  //       while (true) {
  //         try {
  //           next = ES.IteratorStep(it);
  //           if (next === false) {
  //             iteratorRecord.done = true;
  //             break;
  //           }
  //           nextValue = next.value;
  //         } catch (e) {
  //           iteratorRecord.done = true;
  //           throw e;
  //         }
  //         values[index] = void 0;
  //         var nextPromise = C.resolve(nextValue);
  //         var resolveElement = _promiseAllResolver(
  //           index,
  //           values,
  //           resultCapability,
  //           remaining
  //         );
  //         remaining.count += 1;
  //         optimizedThen(nextPromise.then, nextPromise, resolveElement, resultCapability.reject);
  //         index += 1;
  //       }
  //       if ((--remaining.count) === 0) {
  //         var resolve = resultCapability.resolve;
  //         resolve(values); // call w/ this===undefined
  //       }
  //       return resultCapability.promise;
  //     };
  
  //     var performPromiseRace = function (iteratorRecord, C, resultCapability) {
  //       var it = iteratorRecord.iterator;
  //       var next, nextValue, nextPromise;
  //       while (true) {
  //         try {
  //           next = ES.IteratorStep(it);
  //           if (next === false) {
  //             // NOTE: If iterable has no items, resulting promise will never
  //             // resolve; see:
  //             // https://github.com/domenic/promises-unwrapping/issues/75
  //             // https://bugs.ecmascript.org/show_bug.cgi?id=2515
  //             iteratorRecord.done = true;
  //             break;
  //           }
  //           nextValue = next.value;
  //         } catch (e) {
  //           iteratorRecord.done = true;
  //           throw e;
  //         }
  //         nextPromise = C.resolve(nextValue);
  //         optimizedThen(nextPromise.then, nextPromise, resultCapability.resolve, resultCapability.reject);
  //       }
  //       return resultCapability.promise;
  //     };
  
  //     defineProperties(Promise, {
  //       all: function all(iterable) {
  //         var C = this;
  //         if (!ES.TypeIsObject(C)) {
  //           throw new TypeError('Promise is not object');
  //         }
  //         var capability = new PromiseCapability(C);
  //         var iterator, iteratorRecord;
  //         try {
  //           iterator = ES.GetIterator(iterable);
  //           iteratorRecord = { iterator: iterator, done: false };
  //           return performPromiseAll(iteratorRecord, C, capability);
  //         } catch (e) {
  //           var exception = e;
  //           if (iteratorRecord && !iteratorRecord.done) {
  //             try {
  //               ES.IteratorClose(iterator, true);
  //             } catch (ee) {
  //               exception = ee;
  //             }
  //           }
  //           var reject = capability.reject;
  //           reject(exception);
  //           return capability.promise;
  //         }
  //       },
  
  //       race: function race(iterable) {
  //         var C = this;
  //         if (!ES.TypeIsObject(C)) {
  //           throw new TypeError('Promise is not object');
  //         }
  //         var capability = new PromiseCapability(C);
  //         var iterator, iteratorRecord;
  //         try {
  //           iterator = ES.GetIterator(iterable);
  //           iteratorRecord = { iterator: iterator, done: false };
  //           return performPromiseRace(iteratorRecord, C, capability);
  //         } catch (e) {
  //           var exception = e;
  //           if (iteratorRecord && !iteratorRecord.done) {
  //             try {
  //               ES.IteratorClose(iterator, true);
  //             } catch (ee) {
  //               exception = ee;
  //             }
  //           }
  //           var reject = capability.reject;
  //           reject(exception);
  //           return capability.promise;
  //         }
  //       },
  
  //       reject: function reject(reason) {
  //         var C = this;
  //         if (!ES.TypeIsObject(C)) {
  //           throw new TypeError('Bad promise constructor');
  //         }
  //         var capability = new PromiseCapability(C);
  //         var rejectFunc = capability.reject;
  //         rejectFunc(reason); // call with this===undefined
  //         return capability.promise;
  //       },
  
  //       resolve: function resolve(v) {
  //         // See https://esdiscuss.org/topic/fixing-promise-resolve for spec
  //         var C = this;
  //         if (!ES.TypeIsObject(C)) {
  //           throw new TypeError('Bad promise constructor');
  //         }
  //         if (ES.IsPromise(v)) {
  //           var constructor = v.constructor;
  //           if (constructor === C) {
  //             return v;
  //           }
  //         }
  //         var capability = new PromiseCapability(C);
  //         var resolveFunc = capability.resolve;
  //         resolveFunc(v); // call with this===undefined
  //         return capability.promise;
  //       }
  //     });
  
  //     defineProperties(Promise$prototype, {
  //       'catch': function (onRejected) {
  //         return this.then(null, onRejected);
  //       },
  
  //       then: function then(onFulfilled, onRejected) {
  //         var promise = this;
  //         if (!ES.IsPromise(promise)) { throw new TypeError('not a promise'); }
  //         var C = ES.SpeciesConstructor(promise, Promise);
  //         var resultCapability;
  //         var returnValueIsIgnored = arguments.length > 2 && arguments[2] === PROMISE_FAKE_CAPABILITY;
  //         if (returnValueIsIgnored && C === Promise) {
  //           resultCapability = PROMISE_FAKE_CAPABILITY;
  //         } else {
  //           resultCapability = new PromiseCapability(C);
  //         }
  //         // PerformPromiseThen(promise, onFulfilled, onRejected, resultCapability)
  //         // Note that we've split the 'reaction' object into its two
  //         // components, "capabilities" and "handler"
  //         // "capabilities" is always equal to `resultCapability`
  //         var fulfillReactionHandler = ES.IsCallable(onFulfilled) ? onFulfilled : PROMISE_IDENTITY;
  //         var rejectReactionHandler = ES.IsCallable(onRejected) ? onRejected : PROMISE_THROWER;
  //         var _promise = promise._promise;
  //         var value;
  //         if (_promise.state === PROMISE_PENDING) {
  //           if (_promise.reactionLength === 0) {
  //             _promise.fulfillReactionHandler0 = fulfillReactionHandler;
  //             _promise.rejectReactionHandler0 = rejectReactionHandler;
  //             _promise.reactionCapability0 = resultCapability;
  //           } else {
  //             var idx = 3 * (_promise.reactionLength - 1);
  //             _promise[idx + PROMISE_FULFILL_OFFSET] = fulfillReactionHandler;
  //             _promise[idx + PROMISE_REJECT_OFFSET] = rejectReactionHandler;
  //             _promise[idx + PROMISE_CAPABILITY_OFFSET] = resultCapability;
  //           }
  //           _promise.reactionLength += 1;
  //         } else if (_promise.state === PROMISE_FULFILLED) {
  //           value = _promise.result;
  //           enqueuePromiseReactionJob(
  //             fulfillReactionHandler,
  //             resultCapability,
  //             value
  //           );
  //         } else if (_promise.state === PROMISE_REJECTED) {
  //           value = _promise.result;
  //           enqueuePromiseReactionJob(
  //             rejectReactionHandler,
  //             resultCapability,
  //             value
  //           );
  //         } else {
  //           throw new TypeError('unexpected Promise state');
  //         }
  //         return resultCapability.promise;
  //       }
  //     });
  //     // This helps the optimizer by ensuring that methods which take
  //     // capabilities aren't polymorphic.
  //     PROMISE_FAKE_CAPABILITY = new PromiseCapability(Promise);
  //     Promise$prototype$then = Promise$prototype.then;
  
  //     return Promise;
  //   }());
  
  //   // Chrome's native Promise has extra methods that it shouldn't have. Let's remove them.
  //   if (globals.Promise) {
  //     delete globals.Promise.accept;
  //     delete globals.Promise.defer;
  //     delete globals.Promise.prototype.chain;
  //   }
  
  //   if (typeof PromiseShim === 'function') {
  //     // export the Promise constructor.
  //     defineProperties(globals, { Promise: PromiseShim });
  //     // In Chrome 33 (and thereabouts) Promise is defined, but the
  //     // implementation is buggy in a number of ways.  Let's check subclassing
  //     // support to see if we have a buggy implementation.
  //     var promiseSupportsSubclassing = supportsSubclassing(globals.Promise, function (S) {
  //       return S.resolve(42).then(function () {}) instanceof S;
  //     });
  //     var promiseIgnoresNonFunctionThenCallbacks = !throwsError(function () {
  //       return globals.Promise.reject(42).then(null, 5).then(null, noop);
  //     });
  //     var promiseRequiresObjectContext = throwsError(function () { return globals.Promise.call(3, noop); });
  //     // Promise.resolve() was errata'ed late in the ES6 process.
  //     // See: https://bugzilla.mozilla.org/show_bug.cgi?id=1170742
  //     //      https://code.google.com/p/v8/issues/detail?id=4161
  //     // It serves as a proxy for a number of other bugs in early Promise
  //     // implementations.
  //     var promiseResolveBroken = (function (Promise) {
  //       var p = Promise.resolve(5);
  //       p.constructor = {};
  //       var p2 = Promise.resolve(p);
  //       try {
  //         p2.then(null, noop).then(null, noop); // avoid "uncaught rejection" warnings in console
  //       } catch (e) {
  //         return true; // v8 native Promises break here https://code.google.com/p/chromium/issues/detail?id=575314
  //       }
  //       return p === p2; // This *should* be false!
  //     }(globals.Promise));
  
  //     // Chrome 46 (probably older too) does not retrieve a thenable's .then synchronously
  //     var getsThenSynchronously = supportsDescriptors && (function () {
  //       var count = 0;
  //       // eslint-disable-next-line getter-return
  //       var thenable = Object.defineProperty({}, 'then', { get: function () { count += 1; } });
  //       Promise.resolve(thenable);
  //       return count === 1;
  //     }());
  
  //     var BadResolverPromise = function BadResolverPromise(executor) {
  //       var p = new Promise(executor);
  //       executor(3, function () {});
  //       this.then = p.then;
  //       this.constructor = BadResolverPromise;
  //     };
  //     BadResolverPromise.prototype = Promise.prototype;
  //     BadResolverPromise.all = Promise.all;
  //     // Chrome Canary 49 (probably older too) has some implementation bugs
  //     var hasBadResolverPromise = valueOrFalseIfThrows(function () {
  //       return !!BadResolverPromise.all([1, 2]);
  //     });
  
  //     if (!promiseSupportsSubclassing || !promiseIgnoresNonFunctionThenCallbacks ||
  //         !promiseRequiresObjectContext || promiseResolveBroken ||
  //         !getsThenSynchronously || hasBadResolverPromise) {
  //       /* globals Promise: true */
  //       /* eslint-disable no-undef, no-global-assign */
  //       /* jshint -W020 */
  //       Promise = PromiseShim;
  //       /* jshint +W020 */
  //       /* eslint-enable no-undef, no-global-assign */
  //       /* globals Promise: false */
  //       overrideNative(globals, 'Promise', PromiseShim);
  //     }
  //     if (Promise.all.length !== 1) {
  //       var origAll = Promise.all;
  //       overrideNative(Promise, 'all', function all(iterable) {
  //         return ES.Call(origAll, this, arguments);
  //       });
  //     }
  //     if (Promise.race.length !== 1) {
  //       var origRace = Promise.race;
  //       overrideNative(Promise, 'race', function race(iterable) {
  //         return ES.Call(origRace, this, arguments);
  //       });
  //     }
  //     if (Promise.resolve.length !== 1) {
  //       var origResolve = Promise.resolve;
  //       overrideNative(Promise, 'resolve', function resolve(x) {
  //         return ES.Call(origResolve, this, arguments);
  //       });
  //     }
  //     if (Promise.reject.length !== 1) {
  //       var origReject = Promise.reject;
  //       overrideNative(Promise, 'reject', function reject(r) {
  //         return ES.Call(origReject, this, arguments);
  //       });
  //     }
  //     ensureEnumerable(Promise, 'all');
  //     ensureEnumerable(Promise, 'race');
  //     ensureEnumerable(Promise, 'resolve');
  //     ensureEnumerable(Promise, 'reject');
  //     addDefaultSpecies(Promise);
  //   }
  // ##### END: MODIFIED BY SAP
  
    // Map and Set require a true ES5 environment
    // Their fast path also requires that the environment preserve
    // property insertion order, which is not guaranteed by the spec.
    var testOrder = function (a) {
      var b = keys(_reduce(a, function (o, k) {
        o[k] = true;
        return o;
      }, {}));
      return a.join(':') === b.join(':');
    };
    var preservesInsertionOrder = testOrder(['z', 'a', 'bb']);
    // some engines (eg, Chrome) only preserve insertion order for string keys
    var preservesNumericInsertionOrder = testOrder(['z', 1, 'a', '3', 2]);
  
    if (supportsDescriptors) {
  
      var fastkey = function fastkey(key, skipInsertionOrderCheck) {
        if (!skipInsertionOrderCheck && !preservesInsertionOrder) {
          return null;
        }
        if (isNullOrUndefined(key)) {
          return '^' + ES.ToString(key);
        } else if (typeof key === 'string') {
          return '$' + key;
        } else if (typeof key === 'number') {
          // note that -0 will get coerced to "0" when used as a property key
          if (!preservesNumericInsertionOrder) {
            return 'n' + key;
          }
          return key;
        } else if (typeof key === 'boolean') {
          return 'b' + key;
        }
        return null;
      };
  
      var emptyObject = function emptyObject() {
        // accomodate some older not-quite-ES5 browsers
        return Object.create ? Object.create(null) : {};
      };
  
      var addIterableToMap = function addIterableToMap(MapConstructor, map, iterable) {
        if (isArray(iterable) || Type.string(iterable)) {
          _forEach(iterable, function (entry) {
            if (!ES.TypeIsObject(entry)) {
              throw new TypeError('Iterator value ' + entry + ' is not an entry object');
            }
            map.set(entry[0], entry[1]);
          });
        } else if (iterable instanceof MapConstructor) {
          _call(MapConstructor.prototype.forEach, iterable, function (value, key) {
            map.set(key, value);
          });
        } else {
          var iter, adder;
          if (!isNullOrUndefined(iterable)) {
            adder = map.set;
            if (!ES.IsCallable(adder)) { throw new TypeError('bad map'); }
            iter = ES.GetIterator(iterable);
          }
          if (typeof iter !== 'undefined') {
            while (true) {
              var next = ES.IteratorStep(iter);
              if (next === false) { break; }
              var nextItem = next.value;
              try {
                if (!ES.TypeIsObject(nextItem)) {
                  throw new TypeError('Iterator value ' + nextItem + ' is not an entry object');
                }
                _call(adder, map, nextItem[0], nextItem[1]);
              } catch (e) {
                ES.IteratorClose(iter, true);
                throw e;
              }
            }
          }
        }
      };
      var addIterableToSet = function addIterableToSet(SetConstructor, set, iterable) {
        if (isArray(iterable) || Type.string(iterable)) {
          _forEach(iterable, function (value) {
            set.add(value);
          });
        } else if (iterable instanceof SetConstructor) {
          _call(SetConstructor.prototype.forEach, iterable, function (value) {
            set.add(value);
          });
        } else {
          var iter, adder;
          if (!isNullOrUndefined(iterable)) {
            adder = set.add;
            if (!ES.IsCallable(adder)) { throw new TypeError('bad set'); }
            iter = ES.GetIterator(iterable);
          }
          if (typeof iter !== 'undefined') {
            while (true) {
              var next = ES.IteratorStep(iter);
              if (next === false) { break; }
              var nextValue = next.value;
              try {
                _call(adder, set, nextValue);
              } catch (e) {
                ES.IteratorClose(iter, true);
                throw e;
              }
            }
          }
        }
      };
  
      var collectionShims = {
        Map: (function () {
  
          var empty = {};
  
          var MapEntry = function MapEntry(key, value) {
            this.key = key;
            this.value = value;
            this.next = null;
            this.prev = null;
          };
  
          MapEntry.prototype.isRemoved = function isRemoved() {
            return this.key === empty;
          };
  
          var isMap = function isMap(map) {
            return !!map._es6map;
          };
  
          var requireMapSlot = function requireMapSlot(map, method) {
            if (!ES.TypeIsObject(map) || !isMap(map)) {
              throw new TypeError('Method Map.prototype.' + method + ' called on incompatible receiver ' + ES.ToString(map));
            }
          };
  
          var MapIterator = function MapIterator(map, kind) {
            requireMapSlot(map, '[[MapIterator]]');
            this.head = map._head;
            this.i = this.head;
            this.kind = kind;
          };
  
          MapIterator.prototype = {
            isMapIterator: true,
            next: function next() {
              if (!this.isMapIterator) {
                throw new TypeError('Not a MapIterator');
              }
              var i = this.i;
              var kind = this.kind;
              var head = this.head;
              if (typeof this.i === 'undefined') {
                return iteratorResult();
              }
              while (i.isRemoved() && i !== head) {
                // back up off of removed entries
                i = i.prev;
              }
              // advance to next unreturned element.
              var result;
              while (i.next !== head) {
                i = i.next;
                if (!i.isRemoved()) {
                  if (kind === 'key') {
                    result = i.key;
                  } else if (kind === 'value') {
                    result = i.value;
                  } else {
                    result = [i.key, i.value];
                  }
                  this.i = i;
                  return iteratorResult(result);
                }
              }
              // once the iterator is done, it is done forever.
              this.i = void 0;
              return iteratorResult();
            }
          };
          addIterator(MapIterator.prototype);
  
          var Map$prototype;
          var MapShim = function Map() {
            if (!(this instanceof Map)) {
              throw new TypeError('Constructor Map requires "new"');
            }
            if (this && this._es6map) {
              throw new TypeError('Bad construction');
            }
            var map = emulateES6construct(this, Map, Map$prototype, {
              _es6map: true,
              _head: null,
              _map: OrigMap ? new OrigMap() : null,
              _size: 0,
              _storage: emptyObject()
            });
  
            var head = new MapEntry(null, null);
            // circular doubly-linked list.
            /* eslint no-multi-assign: 1 */
            head.next = head.prev = head;
            map._head = head;
  
            // Optionally initialize map from iterable
            if (arguments.length > 0) {
              addIterableToMap(Map, map, arguments[0]);
            }
            return map;
          };
          Map$prototype = MapShim.prototype;
  
          Value.getter(Map$prototype, 'size', function () {
            if (typeof this._size === 'undefined') {
              throw new TypeError('size method called on incompatible Map');
            }
            return this._size;
          });
  
          defineProperties(Map$prototype, {
            get: function get(key) {
              requireMapSlot(this, 'get');
              var entry;
              var fkey = fastkey(key, true);
              if (fkey !== null) {
                // fast O(1) path
                entry = this._storage[fkey];
                if (entry) {
                  return entry.value;
                } else {
                  return;
                }
              }
              if (this._map) {
                // fast object key path
                entry = origMapGet.call(this._map, key);
                if (entry) {
                  return entry.value;
                } else {
                  return;
                }
              }
              var head = this._head;
              var i = head;
              while ((i = i.next) !== head) {
                if (ES.SameValueZero(i.key, key)) {
                  return i.value;
                }
              }
            },
  
            has: function has(key) {
              requireMapSlot(this, 'has');
              var fkey = fastkey(key, true);
              if (fkey !== null) {
                // fast O(1) path
                return typeof this._storage[fkey] !== 'undefined';
              }
              if (this._map) {
                // fast object key path
                return origMapHas.call(this._map, key);
              }
              var head = this._head;
              var i = head;
              while ((i = i.next) !== head) {
                if (ES.SameValueZero(i.key, key)) {
                  return true;
                }
              }
              return false;
            },
  
            set: function set(key, value) {
              requireMapSlot(this, 'set');
              var head = this._head;
              var i = head;
              var entry;
              var fkey = fastkey(key, true);
              if (fkey !== null) {
                // fast O(1) path
                if (typeof this._storage[fkey] !== 'undefined') {
                  this._storage[fkey].value = value;
                  return this;
                } else {
                  entry = this._storage[fkey] = new MapEntry(key, value); /* eslint no-multi-assign: 1 */
                  i = head.prev;
                  // fall through
                }
              } else if (this._map) {
                // fast object key path
                if (origMapHas.call(this._map, key)) {
                  origMapGet.call(this._map, key).value = value;
                } else {
                  entry = new MapEntry(key, value);
                  origMapSet.call(this._map, key, entry);
                  i = head.prev;
                  // fall through
                }
              }
              while ((i = i.next) !== head) {
                if (ES.SameValueZero(i.key, key)) {
                  i.value = value;
                  return this;
                }
              }
              entry = entry || new MapEntry(key, value);
              if (ES.SameValue(-0, key)) {
                entry.key = +0; // coerce -0 to +0 in entry
              }
              entry.next = this._head;
              entry.prev = this._head.prev;
              entry.prev.next = entry;
              entry.next.prev = entry;
              this._size += 1;
              return this;
            },
  
            'delete': function (key) {
              requireMapSlot(this, 'delete');
              var head = this._head;
              var i = head;
              var fkey = fastkey(key, true);
              if (fkey !== null) {
                // fast O(1) path
                if (typeof this._storage[fkey] === 'undefined') {
                  return false;
                }
                i = this._storage[fkey].prev;
                delete this._storage[fkey];
                // fall through
              } else if (this._map) {
                // fast object key path
                if (!origMapHas.call(this._map, key)) {
                  return false;
                }
                i = origMapGet.call(this._map, key).prev;
                origMapDelete.call(this._map, key);
                // fall through
              }
              while ((i = i.next) !== head) {
                if (ES.SameValueZero(i.key, key)) {
                  i.key = empty;
                  i.value = empty;
                  i.prev.next = i.next;
                  i.next.prev = i.prev;
                  this._size -= 1;
                  return true;
                }
              }
              return false;
            },
  
            clear: function clear() {
              /* eslint no-multi-assign: 1 */
              requireMapSlot(this, 'clear');
              this._map = OrigMap ? new OrigMap() : null;
              this._size = 0;
              this._storage = emptyObject();
              var head = this._head;
              var i = head;
              var p = i.next;
              while ((i = p) !== head) {
                i.key = empty;
                i.value = empty;
                p = i.next;
                i.next = i.prev = head;
              }
              head.next = head.prev = head;
            },
  
            keys: function keys() {
              requireMapSlot(this, 'keys');
              return new MapIterator(this, 'key');
            },
  
            values: function values() {
              requireMapSlot(this, 'values');
              return new MapIterator(this, 'value');
            },
  
            entries: function entries() {
              requireMapSlot(this, 'entries');
              return new MapIterator(this, 'key+value');
            },
  
            forEach: function forEach(callback) {
              requireMapSlot(this, 'forEach');
              var context = arguments.length > 1 ? arguments[1] : null;
              var it = this.entries();
              for (var entry = it.next(); !entry.done; entry = it.next()) {
                if (context) {
                  _call(callback, context, entry.value[1], entry.value[0], this);
                } else {
                  callback(entry.value[1], entry.value[0], this);
                }
              }
            }
          });
          addIterator(Map$prototype, Map$prototype.entries);
  
          return MapShim;
        }()),
  
        Set: (function () {
          var isSet = function isSet(set) {
            return set._es6set && typeof set._storage !== 'undefined';
          };
          var requireSetSlot = function requireSetSlot(set, method) {
            if (!ES.TypeIsObject(set) || !isSet(set)) {
              // https://github.com/paulmillr/es6-shim/issues/176
              throw new TypeError('Set.prototype.' + method + ' called on incompatible receiver ' + ES.ToString(set));
            }
          };
  
          // Creating a Map is expensive.  To speed up the common case of
          // Sets containing only string or numeric keys, we use an object
          // as backing storage and lazily create a full Map only when
          // required.
          var Set$prototype;
          var SetShim = function Set() {
            if (!(this instanceof Set)) {
              throw new TypeError('Constructor Set requires "new"');
            }
            if (this && this._es6set) {
              throw new TypeError('Bad construction');
            }
            var set = emulateES6construct(this, Set, Set$prototype, {
              _es6set: true,
              '[[SetData]]': null,
              _storage: emptyObject()
            });
            if (!set._es6set) {
              throw new TypeError('bad set');
            }
  
            // Optionally initialize Set from iterable
            if (arguments.length > 0) {
              addIterableToSet(Set, set, arguments[0]);
            }
            return set;
          };
          Set$prototype = SetShim.prototype;
  
          var decodeKey = function (key) {
            var k = key;
            if (k === '^null') {
              return null;
            } else if (k === '^undefined') {
              return void 0;
            } else {
              var first = k.charAt(0);
              if (first === '$') {
                return _strSlice(k, 1);
              } else if (first === 'n') {
                return +_strSlice(k, 1);
              } else if (first === 'b') {
                return k === 'btrue';
              }
            }
            return +k;
          };
          // Switch from the object backing storage to a full Map.
          var ensureMap = function ensureMap(set) {
            if (!set['[[SetData]]']) {
              var m = new collectionShims.Map();
              set['[[SetData]]'] = m;
              _forEach(keys(set._storage), function (key) {
                var k = decodeKey(key);
                m.set(k, k);
              });
              set['[[SetData]]'] = m;
            }
            set._storage = null; // free old backing storage
          };
  
          Value.getter(SetShim.prototype, 'size', function () {
            requireSetSlot(this, 'size');
            if (this._storage) {
              return keys(this._storage).length;
            }
            ensureMap(this);
            return this['[[SetData]]'].size;
          });
  
          defineProperties(SetShim.prototype, {
            has: function has(key) {
              requireSetSlot(this, 'has');
              var fkey;
              if (this._storage && (fkey = fastkey(key)) !== null) {
                return !!this._storage[fkey];
              }
              ensureMap(this);
              return this['[[SetData]]'].has(key);
            },
  
            add: function add(key) {
              requireSetSlot(this, 'add');
              var fkey;
              if (this._storage && (fkey = fastkey(key)) !== null) {
                this._storage[fkey] = true;
                return this;
              }
              ensureMap(this);
              this['[[SetData]]'].set(key, key);
              return this;
            },
  
            'delete': function (key) {
              requireSetSlot(this, 'delete');
              var fkey;
              if (this._storage && (fkey = fastkey(key)) !== null) {
                var hasFKey = _hasOwnProperty(this._storage, fkey);
                return (delete this._storage[fkey]) && hasFKey;
              }
              ensureMap(this);
              return this['[[SetData]]']['delete'](key);
            },
  
            clear: function clear() {
              requireSetSlot(this, 'clear');
              if (this._storage) {
                this._storage = emptyObject();
              }
              if (this['[[SetData]]']) {
                this['[[SetData]]'].clear();
              }
            },
  
            values: function values() {
              requireSetSlot(this, 'values');
              ensureMap(this);
              return new SetIterator(this['[[SetData]]'].values());
            },
  
            entries: function entries() {
              requireSetSlot(this, 'entries');
              ensureMap(this);
              return new SetIterator(this['[[SetData]]'].entries());
            },
  
            forEach: function forEach(callback) {
              requireSetSlot(this, 'forEach');
              var context = arguments.length > 1 ? arguments[1] : null;
              var entireSet = this;
              ensureMap(entireSet);
              this['[[SetData]]'].forEach(function (value, key) {
                if (context) {
                  _call(callback, context, key, key, entireSet);
                } else {
                  callback(key, key, entireSet);
                }
              });
            }
          });
          defineProperty(SetShim.prototype, 'keys', SetShim.prototype.values, true);
          addIterator(SetShim.prototype, SetShim.prototype.values);
  
          var SetIterator = function SetIterator(it) {
            this.it = it;
          };
          SetIterator.prototype = {
            isSetIterator: true,
            next: function next() {
              if (!this.isSetIterator) {
                throw new TypeError('Not a SetIterator');
              }
              return this.it.next();
            }
          };
          addIterator(SetIterator.prototype);
  
          return SetShim;
        }())
      };
  
      var isGoogleTranslate = globals.Set && !Set.prototype['delete'] && Set.prototype.remove && Set.prototype.items && Set.prototype.map && Array.isArray(new Set().keys);
      if (isGoogleTranslate) {
        // special-case force removal of wildly invalid Set implementation in Google Translate iframes
        // see https://github.com/paulmillr/es6-shim/issues/438 / https://twitter.com/ljharb/status/849335573114363904
        globals.Set = collectionShims.Set;
      }
      if (globals.Map || globals.Set) {
        // Safari 8, for example, doesn't accept an iterable.
        var mapAcceptsArguments = valueOrFalseIfThrows(function () { return new Map([[1, 2]]).get(1) === 2; });
        if (!mapAcceptsArguments) {
          globals.Map = function Map() {
            if (!(this instanceof Map)) {
              throw new TypeError('Constructor Map requires "new"');
            }
            var m = new OrigMap();
            if (arguments.length > 0) {
              addIterableToMap(Map, m, arguments[0]);
            }
            delete m.constructor;
            Object.setPrototypeOf(m, globals.Map.prototype);
            return m;
          };
          globals.Map.prototype = create(OrigMap.prototype);
          defineProperty(globals.Map.prototype, 'constructor', globals.Map, true);
          Value.preserveToString(globals.Map, OrigMap);
        }
        var testMap = new Map();
        var mapUsesSameValueZero = (function () {
          // Chrome 38-42, node 0.11/0.12, iojs 1/2 also have a bug when the Map has a size > 4
          var m = new Map([[1, 0], [2, 0], [3, 0], [4, 0]]);
          m.set(-0, m);
          return m.get(0) === m && m.get(-0) === m && m.has(0) && m.has(-0);
        }());
        var mapSupportsChaining = testMap.set(1, 2) === testMap;
        if (!mapUsesSameValueZero || !mapSupportsChaining) {
          overrideNative(Map.prototype, 'set', function set(k, v) {
            _call(origMapSet, this, k === 0 ? 0 : k, v);
            return this;
          });
        }
        if (!mapUsesSameValueZero) {
          defineProperties(Map.prototype, {
            get: function get(k) {
              return _call(origMapGet, this, k === 0 ? 0 : k);
            },
            has: function has(k) {
              return _call(origMapHas, this, k === 0 ? 0 : k);
            }
          }, true);
          Value.preserveToString(Map.prototype.get, origMapGet);
          Value.preserveToString(Map.prototype.has, origMapHas);
        }
        var testSet = new Set();
        var setUsesSameValueZero = Set.prototype['delete'] && Set.prototype.add && Set.prototype.has && (function (s) {
          s['delete'](0);
          s.add(-0);
          return !s.has(0);
        }(testSet));
        var setSupportsChaining = testSet.add(1) === testSet;
        if (!setUsesSameValueZero || !setSupportsChaining) {
          var origSetAdd = Set.prototype.add;
          Set.prototype.add = function add(v) {
            _call(origSetAdd, this, v === 0 ? 0 : v);
            return this;
          };
          Value.preserveToString(Set.prototype.add, origSetAdd);
        }
        if (!setUsesSameValueZero) {
          var origSetHas = Set.prototype.has;
          Set.prototype.has = function has(v) {
            return _call(origSetHas, this, v === 0 ? 0 : v);
          };
          Value.preserveToString(Set.prototype.has, origSetHas);
          var origSetDel = Set.prototype['delete'];
          Set.prototype['delete'] = function SetDelete(v) {
            return _call(origSetDel, this, v === 0 ? 0 : v);
          };
          Value.preserveToString(Set.prototype['delete'], origSetDel);
        }
        var mapSupportsSubclassing = supportsSubclassing(globals.Map, function (M) {
          var m = new M([]);
          // Firefox 32 is ok with the instantiating the subclass but will
          // throw when the map is used.
          m.set(42, 42);
          return m instanceof M;
        });
        // without Object.setPrototypeOf, subclassing is not possible
        var mapFailsToSupportSubclassing = Object.setPrototypeOf && !mapSupportsSubclassing;
        var mapRequiresNew = (function () {
          try {
            return !(globals.Map() instanceof globals.Map);
          } catch (e) {
            return e instanceof TypeError;
          }
        }());
        if (globals.Map.length !== 0 || mapFailsToSupportSubclassing || !mapRequiresNew) {
          globals.Map = function Map() {
            if (!(this instanceof Map)) {
              throw new TypeError('Constructor Map requires "new"');
            }
            var m = new OrigMap();
            if (arguments.length > 0) {
              addIterableToMap(Map, m, arguments[0]);
            }
            delete m.constructor;
            Object.setPrototypeOf(m, Map.prototype);
            return m;
          };
          globals.Map.prototype = OrigMap.prototype;
          defineProperty(globals.Map.prototype, 'constructor', globals.Map, true);
          Value.preserveToString(globals.Map, OrigMap);
        }
        var setSupportsSubclassing = supportsSubclassing(globals.Set, function (S) {
          var s = new S([]);
          s.add(42, 42);
          return s instanceof S;
        });
        // without Object.setPrototypeOf, subclassing is not possible
        var setFailsToSupportSubclassing = Object.setPrototypeOf && !setSupportsSubclassing;
        var setRequiresNew = (function () {
          try {
            return !(globals.Set() instanceof globals.Set);
          } catch (e) {
            return e instanceof TypeError;
          }
        }());
        if (globals.Set.length !== 0 || setFailsToSupportSubclassing || !setRequiresNew) {
          var OrigSet = globals.Set;
          globals.Set = function Set() {
            if (!(this instanceof Set)) {
              throw new TypeError('Constructor Set requires "new"');
            }
            var s = new OrigSet();
            if (arguments.length > 0) {
              addIterableToSet(Set, s, arguments[0]);
            }
            delete s.constructor;
            Object.setPrototypeOf(s, Set.prototype);
            return s;
          };
          globals.Set.prototype = OrigSet.prototype;
          defineProperty(globals.Set.prototype, 'constructor', globals.Set, true);
          Value.preserveToString(globals.Set, OrigSet);
        }
        var newMap = new globals.Map();
        var mapIterationThrowsStopIterator = !valueOrFalseIfThrows(function () {
          return newMap.keys().next().done;
        });
        /*
          - In Firefox < 23, Map#size is a function.
          - In all current Firefox, Set#entries/keys/values & Map#clear do not exist
          - https://bugzilla.mozilla.org/show_bug.cgi?id=869996
          - In Firefox 24, Map and Set do not implement forEach
          - In Firefox 25 at least, Map and Set are callable without "new"
        */
        if (
          typeof globals.Map.prototype.clear !== 'function' ||
          new globals.Set().size !== 0 ||
          newMap.size !== 0 ||
          typeof globals.Map.prototype.keys !== 'function' ||
          typeof globals.Set.prototype.keys !== 'function' ||
          typeof globals.Map.prototype.forEach !== 'function' ||
          typeof globals.Set.prototype.forEach !== 'function' ||
          isCallableWithoutNew(globals.Map) ||
          isCallableWithoutNew(globals.Set) ||
          typeof newMap.keys().next !== 'function' || // Safari 8
          mapIterationThrowsStopIterator || // Firefox 25
          !mapSupportsSubclassing
        ) {
          defineProperties(globals, {
            Map: collectionShims.Map,
            Set: collectionShims.Set
          }, true);
        }
  
        if (globals.Set.prototype.keys !== globals.Set.prototype.values) {
          // Fixed in WebKit with https://bugs.webkit.org/show_bug.cgi?id=144190
          defineProperty(globals.Set.prototype, 'keys', globals.Set.prototype.values, true);
        }
  
        // Shim incomplete iterator implementations.
        addIterator(Object.getPrototypeOf((new globals.Map()).keys()));
        addIterator(Object.getPrototypeOf((new globals.Set()).keys()));
  
        if (functionsHaveNames && globals.Set.prototype.has.name !== 'has') {
          // Microsoft Edge v0.11.10074.0 is missing a name on Set#has
          var anonymousSetHas = globals.Set.prototype.has;
          overrideNative(globals.Set.prototype, 'has', function has(key) {
            return _call(anonymousSetHas, this, key);
          });
        }
      }
      defineProperties(globals, collectionShims);
      addDefaultSpecies(globals.Map);
      addDefaultSpecies(globals.Set);
    }
  
    var throwUnlessTargetIsObject = function throwUnlessTargetIsObject(target) {
      if (!ES.TypeIsObject(target)) {
        throw new TypeError('target must be an object');
      }
    };
  
    // Some Reflect methods are basically the same as
    // those on the Object global, except that a TypeError is thrown if
    // target isn't an object. As well as returning a boolean indicating
    // the success of the operation.
    var ReflectShims = {
      // Apply method in a functional form.
      apply: function apply() {
        return ES.Call(ES.Call, null, arguments);
      },
  
      // New operator in a functional form.
      construct: function construct(constructor, args) {
        if (!ES.IsConstructor(constructor)) {
          throw new TypeError('First argument must be a constructor.');
        }
        var newTarget = arguments.length > 2 ? arguments[2] : constructor;
        if (!ES.IsConstructor(newTarget)) {
          throw new TypeError('new.target must be a constructor.');
        }
        return ES.Construct(constructor, args, newTarget, 'internal');
      },
  
      // When deleting a non-existent or configurable property,
      // true is returned.
      // When attempting to delete a non-configurable property,
      // it will return false.
      deleteProperty: function deleteProperty(target, key) {
        throwUnlessTargetIsObject(target);
        if (supportsDescriptors) {
          var desc = Object.getOwnPropertyDescriptor(target, key);
  
          if (desc && !desc.configurable) {
            return false;
          }
        }
  
        // Will return true.
        return delete target[key];
      },
  
      has: function has(target, key) {
        throwUnlessTargetIsObject(target);
        return key in target;
      }
    };
  
    if (Object.getOwnPropertyNames) {
      Object.assign(ReflectShims, {
        // Basically the result of calling the internal [[OwnPropertyKeys]].
        // Concatenating propertyNames and propertySymbols should do the trick.
        // This should continue to work together with a Symbol shim
        // which overrides Object.getOwnPropertyNames and implements
        // Object.getOwnPropertySymbols.
        ownKeys: function ownKeys(target) {
          throwUnlessTargetIsObject(target);
          var keys = Object.getOwnPropertyNames(target);
  
          if (ES.IsCallable(Object.getOwnPropertySymbols)) {
            _pushApply(keys, Object.getOwnPropertySymbols(target));
          }
  
          return keys;
        }
      });
    }
  
    var callAndCatchException = function ConvertExceptionToBoolean(func) {
      return !throwsError(func);
    };
  
    if (Object.preventExtensions) {
      Object.assign(ReflectShims, {
        isExtensible: function isExtensible(target) {
          throwUnlessTargetIsObject(target);
          return Object.isExtensible(target);
        },
        preventExtensions: function preventExtensions(target) {
          throwUnlessTargetIsObject(target);
          return callAndCatchException(function () {
            return Object.preventExtensions(target);
          });
        }
      });
    }
  
    if (supportsDescriptors) {
      var internalGet = function get(target, key, receiver) {
        var desc = Object.getOwnPropertyDescriptor(target, key);
  
        if (!desc) {
          var parent = Object.getPrototypeOf(target);
  
          if (parent === null) {
            return void 0;
          }
  
          return internalGet(parent, key, receiver);
        }
  
        if ('value' in desc) {
          return desc.value;
        }
  
        if (desc.get) {
          return ES.Call(desc.get, receiver);
        }
  
        return void 0;
      };
  
      var internalSet = function set(target, key, value, receiver) {
        var desc = Object.getOwnPropertyDescriptor(target, key);
  
        if (!desc) {
          var parent = Object.getPrototypeOf(target);
  
          if (parent !== null) {
            return internalSet(parent, key, value, receiver);
          }
  
          desc = {
            value: void 0,
            writable: true,
            enumerable: true,
            configurable: true
          };
        }
  
        if ('value' in desc) {
          if (!desc.writable) {
            return false;
          }
  
          if (!ES.TypeIsObject(receiver)) {
            return false;
          }
  
          var existingDesc = Object.getOwnPropertyDescriptor(receiver, key);
  
          if (existingDesc) {
            return Reflect.defineProperty(receiver, key, {
              value: value
            });
          } else {
            return Reflect.defineProperty(receiver, key, {
              value: value,
              writable: true,
              enumerable: true,
              configurable: true
            });
          }
        }
  
        if (desc.set) {
          _call(desc.set, receiver, value);
          return true;
        }
  
        return false;
      };
  
      Object.assign(ReflectShims, {
        defineProperty: function defineProperty(target, propertyKey, attributes) {
          throwUnlessTargetIsObject(target);
          return callAndCatchException(function () {
            return Object.defineProperty(target, propertyKey, attributes);
          });
        },
  
        getOwnPropertyDescriptor: function getOwnPropertyDescriptor(target, propertyKey) {
          throwUnlessTargetIsObject(target);
          return Object.getOwnPropertyDescriptor(target, propertyKey);
        },
  
        // Syntax in a functional form.
        get: function get(target, key) {
          throwUnlessTargetIsObject(target);
          var receiver = arguments.length > 2 ? arguments[2] : target;
  
          return internalGet(target, key, receiver);
        },
  
        set: function set(target, key, value) {
          throwUnlessTargetIsObject(target);
          var receiver = arguments.length > 3 ? arguments[3] : target;
  
          return internalSet(target, key, value, receiver);
        }
      });
    }
  
    if (Object.getPrototypeOf) {
      var objectDotGetPrototypeOf = Object.getPrototypeOf;
      ReflectShims.getPrototypeOf = function getPrototypeOf(target) {
        throwUnlessTargetIsObject(target);
        return objectDotGetPrototypeOf(target);
      };
    }
  
    if (Object.setPrototypeOf && ReflectShims.getPrototypeOf) {
      var willCreateCircularPrototype = function (object, lastProto) {
        var proto = lastProto;
        while (proto) {
          if (object === proto) {
            return true;
          }
          proto = ReflectShims.getPrototypeOf(proto);
        }
        return false;
      };
  
      Object.assign(ReflectShims, {
        // Sets the prototype of the given object.
        // Returns true on success, otherwise false.
        setPrototypeOf: function setPrototypeOf(object, proto) {
          throwUnlessTargetIsObject(object);
          if (proto !== null && !ES.TypeIsObject(proto)) {
            throw new TypeError('proto must be an object or null');
          }
  
          // If they already are the same, we're done.
          if (proto === Reflect.getPrototypeOf(object)) {
            return true;
          }
  
          // Cannot alter prototype if object not extensible.
          if (Reflect.isExtensible && !Reflect.isExtensible(object)) {
            return false;
          }
  
          // Ensure that we do not create a circular prototype chain.
          if (willCreateCircularPrototype(object, proto)) {
            return false;
          }
  
          Object.setPrototypeOf(object, proto);
  
          return true;
        }
      });
    }
    var defineOrOverrideReflectProperty = function (key, shim) {
      if (!ES.IsCallable(globals.Reflect[key])) {
        defineProperty(globals.Reflect, key, shim);
      } else {
        var acceptsPrimitives = valueOrFalseIfThrows(function () {
          globals.Reflect[key](1);
          globals.Reflect[key](NaN);
          globals.Reflect[key](true);
          return true;
        });
        if (acceptsPrimitives) {
          overrideNative(globals.Reflect, key, shim);
        }
      }
    };
    Object.keys(ReflectShims).forEach(function (key) {
      defineOrOverrideReflectProperty(key, ReflectShims[key]);
    });
    var originalReflectGetProto = globals.Reflect.getPrototypeOf;
    if (functionsHaveNames && originalReflectGetProto && originalReflectGetProto.name !== 'getPrototypeOf') {
      overrideNative(globals.Reflect, 'getPrototypeOf', function getPrototypeOf(target) {
        return _call(originalReflectGetProto, globals.Reflect, target);
      });
    }
    if (globals.Reflect.setPrototypeOf) {
      if (valueOrFalseIfThrows(function () {
        globals.Reflect.setPrototypeOf(1, {});
        return true;
      })) {
        overrideNative(globals.Reflect, 'setPrototypeOf', ReflectShims.setPrototypeOf);
      }
    }
    if (globals.Reflect.defineProperty) {
      if (!valueOrFalseIfThrows(function () {
        var basic = !globals.Reflect.defineProperty(1, 'test', { value: 1 });
        // "extensible" fails on Edge 0.12
        var extensible = typeof Object.preventExtensions !== 'function' || !globals.Reflect.defineProperty(Object.preventExtensions({}), 'test', {});
        return basic && extensible;
      })) {
        overrideNative(globals.Reflect, 'defineProperty', ReflectShims.defineProperty);
      }
    }
    if (globals.Reflect.construct) {
      if (!valueOrFalseIfThrows(function () {
        var F = function F() {};
        return globals.Reflect.construct(function () {}, [], F) instanceof F;
      })) {
        overrideNative(globals.Reflect, 'construct', ReflectShims.construct);
      }
    }
  
    if (String(new Date(NaN)) !== 'Invalid Date') {
      var dateToString = Date.prototype.toString;
      var shimmedDateToString = function toString() {
        var valueOf = +this;
        if (valueOf !== valueOf) {
          return 'Invalid Date';
        }
        return ES.Call(dateToString, this);
      };
      overrideNative(Date.prototype, 'toString', shimmedDateToString);
    }
  
  // ##### BEGIN: MODIFIED BY SAP
  //   // Annex B HTML methods
  //   // http://www.ecma-international.org/ecma-262/6.0/#sec-additional-properties-of-the-string.prototype-object
  //   var stringHTMLshims = {
  //     anchor: function anchor(name) { return ES.CreateHTML(this, 'a', 'name', name); },
  //     big: function big() { return ES.CreateHTML(this, 'big', '', ''); },
  //     blink: function blink() { return ES.CreateHTML(this, 'blink', '', ''); },
  //     bold: function bold() { return ES.CreateHTML(this, 'b', '', ''); },
  //     fixed: function fixed() { return ES.CreateHTML(this, 'tt', '', ''); },
  //     fontcolor: function fontcolor(color) { return ES.CreateHTML(this, 'font', 'color', color); },
  //     fontsize: function fontsize(size) { return ES.CreateHTML(this, 'font', 'size', size); },
  //     italics: function italics() { return ES.CreateHTML(this, 'i', '', ''); },
  //     link: function link(url) { return ES.CreateHTML(this, 'a', 'href', url); },
  //     small: function small() { return ES.CreateHTML(this, 'small', '', ''); },
  //     strike: function strike() { return ES.CreateHTML(this, 'strike', '', ''); },
  //     sub: function sub() { return ES.CreateHTML(this, 'sub', '', ''); },
  //     sup: function sub() { return ES.CreateHTML(this, 'sup', '', ''); }
  //   };
  //   _forEach(Object.keys(stringHTMLshims), function (key) {
  //     var method = String.prototype[key];
  //     var shouldOverwrite = false;
  //     if (ES.IsCallable(method)) {
  //       var output = _call(method, '', ' " ');
  //       var quotesCount = _concat([], output.match(/"/g)).length;
  //       shouldOverwrite = output !== output.toLowerCase() || quotesCount > 2;
  //     } else {
  //       shouldOverwrite = true;
  //     }
  //     if (shouldOverwrite) {
  //       overrideNative(String.prototype, key, stringHTMLshims[key]);
  //     }
  //   });
  // ##### END: MODIFIED BY SAP
  
    var JSONstringifiesSymbols = (function () {
      // Microsoft Edge v0.12 stringifies Symbols incorrectly
      if (!hasSymbols) { return false; } // Symbols are not supported
      var stringify = typeof JSON === 'object' && typeof JSON.stringify === 'function' ? JSON.stringify : null;
      if (!stringify) { return false; } // JSON.stringify is not supported
      if (typeof stringify(Symbol()) !== 'undefined') { return true; } // Symbols should become `undefined`
      if (stringify([Symbol()]) !== '[null]') { return true; } // Symbols in arrays should become `null`
      var obj = { a: Symbol() };
      obj[Symbol()] = true;
      if (stringify(obj) !== '{}') { return true; } // Symbol-valued keys *and* Symbol-valued properties should be omitted
      return false;
    }());
    var JSONstringifyAcceptsObjectSymbol = valueOrFalseIfThrows(function () {
      // Chrome 45 throws on stringifying object symbols
      if (!hasSymbols) { return true; } // Symbols are not supported
      return JSON.stringify(Object(Symbol())) === '{}' && JSON.stringify([Object(Symbol())]) === '[{}]';
    });
    if (JSONstringifiesSymbols || !JSONstringifyAcceptsObjectSymbol) {
      var origStringify = JSON.stringify;
      overrideNative(JSON, 'stringify', function stringify(value) {
        if (typeof value === 'symbol') { return; }
        var replacer;
        if (arguments.length > 1) {
          replacer = arguments[1];
        }
        var args = [value];
        if (!isArray(replacer)) {
          var replaceFn = ES.IsCallable(replacer) ? replacer : null;
          var wrappedReplacer = function (key, val) {
            var parsedValue = replaceFn ? _call(replaceFn, this, key, val) : val;
            if (typeof parsedValue !== 'symbol') {
              if (Type.symbol(parsedValue)) {
                return assignTo({})(parsedValue);
              } else {
                return parsedValue;
              }
            }
          };
          args.push(wrappedReplacer);
        } else {
          // create wrapped replacer that handles an array replacer?
          args.push(replacer);
        }
        if (arguments.length > 2) {
          args.push(arguments[2]);
        }
        return origStringify.apply(this, args);
      });
    }
  
    return globals;
  }));
  //@ui5-bundle-raw-include ui5loader.js
  /*!
   * OpenUI5
   * (c) Copyright 2009-2019 SAP SE or an SAP affiliate company.
   * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
   */
  
  /*
   * IMPORTANT NOTICE
   * With 1.54, ui5loader.js and its new features are not yet a public API.
   * The loader must only be used via the well-known and documented UI5 APIs
   * such as sap.ui.define, sap.ui.require, etc.
   * Any direct usage of ui5loader.js or its features is not supported and
   * might break in future releases.
   */
  
  /*global sap:true, console, document, Promise, XMLHttpRequest */
  
  (function(__global) {
  	"use strict";
  
  	/*
  	 * Helper function that removes any query and/or hash parts from the given URL.
  	 *
  	 * @param {string} href URL to remove query and hash from
  	 * @returns {string}
  	 */
  	function pathOnly(href) {
  		var p = href.search(/[?#]/);
  		return p < 0 ? href : href.slice(0, p);
  	}
  
  	/*
  	 * Helper function that returns the document base URL without search parameters and hash.
  	 *
  	 * @returns {string}
  	 */
  	function docBase() {
  		return pathOnly(document.baseURI);
  	}
  
  	/*
  	 * Whether the current browser is IE11, derived from the compatibility check for the URL Web API.
  	 */
  	var isIE11 = false;
  
  	/**
  	 * Resolve a given URL, either against the base URL of the current document or against a given base URL.
  	 *
  	 * If no base URL is given, the URL will be resolved relative to the baseURI of the current document.
  	 * If a base URL is given, that base will first be resolved relative to the document's baseURI,
  	 * then the URL will be resolved relative to the resolved base.
  	 *
  	 * @param {string} sURI Relative or absolute URL that should be resolved
  	 * @param {string} [sBase=document.baseURI] Base URL relative to which the URL should be resolved
  	 * @returns {string} Resolved URL
  	 */
  	var resolveURL = (function(_URL) {
  
  		// feature check: URI support
  		// - can URL be used as a constructor (fails in IE 11)?
  		// - does toString() return the expected URL string (fails in PhantomJS 2.1)?
  		try {
  			if ( !/localhost/.test(new _URL('index.html', 'http://localhost:8080/')) ) {
  				_URL = null;
  			}
  		} catch (e) {
  			isIE11 = true;
  			_URL = null;
  		}
  
  		if ( _URL ) {
  			return function(sURI, sBase) {
  				// For a spec see https://url.spec.whatwg.org/
  				// For browser support see https://developer.mozilla.org/en/docs/Web/API/URL
  				return new _URL(sURI, sBase ? new _URL(sBase, docBase()) : docBase()).toString();
  			};
  		}
  
  		// fallback for IE11 and PhantomJS: use a shadow document with <base> and <a>nchor tag
  		var doc = document.implementation.createHTMLDocument("Dummy doc for resolveURI");
  		var base = doc.createElement('base');
  		base.href = docBase();
  		doc.head.appendChild(base);
  		var anchor = doc.createElement("A");
  		doc.body.appendChild(anchor);
  
  		return function (sURI, sBase) {
  			base.href = docBase();
  			if ( sBase != null ) {
  				// first resolve sBase relative to location
  				anchor.href = sBase;
  				// then use it as base
  				base.href = anchor.href;
  			}
  			anchor.href = sURI;
  			// console.log("(" + sURI + "," + sBase + ") => (" + base.href + "," + anchor.href + ")");
  			return anchor.href;
  		};
  
  	}(__global.URL || __global.webkitURL));
  
  	// ---- helpers -------------------------------------------------------------------------------
  
  	function noop() {}
  
  	function forEach(obj, callback) {
  		Object.keys(obj).forEach(function(key) {
  			callback(key, obj[key]);
  		});
  	}
  
  	function executeInSeparateTask(fn) {
  		setTimeout(fn, 0);
  	}
  
  	function executeInMicroTask(fn) {
  		Promise.resolve().then(fn);
  	}
  
  	// ---- hooks & configuration -----------------------------------------------------------------
  
  	/**
  	 * Log functionality.
  	 *
  	 * Can be set to an object with the methods shown below (subset of sap/base/Log).
  	 * Logging methods never must fail. Should they ever throw errors, then the internal state
  	 * of the loader will be broken.
  	 *
  	 * By default, all methods are implemented as NOOPs.
  	 *
  	 * @type {{debug:function(),info:function(),warning:function(),error:function(),isLoggable:function():boolean}}
  	 * @private
  	 */
  	var log = {
  		debug: noop,
  		info: noop,
  		warning: noop,
  		error: noop,
  		isLoggable: noop
  	}; // Null Object pattern: dummy logger which is used as long as no logger is injected
  
  	/**
  	 * Basic assert functionality.
  	 *
  	 * Can be set to a function that gets a value (the expression t be asserted) as first
  	 * parameter and a message as second parameter. When the expression coerces to false,
  	 * the assertion is violated and the message should be emitted (logged, thrown, whatever).
  	 *
  	 * By default, this is implemented as a NOOP.
  	 * @type {function(any,string)}
  	 * @private
  	 */
  	var assert = noop; // Null Object pattern: dummy assert which is used as long as no assert is injected
  
  	/**
  	 * Callback for performance measurement.
  	 *
  	 * When set, it must be an object with methods <code>start</code> and <code>end</code>.
  	 * @type {{start:function(string,any),end:function(string)}}
  	 * @private
  	 */
  	var measure;
  
  	/**
  	 * Source code transformation hook.
  	 *
  	 * To be used by code coverage, only supported in sync mode.
  	 * @private
  	 */
  	var translate;
  
  	/**
  	 * Method used by sap.ui.require to simulate asynchronous behavior.
  	 *
  	 * The default executes the given function in a separate browser task.
  	 * Can be changed to execute in a micro task to save idle time in case of
  	 * many nested sap.ui.require calls.
  	 */
  	var simulateAsyncCallback = executeInSeparateTask;
  
  	/*
  	 * Activates strictest possible compliance with AMD spec
  	 * - no multiple executions of the same module
  	 * - at most one anonymous module definition per file, zero for adhoc definitions
  	 */
  	var strictModuleDefinitions = true;
  
  	/**
  	 * Whether asynchronous loading can be used at all.
  	 * When activated, require will load asynchronously, else synchronously.
  	 * @type {boolean}
  	 * @private
  	 */
  	var bGlobalAsyncMode = false;
  
  
  	/**
  	 * Whether ui5loader currently exposes its AMD implementation as global properties
  	 * <code>define</code> and <code>require</code>. Defaults to <code>false</code>.
  	 * @type {boolean}
  	 * @private
  	 */
  	var bExposeAsAMDLoader = false;
  
  	/**
  	 * How the loader should react to calls of sync APIs or when global names are accessed:
  	 * 0: tolerate
  	 * 1: warn
  	 * 2: reject
  	 * @type {int}
  	 * @private
  	 */
  	var syncCallBehavior = 0;
  
  	/**
  	 * Default base URL for modules, used when no other configuration is provided.
  	 * In case the base url is removed via <code>registerResourcePath("", null)</code>
  	 * it will be reset to this URL instead.
  	 * @const
  	 * @type {string}
  	 * @private
  	 */
  	var DEFAULT_BASE_URL = "./";
  
  	/**
  	 * Temporarily saved reference to the original value of the global define variable.
  	 *
  	 * @type {any}
  	 * @private
  	 */
  	var vOriginalDefine;
  
  	/**
  	 * Temporarily saved reference to the original value of the global require variable.
  	 *
  	 * @type {any}
  	 * @private
  	 */
  	var vOriginalRequire;
  
  
  	/**
  	 * A map of URL prefixes keyed by the corresponding module name prefix.
  	 *
  	 * Note that the empty prefix ('') will always match and thus serves as a fallback.
  	 * @type {Object.<string,{url:string,absoluteUrl:string}>}
  	 * @see jQuery.sap.registerModulePath
  	 * @private
  	 */
  	var mUrlPrefixes = Object.create(null);
  	mUrlPrefixes[''] = {
  		url: DEFAULT_BASE_URL,
  		absoluteUrl: resolveURL(DEFAULT_BASE_URL, document.baseURI)
  	};
  
  	/**
  	 * Mapping of module IDs.
  	 *
  	 * Each entry is a map of its own, keyed by the module ID prefix for which it should be
  	 * applied. Each contained map maps module ID prefixes to module ID prefixes.
  	 *
  	 * All module ID prefixes must not have extensions.
  	 * @type {Object.<string,Object.<string,string>>}
  	 * @private
  	 */
  	var mMaps = Object.create(null),
  
  	/**
  	 * Information about third party modules, keyed by the module's resource name (including extension '.js').
  	 *
  	 * Each module shim object can have the following properties:
  	 * <ul>
  	 * <li><i>boolean</i>: [amd=false] Whether the module uses an AMD loader if present. If set to <code>true</code>,
  	 *     UI5 will disable an AMD loader while loading such a module to force the module to expose its content
  	 *     via global names.</li>
  	 * <li><i>string[]|string</i>: [exports=undefined] Global name (or names) that are exported by the module.
  	 *     If one ore multiple names are defined, the first one will be read from the global object and will be
  	 *     used as value of the module. Each name can be a dot separated hierarchical name (will be resolved with
  	 *     <code>getGlobalProperty</code>)</li>
  	 * <li><i>string[]</i>: [deps=undefined] List of modules that the module depends on. The modules will be loaded
  	 *     first before loading the module itself. Note that the stored dependencies also include the extension '.js'
  	 *     for easier evaluation, but <code>config({shim:...})</code> expects them without the extension for
  	 *     compatibility with the AMD-JS specification.</li>
  	 * </ul>
  	 *
  	 * @see config method
  	 * @type {Object.<string,{amd:boolean,exports:(string|string[]),deps:string[]}>}
  	 * @private
  	 */
  		mShims = Object.create(null),
  
  	/**
  	 * Dependency Cache information.
  	 * Maps the name of a module to a list of its known dependencies.
  	 * @type {Object.<string,string[]>}
  	 * @private
  	 */
  		mDepCache = Object.create(null),
  
  	/**
  	 * Whether the loader should try to load debug sources.
  	 * @type {boolean}
  	 * @private
  	 */
  		bDebugSources = false,
  
  	/**
  	 * Indicates partial or total debug mode.
  	 *
  	 * Can be set to a function which checks whether preloads should be ignored for the given module.
  	 * If undefined, all preloads will be used.
  	 * @type {function(string):boolean|undefined}
  	 * @private
  	 */
  		fnIgnorePreload;
  
  
  	// ---- internal state ------------------------------------------------------------------------
  
  	/**
  	 * Map of modules that have been loaded or required so far, keyed by their name.
  	 *
  	 * @type {Object<string,Module>}
  	 * @private
  	 */
  	var mModules = Object.create(null),
  
  	/**
  	 * Whether (sap.ui.)define calls must be executed synchronously in the current context.
  	 *
  	 * The initial value is <code>null</code>. During the execution of a module loading operation
  	 * ((sap.ui.)require or (sap.ui.)define etc.), it is set to true or false depending on the
  	 * legacy synchronicity behavior of the operation.
  	 *
  	 * Problem: when AMD modules are loaded with hard coded script tags and when some later inline
  	 * script expects the module export synchronously, then the (sap.ui.)define must be executed
  	 * synchronously.
  	 * Most prominent example: unit tests that include QUnitUtils as a script tag and use qutils
  	 * in one of their inline scripts.
  	 * @type {boolean}
  	 * @private
  	 */
  		bForceSyncDefines = null,
  
  	/**
  	 * Stack of modules that are currently being executed in case of synchronous processing.
  	 *
  	 * Allows to identify the executing module (e.g. when resolving dependencies or in case of
  	 * in case of bundles like sap-ui-core).
  	 *
  	 * @type {Array.<{name:string,used:boolean}>}
  	 * @private
  	 */
  		_execStack = [ ],
  
  	/**
  	 * A prefix that will be added to module loading log statements and which reflects the nesting of module executions.
  	 * @type {string}
  	 * @private
  	 */
  		sLogPrefix = "",
  
  	/**
  	 * Counter used to give anonymous modules a unique module ID.
  	 * @type {int}
  	 * @private
  	 */
  		iAnonymousModuleCount = 0,
  
  	/**
  	 * IE only: max size a script should have when executing it with execScript, otherwise fallback to eval.
  	 * @type {int}
  	 * @const
  	 * @private
  	 */
  		MAX_EXEC_SCRIPT_LENGTH = 512 * 1024;
  
  
  	// ---- Names and Paths -----------------------------------------------------------------------
  
  	/**
  	 * Name conversion function that converts a name in unified resource name syntax to a name in UI5 module name syntax.
  	 * If the name cannot be converted (e.g. doesn't end with '.js'), then <code>undefined</code> is returned.
  	 *
  	 * @param {string} sName Name in unified resource name syntax
  	 * @returns {string|undefined} Name in UI5 (legacy) module name syntax (dot separated)
  	 *   or <code>undefined</code> when the name can't be converted
  	 * @private
  	 */
  	function urnToUI5(sName) {
  		// UI5 module name syntax is only defined for JS resources
  		if ( !/\.js$/.test(sName) ) {
  			return undefined;
  		}
  
  		sName = sName.slice(0, -3);
  		if ( /^jquery\.sap\./.test(sName) ) {
  			return sName; // do nothing
  		}
  		return sName.replace(/\//g, ".");
  	}
  
  	function urnToIDAndType(sResourceName) {
  		var basenamePos = sResourceName.lastIndexOf('/'),
  			dotPos = sResourceName.lastIndexOf('.');
  		if ( dotPos > basenamePos ) {
  			return {
  				id: sResourceName.slice(0, dotPos),
  				type: sResourceName.slice(dotPos)
  			};
  		}
  		return {
  			id: sResourceName,
  			type: ''
  		};
  	}
  
  	var rJSSubTypes = /(\.controller|\.fragment|\.view|\.designtime|\.support)?.js$/;
  
  	function urnToBaseIDAndSubType(sResourceName) {
  		var m = rJSSubTypes.exec(sResourceName);
  		if ( m ) {
  			return {
  				baseID: sResourceName.slice(0, m.index),
  				subType: m[0]
  			};
  		}
  	}
  
  	var rDotSegmentAnywhere = /(?:^|\/)\.+(?=\/|$)/;
  	var rDotSegment = /^\.*$/;
  
  	/**
  	 * Normalizes a resource name by resolving any relative name segments.
  	 *
  	 * A segment consisting of a single dot <code>./</code>, when used at the beginning of a name refers
  	 * to the containing package of the <code>sBaseName</code>. When used inside a name, it is ignored.
  	 *
  	 * A segment consisting of two dots <code>../</code> refers to the parent package. It can be used
  	 * anywhere in a name, but the resolved name prefix up to that point must not be empty.
  	 *
  	 * Example: A name <code>../common/validation.js</code> defined in <code>sap/myapp/controller/mycontroller.controller.js</code>
  	 * will resolve to <code>sap/myapp/common/validation.js</code>.
  	 *
  	 * When <code>sBaseName</code> is <code>null</code> (e.g. for a <code>sap.ui.require</code> call),
  	 * the resource name must not start with a relative name segment or an error will be thrown.
  	 *
  	 * @param {string} sResourceName Name to resolve
  	 * @param {string|null} sBaseName Name of a reference module relative to which the name will be resolved
  	 * @returns {string} Resolved name
  	 * @throws {Error} When a relative name should be resolved but not basename is given;
  	 *   or when upward navigation (../) is requested on the root level
  	 *   or when a name segment consists of 3 or more dots only
  	 * @private
  	 */
  	function normalize(sResourceName, sBaseName) {
  
  		var p = sResourceName.search(rDotSegmentAnywhere),
  			aSegments,
  			sSegment,
  			i,j,l;
  
  		// check whether the name needs to be resolved at all - if not, just return the sModuleName as it is.
  		if ( p < 0 ) {
  			return sResourceName;
  		}
  
  		// if the name starts with a relative segment then there must be a base name (a global sap.ui.require doesn't support relative names)
  		if ( p === 0 ) {
  			if ( sBaseName == null ) {
  				throw new Error("relative name not supported ('" + sResourceName + "'");
  			}
  			// prefix module name with the parent package
  			sResourceName = sBaseName.slice(0, sBaseName.lastIndexOf('/') + 1) + sResourceName;
  		}
  
  		aSegments = sResourceName.split('/');
  
  		// process path segments
  		for (i = 0, j = 0, l = aSegments.length; i < l; i++) {
  
  			sSegment = aSegments[i];
  
  			if ( rDotSegment.test(sSegment) ) {
  				if (sSegment === '.' || sSegment === '') {
  					// ignore '.' as it's just a pointer to current package. ignore '' as it results from double slashes (ignored by browsers as well)
  					continue;
  				} else if (sSegment === '..') {
  					// move to parent directory
  					if ( j === 0 ) {
  						throw new Error("Can't navigate to parent of root ('" + sResourceName + "')");
  					}
  					j--;
  				} else {
  					throw new Error("Illegal path segment '" + sSegment + "' ('" + sResourceName + "')");
  				}
  			} else {
  				aSegments[j++] = sSegment;
  			}
  
  		}
  
  		aSegments.length = j;
  
  		return aSegments.join('/');
  	}
  
  	/**
  	 * Adds a resource path to the resources map.
  	 *
  	 * @param {string} sResourceNamePrefix prefix is used as map key
  	 * @param {string} sUrlPrefix path to the resource
  	 */
  	function registerResourcePath(sResourceNamePrefix, sUrlPrefix) {
  		sResourceNamePrefix = String(sResourceNamePrefix || "");
  
  		if ( sUrlPrefix == null ) {
  
  			// remove a registered URL prefix, if it wasn't for the empty resource name prefix
  			if ( sResourceNamePrefix ) {
  				if ( mUrlPrefixes[sResourceNamePrefix] ) {
  					delete mUrlPrefixes[sResourceNamePrefix];
  					log.info("registerResourcePath ('" + sResourceNamePrefix + "') (registration removed)");
  				}
  				return;
  			}
  
  			// otherwise restore the default
  			sUrlPrefix = DEFAULT_BASE_URL;
  			log.info("registerResourcePath ('" + sResourceNamePrefix + "') (default registration restored)");
  
  		}
  
  		// cast to string and remove query parameters and/or hash
  		sUrlPrefix = pathOnly(String(sUrlPrefix));
  
  		// ensure that the prefix ends with a '/'
  		if ( sUrlPrefix.slice(-1) !== '/' ) {
  			sUrlPrefix += '/';
  		}
  
  		mUrlPrefixes[sResourceNamePrefix] = {
  			url: sUrlPrefix,
  			// calculate absolute URL, only to be used by 'guessResourceName'
  			absoluteUrl: resolveURL(sUrlPrefix)
  		};
  	}
  
  	/**
  	 * Retrieves path to a given resource by finding the longest matching prefix for the resource name
  	 *
  	 * @param {string} sResourceName name of the resource stored in the resources map
  	 * @param {string} sSuffix url suffix
  	 *
  	 * @returns {string} resource path
  	 */
  	function getResourcePath(sResourceName, sSuffix) {
  
  		var sNamePrefix = sResourceName,
  			p = sResourceName.length,
  			sPath;
  
  		// search for a registered name prefix, starting with the full name and successively removing one segment
  		while ( p > 0 && !mUrlPrefixes[sNamePrefix] ) {
  			p = sNamePrefix.lastIndexOf('/');
  			// Note: an empty segment at p = 0 (leading slash) will be ignored
  			sNamePrefix = p > 0 ? sNamePrefix.slice(0, p) : '';
  		}
  
  		assert((p > 0 || sNamePrefix === '') && mUrlPrefixes[sNamePrefix], "there always must be a mapping");
  
  		sPath = mUrlPrefixes[sNamePrefix].url + sResourceName.slice(p + 1); // also skips a leading slash!
  
  		//remove trailing slash
  		if ( sPath.slice(-1) === '/' ) {
  			sPath = sPath.slice(0, -1);
  		}
  		return sPath + (sSuffix || '');
  
  	}
  
  	/**
  	 * Returns the reporting mode for synchronous calls
  	 *
  	 * @returns {int} sync call behavior
  	 */
  	function getSyncCallBehavior() {
  		return syncCallBehavior;
  	}
  
  	function guessResourceName(sURL) {
  		var sNamePrefix,
  			sUrlPrefix,
  			sResourceName;
  
  		// Make sure to have an absolute URL without query parameters or hash
  		// to check against absolute prefix URLs
  		sURL = pathOnly(resolveURL(sURL));
  
  		for (sNamePrefix in mUrlPrefixes) {
  
  			// Note: configured URL prefixes are guaranteed to end with a '/'
  			// But to support the legacy scenario promoted by the application tools ( "registerModulePath('Application','Application')" )
  			// the prefix check here has to be done without the slash
  			sUrlPrefix = mUrlPrefixes[sNamePrefix].absoluteUrl.slice(0, -1);
  
  			if ( sURL.indexOf(sUrlPrefix) === 0 ) {
  
  				// calc resource name
  				sResourceName = sNamePrefix + sURL.slice(sUrlPrefix.length);
  				// remove a leading '/' (occurs if name prefix is empty and if match was a full segment match
  				if ( sResourceName.charAt(0) === '/' ) {
  					sResourceName = sResourceName.slice(1);
  				}
  
  				if ( mModules[sResourceName] && mModules[sResourceName].data ) {
  					return sResourceName;
  				}
  			}
  		}
  	}
  
  	/**
  	 * Find the most specific map config that matches the given context resource
  	 * @param {string} sContext Resource name to be used as context
  	 * @returns {Object<string,string>|undefined} Most specific map or <code>undefined</code>
  	 */
  	function findMapForContext(sContext) {
  		var p, mMap;
  		if ( sContext != null ) {
  			// maps are defined on module IDs, reduce URN to module ID
  			sContext = urnToIDAndType(sContext).id;
  			p = sContext.length;
  			mMap = mMaps[sContext];
  			while ( p > 0 && mMap == null ) {
  				p = sContext.lastIndexOf('/');
  				if ( p > 0 ) { // Note: an empty segment at p = 0 (leading slash) will be ignored
  					sContext = sContext.slice(0, p);
  					mMap = mMaps[sContext];
  				}
  			}
  		}
  		// if none is found, fallback to '*' map
  		return mMap || mMaps['*'];
  	}
  
  	function getMappedName(sResourceName, sRequestingResourceName) {
  
  		var mMap = findMapForContext(sRequestingResourceName),
  			sPrefix, p;
  
  		// resolve relative names
  		sResourceName = normalize(sResourceName, sRequestingResourceName);
  
  		// if there's a map, search for the most specific matching entry
  		if ( mMap != null ) {
  			// start with the full ID and successively remove one segment
  			sPrefix = urnToIDAndType(sResourceName).id;
  			p = sPrefix.length;
  			while ( p > 0 && mMap[sPrefix] == null ) {
  				p = sPrefix.lastIndexOf('/');
  				// Note: an empty segment at p = 0 (leading slash) will be ignored
  				sPrefix = p > 0 ? sPrefix.slice(0, p) : '';
  			}
  
  			if ( p > 0 ) {
  				if ( log.isLoggable() ) {
  					log.debug('module ID ' + sResourceName + " mapped to " + mMap[sPrefix] + sResourceName.slice(p));
  				}
  				return mMap[sPrefix] + sResourceName.slice(p); // also skips a leading slash!
  			}
  		}
  
  		return sResourceName;
  	}
  
  	function getGlobalObject(oObject, aNames, l, bCreate) {
  		for (var i = 0; oObject && i < l; i++) {
  			if (!oObject[aNames[i]] && bCreate ) {
  				oObject[aNames[i]] = {};
  			}
  			oObject = oObject[aNames[i]];
  		}
  		return oObject;
  	}
  
  	function getGlobalProperty(sName) {
  		var aNames = sName ? sName.split(".") : [];
  
  		if ( syncCallBehavior && aNames.length > 1 ) {
  			log.error("[nosync] getGlobalProperty called to retrieve global name '" + sName + "'");
  		}
  
  		return getGlobalObject(__global, aNames, aNames.length);
  	}
  
  	function setGlobalProperty(sName, vValue) {
  		var aNames = sName ? sName.split(".") : [],
  			oObject;
  		if ( aNames.length > 0 ) {
  			oObject = getGlobalObject(__global, aNames, aNames.length - 1, true);
  			oObject[aNames[aNames.length - 1]] = vValue;
  		}
  	}
  
  	// ---- Modules -------------------------------------------------------------------------------
  
  	function wrapExport(value) {
  		return { moduleExport: value };
  	}
  
  	function unwrapExport(wrapper) {
  		return wrapper.moduleExport;
  	}
  
  	/**
  	 * Module neither has been required nor preloaded nor declared, but someone asked for it.
  	 */
  	var INITIAL = 0,
  
  	/**
  	 * Module has been preloaded, but not required or declared.
  	 */
  		PRELOADED = -1,
  
  	/**
  	 * Module has been declared.
  	 */
  		LOADING = 1,
  
  	/**
  	 * Module has been loaded, but not yet executed.
  	 */
  		LOADED = 2,
  
  	/**
  	 * Module is currently being executed
  	 */
  		EXECUTING = 3,
  
  	/**
  	 * Module has been loaded and executed without errors.
  	 */
  		READY = 4,
  
  	/**
  	 * Module either could not be loaded or execution threw an error
  	 */
  		FAILED = 5,
  
  	/**
  	 * Special content value used internally until the content of a module has been determined
  	 */
  		NOT_YET_DETERMINED = {};
  
  	/**
  	 * A module/resource as managed by the module system.
  	 *
  	 * Each module is an object with the following properties
  	 * <ul>
  	 * <li>{int} state one of the module states defined in this function</li>
  	 * <li>{string} url URL where the module has been loaded from</li>
  	 * <li>{any} data temp. raw content of the module (between loaded and ready or when preloaded)</li>
  	 * <li>{string} group the bundle with which a resource was loaded or null</li>
  	 * <li>{string} error an error description for state <code>FAILED</code></li>
  	 * <li>{any} content the content of the module as exported via define()<(li>
  	 * </ul>
  	 *
  	 * @param {string} name Name of the module, including extension
  	 */
  	function Module(name) {
  		this.name = name;
  		this.state = INITIAL;
  		/*
  		 * Whether processing of the module is complete.
  		 * This is very similar to, but not the same as state >= READY because declareModule() sets state=READY very early.
  		 * That state transition is 'legacy' from the library-all files; it needs to checked whether it can be removed.
  		 */
  		this.settled = false;
  		this.url =
  		this._deferred =
  		this.data =
  		this.group =
  		this.error =
  		this.pending = null;
  		this.content = NOT_YET_DETERMINED;
  	}
  
  	Module.prototype.deferred = function() {
  		if ( this._deferred == null ) {
  			var deferred = this._deferred = {};
  			deferred.promise = new Promise(function(resolve,reject) {
  				deferred.resolve = resolve;
  				deferred.reject = reject;
  			});
  			// avoid 'Uncaught (in promise)' log entries
  			deferred.promise.catch(noop);
  		}
  		return this._deferred;
  	};
  
  	Module.prototype.api = function() {
  		if ( this._api == null ) {
  			this._exports = {};
  			this._api = {
  				id: this.name.slice(0,-3),
  				exports: this._exports,
  				url: this.url,
  				config: noop
  			};
  		}
  		return this._api;
  	};
  
  	/**
  	 * Sets the module state to READY and either determines the value or sets
  	 * it from the given parameter.
  	 * @param {any} value Module value
  	 */
  	Module.prototype.ready = function(value) {
  		// should throw, but some tests and apps would fail
  		assert(!this.settled, "Module " + this.name + " is already settled");
  		this.state = READY;
  		this.settled = true;
  		if ( arguments.length > 0 ) {
  			// check arguments.length to allow a value of undefined
  			this.content = value;
  		}
  		this.deferred().resolve(wrapExport(this.value()));
  		if ( this.aliases ) {
  			value = this.value();
  			this.aliases.forEach(function(alias) {
  				Module.get(alias).ready(value);
  			});
  		}
  	};
  
  	Module.prototype.fail = function(err) {
  		// should throw, but some tests and apps would fail
  		assert(!this.settled, "Module " + this.name + " is already settled");
  		this.settled = true;
  		if ( this.state !== FAILED ) {
  			this.state = FAILED;
  			this.error = err;
  			this.deferred().reject(err);
  			if ( this.aliases ) {
  				this.aliases.forEach(function(alias) {
  					Module.get(alias).fail(err);
  				});
  			}
  		}
  	};
  
  	Module.prototype.addPending = function(sDependency) {
  		(this.pending || (this.pending = [])).push(sDependency);
  	};
  
  	Module.prototype.addAlias = function(sAliasName) {
  		(this.aliases || (this.aliases = [])).push(sAliasName);
  		// add this module as pending dependency to the original
  		Module.get(sAliasName).addPending(this.name);
  	};
  
  	Module.prototype.preload = function(url, data, bundle) {
  		if ( this.state === INITIAL && !(fnIgnorePreload && fnIgnorePreload(this.name)) ) {
  			this.state = PRELOADED;
  			this.url = url;
  			this.data = data;
  			this.group = bundle;
  		}
  		return this;
  	};
  
  	/**
  	 * Determines the value of this module.
  	 *
  	 * If the module hasn't been loaded or executed yet, <code>undefined</code> will be returned.
  	 *
  	 * @returns {any} Export of the module or <code>undefined</code>
  	 * @private
  	 */
  	Module.prototype.value = function() {
  
  		if ( this.state === READY ) {
  			if ( this.content === NOT_YET_DETERMINED ) {
  				// Determine the module value lazily.
  				// For AMD modules this has already been done on execution of the factory function.
  				// For other modules that are required synchronously, it has been done after execution.
  				// For the few remaining scenarios (like global scripts), it is done here
  				var oShim = mShims[this.name],
  					sExport = oShim && (Array.isArray(oShim.exports) ? oShim.exports[0] : oShim.exports);
  				// best guess for thirdparty modules or legacy modules that don't use sap.ui.define
  				this.content = getGlobalProperty( sExport || urnToUI5(this.name) );
  			}
  			return this.content;
  		}
  
  		return undefined;
  	};
  
  	/**
  	 * Checks whether this module depends on the given module.
  	 *
  	 * When a module definition (define) is executed, the requested dependencies are added
  	 * as 'pending' to the Module instance. This function checks if the oDependantModule is
  	 * reachable from this module when following the pending dependency information.
  	 *
  	 * Note: when module aliases are introduced (all module definitions in a file use an ID that differs
  	 * from the request module ID), then the alias module is also added as a "pending" dependency.
  	 *
  	 * @param {Module} oDependantModule Module which has a dependency to <code>oModule</code>
  	 * @returns {boolean} Whether this module depends on the given one.
  	 * @private
  	 */
  	Module.prototype.dependsOn = function(oDependantModule) {
  		var dependant = oDependantModule.name,
  			visited = Object.create(null);
  
  		// log.debug("checking for a cycle between", this.name, "and", dependant);
  		function visit(mod) {
  			if ( !visited[mod] ) {
  				// log.debug("  ", mod);
  				visited[mod] = true;
  				var pending = mModules[mod] && mModules[mod].pending;
  				return Array.isArray(pending) &&
  					(pending.indexOf(dependant) >= 0 || pending.some(visit));
  			}
  			return false;
  		}
  
  		return this.name === dependant || visit(this.name);
  	};
  
  	/**
  	 * Find or create a module by its unified resource name.
  	 *
  	 * If the module doesn't exist yet, a new one is created in state INITIAL.
  	 *
  	 * @param {string} sModuleName Name of the module in URN syntax
  	 * @returns {Module} Module with that name, newly created if it didn't exist yet
  	 * @static
  	 */
  	Module.get = function(sModuleName) {
  		return mModules[sModuleName] || (mModules[sModuleName] = new Module(sModuleName));
  	};
  
  	/*
  	 * Determines the currently executing module.
  	 */
  	function getExecutingModule() {
  		if ( _execStack.length > 0 ) {
  			return _execStack[_execStack.length - 1].name;
  		}
  		return document.currentScript && document.currentScript.getAttribute("data-sap-ui-module");
  	}
  
  	// --------------------------------------------------------------------------------------------
  
  	var _globalDefine,
  		_globalDefineAMD;
  
  	function updateDefineAndInterceptAMDFlag(newDefine) {
  
  		// no change, do nothing
  		if ( _globalDefine === newDefine ) {
  			return;
  		}
  
  		// first cleanup on an old loader
  		if ( _globalDefine ) {
  			_globalDefine.amd = _globalDefineAMD;
  			_globalDefine =
  			_globalDefineAMD = undefined;
  		}
  
  		// remember the new define
  		_globalDefine = newDefine;
  
  		// intercept access to the 'amd' property of the new define, if it's not our own define
  		if ( newDefine && !newDefine.ui5 ) {
  			_globalDefineAMD = _globalDefine.amd;
  
  			Object.defineProperty(_globalDefine, "amd", {
  				get: function() {
  					var sCurrentModule = getExecutingModule();
  					if ( sCurrentModule && mShims[sCurrentModule] && mShims[sCurrentModule].amd ) {
  						log.debug("suppressing define.amd for " + sCurrentModule);
  						return undefined;
  					}
  					return _globalDefineAMD;
  				},
  				set: function(newDefineAMD) {
  					_globalDefineAMD = newDefineAMD;
  					log.debug("define.amd became " + (newDefineAMD ? "active" : "unset"));
  				},
  				configurable: true // we have to allow a redefine for debug mode or restart from CDN etc.
  			});
  		}
  	}
  
  	try {
  		Object.defineProperty(__global, "define", {
  			get: function() {
  				return _globalDefine;
  			},
  			set: function(newDefine) {
  				updateDefineAndInterceptAMDFlag(newDefine);
  				log.debug("define became " + (newDefine ? "active" : "unset"));
  			},
  			configurable: true // we have to allow a redefine for debug mode or restart from CDN etc.
  		});
  	} catch (e) {
  		log.warning("could not intercept changes to window.define, ui5loader won't be able to a change of the AMD loader");
  	}
  
  	updateDefineAndInterceptAMDFlag(__global.define);
  
  	// --------------------------------------------------------------------------------------------
  
  	function ensureStacktrace(oError) {
  		if (!oError.stack) {
  			try {
  				throw oError;
  			} catch (ex) {
  				return ex;
  			}
  		}
  		return oError;
  	}
  
  	function makeNestedError(msg, cause) {
  		var oError = new Error(msg + ": " + cause.message);
  		oError.cause = cause;
  		oError.loadError = cause.loadError;
  		ensureStacktrace(oError);
  		ensureStacktrace(cause);
  		// concat the error stack for better traceability of loading issues
  		// (ignore for PhantomJS since Error.stack is readonly property!)
  		if ( oError.stack && cause.stack ) {
  			try {
  				oError.stack = oError.stack + "\nCaused by: " + cause.stack;
  			} catch (err) {
  				// ignore
  			}
  		}
  		// @evo-todo
  		// for non Chrome browsers we log the caused by stack manually in the console
  		// if (__global.console && !Device.browser.chrome) {
  		// 	/*eslint-disable no-console */
  		// 	console.error(oError.message + "\nCaused by: " + oCausedByStack);
  		// 	/*eslint-enable no-console */
  		// }
  		return oError;
  	}
  
  	function declareModule(sModuleName) {
  		var oModule;
  
  		// sModuleName must be a unified resource name of type .js
  		assert(/\.js$/.test(sModuleName), "must be a Javascript module");
  
  		oModule = Module.get(sModuleName);
  
  		if ( oModule.state > INITIAL ) {
  			return oModule;
  		}
  
  		if ( log.isLoggable() ) {
  			log.debug(sLogPrefix + "declare module '" + sModuleName + "'");
  		}
  
  		// avoid cycles
  		oModule.state = READY;
  
  		return oModule;
  	}
  
  	/**
  	 * Define an already loaded module synchronously.
  	 * Finds or creates a module by its unified resource name and resolves it with the given value.
  	 *
  	 * @param {string} sResourceName Name of the module in URN syntax
  	 * @param {any} vValue Content of the module
  	 */
  	function defineModuleSync(sResourceName, vValue) {
  		Module.get(sResourceName).ready(vValue);
  	}
  
  	/**
  	 * Queue of modules for which sap.ui.define has been called (in async mode), but which have not been executed yet.
  	 * When loading modules via script tag, only the onload handler knows the relationship between executed sap.ui.define calls and
  	 * module name. It then resolves the pending modules in the queue. Only one entry can get the name of the module
  	 * if there are more entries, then this is an error
  	 */
  	var queue = new function ModuleDefinitionQueue() {
  		var aQueue = [],
  			iRun = 0,
  			vTimer;
  
  		this.push = function(name, deps, factory, _export) {
  			if ( log.isLoggable() ) {
  				log.debug("pushing define() call"
  					+ (document.currentScript ? " from " + document.currentScript.src : "")
  					+ " to define queue #" + iRun);
  			}
  			aQueue.push({
  				name: name,
  				deps: deps,
  				factory: factory,
  				_export: _export,
  				guess: document.currentScript && document.currentScript.getAttribute('data-sap-ui-module')
  			});
  
  			// trigger queue processing via a timer in case the currently executing script is not managed by the loader
  			if ( !vTimer ) {
  				vTimer = setTimeout(this.process.bind(this, null, "timer"));
  			}
  		};
  
  		this.clear = function() {
  			aQueue = [];
  			if ( vTimer ) {
  				clearTimeout(vTimer);
  				vTimer = null;
  			}
  		};
  
  		/**
  		 * Process the queue of module definitions, assuming that the original request was for
  		 * <code>oRequestedModule</code>. If there is an unnamed module definition, it is assumed to be
  		 * the one for the requested module.
  		 *
  		 * When called via timer, <code>oRequestedModule</code> will be undefined.
  		 *
  		 * @param {Module} [oRequestedModule] Module for which the current script was loaded.
  		 * @param {string} [sInitiator] A string describing the caller of <code>process</code>
  		 */
  		this.process = function(oRequestedModule, sInitiator) {
  			var bLoggable = log.isLoggable(),
  				iCurrentRun = iRun++,
  				aQueueCopy = aQueue,
  				sModuleName = null;
  
  			// clear the queue and timer early, we've already taken a copy of the queue
  			this.clear();
  
  
  			if ( oRequestedModule ) {
  
  				// if a module execution error was detected, stop processing the queue
  				if ( oRequestedModule.execError ) {
  					if ( bLoggable ) {
  						log.debug("module execution error detected, ignoring queued define calls (" + aQueueCopy.length + ")");
  					}
  					oRequestedModule.fail(oRequestedModule.execError);
  					return;
  				}
  
  			}
  
  			/*
  			 * Name of the requested module, null when unknown or already consumed.
  			 *
  			 *  - when no module request is known (e.g. script was embedded in the page as an unmanaged script tag),
  			 *    then no name is known and unnamed module definitions will be reported as an error
  			 *  - multiple unnamed module definitions also are reported as an error
  			 *  - when the name of a named module definition matches the name of requested module, the name is 'consumed'.
  			 *    Any later unnamed module definition will be reported as an error, too
  			 */
  			sModuleName = oRequestedModule && oRequestedModule.name;
  
  			// check whether there's a module definition for the requested module
  			aQueueCopy.forEach(function(oEntry) {
  				if ( oEntry.name == null ) {
  					if ( sModuleName != null ) {
  						oEntry.name = sModuleName;
  						sModuleName = null;
  					} else {
  						// multiple modules have been queued, but only one module can inherit the name from the require call
  						if ( strictModuleDefinitions ) {
  							var oError = new Error(
  								"Modules that use an anonymous define() call must be loaded with a require() call; " +
  								"they must not be executed via script tag or nested into other modules. ");
  							if ( oRequestedModule ) {
  								oRequestedModule.fail(oError);
  							} else {
  								throw oError;
  							}
  						}
  						// give anonymous modules a unique pseudo ID
  						oEntry.name = '~anonymous~' + (++iAnonymousModuleCount) + '.js';
  						log.error(
  							"Modules that use an anonymous define() call must be loaded with a require() call; " +
  							"they must not be executed via script tag or nested into other modules. " +
  							"All other usages will fail in future releases or when standard AMD loaders are used. " +
  							"Now using substitute name " + oEntry.name);
  					}
  				} else if ( oRequestedModule && oEntry.name === oRequestedModule.name ) {
  					if ( sModuleName == null && !strictModuleDefinitions ) {
  						// if 'strictModuleDefinitions' is active, double execution will be reported anyhow
  						log.error(
  							"Duplicate module definition: both, an unnamed module and a module with the expected name exist." +
  							"This use case will fail in future releases or when standard AMD loaders are used. ");
  					}
  					sModuleName = null;
  				}
  			});
  
  			// if not, assign an alias if there's at least one queued module definition
  			if ( sModuleName && aQueueCopy.length > 0 ) {
  				if ( bLoggable ) {
  					log.debug(
  						"No queued module definition matches the ID of the request. " +
  						"Now assuming that the first definition '" + aQueueCopy[0].name + "' is an alias of '" + sModuleName + "'");
  				}
  				Module.get(aQueueCopy[0].name).addAlias(sModuleName);
  				sModuleName = null;
  			}
  
  			if ( bLoggable ) {
  				log.debug(sLogPrefix + "[" + sInitiator + "] "
  					+ "processing define queue #" + iCurrentRun
  					+ (oRequestedModule ? " for '" + oRequestedModule.name + "'" : "")
  					+ " with entries [" + aQueueCopy.map(function(entry) { return "'" + entry.name + "'"; }) + "]");
  			}
  
  			aQueueCopy.forEach(function(oEntry) {
  				// start to resolve the dependencies
  				executeModuleDefinition(oEntry.name, oEntry.deps, oEntry.factory, oEntry._export, /* bAsync = */ true);
  			});
  
  			if ( sModuleName != null && !oRequestedModule.settled ) {
  				// module name still not consumed, might be a non-UI5 module (e.g. in 'global' format)
  				if ( bLoggable ) {
  					log.debug(sLogPrefix + "no queued module definition for the requested module found, assume the module to be ready");
  				}
  				oRequestedModule.data = undefined; // allow GC
  				oRequestedModule.ready(); // no export known, has to be retrieved via global name
  			}
  
  			if ( bLoggable ) {
  				log.debug(sLogPrefix + "processing define queue #" + iCurrentRun + " done");
  			}
  		};
  	}();
  
  	/**
  	 * Loads the source for the given module with a sync XHR.
  	 * @param {Module} oModule Module to load the source for
  	 * @throws {Error} When loading failed for some reason.
  	 */
  	function loadSyncXHR(oModule) {
  		var xhr = new XMLHttpRequest();
  
  		function enrichXHRError(error) {
  			error = error || ensureStacktrace(new Error(xhr.status + " - " + xhr.statusText));
  			error.status = xhr.status;
  			error.statusText = xhr.statusText;
  			error.loadError = true;
  			return error;
  		}
  
  		xhr.addEventListener('load', function(e) {
  			// File protocol (file://) always has status code 0
  			if ( xhr.status === 200 || xhr.status === 0 ) {
  				oModule.state = LOADED;
  				oModule.data = xhr.responseText;
  			} else {
  				oModule.error = enrichXHRError();
  			}
  		});
  		// Note: according to whatwg spec, error event doesn't fire for sync send(), instead an error is thrown
  		// we register a handler, in case a browser doesn't follow the spec
  		xhr.addEventListener('error', function(e) {
  			oModule.error = enrichXHRError();
  		});
  		xhr.open('GET', oModule.url, false);
  		try {
  			xhr.send();
  		} catch (error) {
  			oModule.error = enrichXHRError(error);
  		}
  	}
  
  	/**
  	 * Global event handler to detect script execution errors.
  	 * Only works for browsers that support <code>document.currentScript</code>.
  	 * @private
  	 */
  	if ( 'currentScript' in document ) {
  		window.addEventListener('error', function onUncaughtError(errorEvent) {
  			var sModuleName = document.currentScript && document.currentScript.getAttribute('data-sap-ui-module');
  			var oModule = sModuleName && Module.get(sModuleName);
  			if ( oModule && oModule.execError == null ) {
  				// if a currently executing module can be identified, attach the error to it and suppress reporting
  				if ( log.isLoggable() ) {
  					log.debug("unhandled exception occurred while executing " + sModuleName + ": " + errorEvent.message);
  				}
  				oModule.execError = errorEvent.error || {
  					name: 'Error',
  					message: errorEvent.message
  				};
  				return false;
  			}
  		});
  	}
  
  	function loadScript(oModule, sAlternativeURL) {
  
  		var oScript;
  
  		function onload(e) {
  			if ( log.isLoggable() ) {
  				log.debug("JavaScript resource loaded: " + oModule.name);
  			}
  			oScript.removeEventListener('load', onload);
  			oScript.removeEventListener('error', onerror);
  			queue.process(oModule, "onload");
  		}
  
  		function onerror(e) {
  			oScript.removeEventListener('load', onload);
  			oScript.removeEventListener('error', onerror);
  			if (sAlternativeURL) {
  				log.warning("retry loading JavaScript resource: " + oModule.name);
  				if (oScript && oScript.parentNode) {
  					oScript.parentNode.removeChild(oScript);
  				}
  				oModule.url = sAlternativeURL;
  				loadScript(oModule, /* sAlternativeURL= */ null);
  				return;
  			}
  
  			log.error("failed to load JavaScript resource: " + oModule.name);
  			oModule.fail(
  				ensureStacktrace(new Error("failed to load '" + oModule.name +  "' from " + oModule.url + ": script load error")));
  		}
  
  		oScript = document.createElement('SCRIPT');
  		// Accessing the 'src' property of the script in this strange way prevents Safari 12 (or WebKit) from
  		// wrongly optimizing access. SF12 seems to check at optimization time whether there's a setter for the
  		// property and optimize accordingly. When a setter is defined or changed at a later point in time (e.g.
  		// by the AppCacheBuster), then the optimization seems not to be updated and the new setter is ignored
  		// BCP 1970035485
  		oScript["s" + "rc"] = oModule.url;
  		//oScript.src = oModule.url;
  		oScript.setAttribute("data-sap-ui-module", oModule.name);
  		if ( sAlternativeURL !== undefined ) {
  			if ( mShims[oModule.name] && mShims[oModule.name].amd ) {
  				oScript.setAttribute("data-sap-ui-module-amd", "true");
  			}
  			oScript.addEventListener('load', onload);
  			oScript.addEventListener('error', onerror);
  		}
  		document.head.appendChild(oScript);
  
  	}
  
  	function preloadDependencies(sModuleName) {
  		var knownDependencies = mDepCache[sModuleName];
  		if ( Array.isArray(knownDependencies) ) {
  			log.debug("preload dependencies for " + sModuleName + ": " + knownDependencies);
  			knownDependencies.forEach(function(dep) {
  				dep = getMappedName(dep, sModuleName);
  				if ( /\.js$/.test(dep) ) {
  					requireModule(null, dep, /* always async */ true);
  				} // else: TODO handle non-JS resources, e.g. link rel=prefetch
  			});
  		}
  	}
  
  	/**
  	 * Loads the given module if needed and returns the module export or a promise on it.
  	 *
  	 * If loading is still ongoing for the requested module and if there is a cycle detected between
  	 * the requesting module and the module to be loaded, then <code>undefined</code> (or a promise on
  	 * <code>undefined</code>) will be returned as intermediate module export to resolve the cycle.
  	 *
  	 * @param {Module} oRequestingModule The module in whose context the new module has to be loaded;
  	 *           this is needed to detect cycles
  	 * @param {string} sModuleName Name of the module to be loaded, in URN form and with '.js' extension
  	 * @param {boolean} bAsync Whether the operation can be executed asynchronously
  	 * @param {boolean} bSkipShimDeps Whether shim dependencies should be ignored
  	 * @returns {any|Promise} Returns the module export in sync mode or a promise on it in async mode
  	 * @throws {Error} When loading failed in sync mode
  	 *
  	 * @private
  	 */
  	function requireModule(oRequestingModule, sModuleName, bAsync, bSkipShimDeps) {
  
  		var bLoggable = log.isLoggable(),
  			oSplitName = urnToBaseIDAndSubType(sModuleName),
  			oShim = mShims[sModuleName],
  			oModule, aExtensions, i, sMsg, bExecutedNow;
  
  		// only for robustness, should not be possible by design (all callers append '.js')
  		if ( !oSplitName ) {
  			throw new Error("can only require Javascript module, not " + sModuleName);
  		}
  
  		// Module names should not start with a "/"
  		if (sModuleName[0] == "/") {
  			log.error("Module names that start with a slash should not be used, as they are reserved for future use.");
  		}
  
  		oModule = Module.get(sModuleName);
  
  		// when there's a shim with dependencies for the module
  		// resolve them first before requiring the module again with bSkipShimDeps = true
  		if ( oShim && oShim.deps && !bSkipShimDeps ) {
  			if ( bLoggable ) {
  				log.debug("require dependencies of raw module " + sModuleName);
  			}
  			return requireAll(oModule, oShim.deps, function() {
  				return requireModule(oRequestingModule, sModuleName, bAsync, /* bSkipShimDeps = */ true);
  			}, function(oErr) {
  				oModule.fail(oErr);
  				if ( bAsync ) {
  					return;
  				}
  				throw oErr;
  			}, bAsync);
  		}
  
  		if ( bLoggable ) {
  			log.debug(sLogPrefix + "require '" + sModuleName + "'"
  					+ (oRequestingModule ? " (dependency of '" + oRequestingModule.name + "')" : ""));
  		}
  
  		// check if module has been loaded already
  		if ( oModule.state !== INITIAL ) {
  			if ( oModule.state === PRELOADED ) {
  				oModule.state = LOADED;
  				oModule.async = bAsync;
  				bExecutedNow = true;
  				measure && measure.start(sModuleName, "Require module " + sModuleName + " (preloaded)", ["require"]);
  				execModule(sModuleName, bAsync);
  				measure && measure.end(sModuleName);
  			}
  
  			if ( oModule.state === READY ) {
  				if ( !bExecutedNow && bLoggable ) {
  					log.debug(sLogPrefix + "module '" + sModuleName + "' has already been loaded (skipped).");
  				}
  				// Note: this intentionally does not return oModule.promise() as the export might be temporary in case of cycles
  				// or it might have changed after repeated module execution
  				return bAsync ? Promise.resolve(wrapExport(oModule.value())) : wrapExport(oModule.value());
  			} else if ( oModule.state === FAILED ) {
  				if ( bAsync ) {
  					return oModule.deferred().promise;
  				} else {
  					throw (bExecutedNow
  						? oModule.error
  						: makeNestedError("found in negative cache: '" + sModuleName + "' from " + oModule.url, oModule.error));
  				}
  			} else {
  				// currently loading or executing
  				if ( bAsync ) {
  					// break up cyclic dependencies
  					if ( oRequestingModule && oModule.dependsOn(oRequestingModule) ) {
  						if ( log.isLoggable() ) {
  							log.debug("cycle detected between '" + oRequestingModule.name + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'");
  						}
  						// Note: this must be a separate promise as the fulfillment is not the final one
  						return Promise.resolve(wrapExport(undefined));
  					}
  					return oModule.deferred().promise;
  				}
  				if ( !bAsync && !oModule.async ) {
  					// sync pending, return undefined
  					if ( log.isLoggable() ) {
  						log.debug("cycle detected between '" + (oRequestingModule ? oRequestingModule.name : "unknown") + "' and '" + sModuleName + "', returning undefined for '" + sModuleName + "'");
  					}
  					return wrapExport(undefined);
  				}
  				// async pending, load sync again
  				log.warning("Sync request triggered for '" + sModuleName + "' while async request was already pending." +
  					" Loading a module twice might cause issues and should be avoided by fully migrating to async APIs.");
  			}
  		}
  
  		if ( isIE11 && bAsync && oShim && oShim.amd ) {
  			// in IE11, we force AMD/UMD modules into sync loading to apply the define.amd workaround
  			// in other browsers, we intercept read access to window.define, see ensureDefineInterceptor
  			bAsync = false;
  		}
  
  		measure && measure.start(sModuleName, "Require module " + sModuleName, ["require"]);
  
  		// set marker for loading modules (to break cycles)
  		oModule.state = LOADING;
  		oModule.async = bAsync;
  
  		// if debug is enabled, try to load debug module first
  		aExtensions = bDebugSources ? ["-dbg", ""] : [""];
  		if ( !bAsync ) {
  
  			for (i = 0; i < aExtensions.length && oModule.state !== LOADED; i++) {
  				// create module URL for the current extension
  				oModule.url = getResourcePath(oSplitName.baseID, aExtensions[i] + oSplitName.subType);
  				if ( bLoggable ) {
  					log.debug(sLogPrefix + "loading " + (aExtensions[i] ? aExtensions[i] + " version of " : "") + "'" + sModuleName + "' from '" + oModule.url + "' (using sync XHR)");
  				}
  
  				if ( syncCallBehavior ) {
  					sMsg = "[nosync] loading module '" + oModule.url + "'";
  					if ( syncCallBehavior === 1 ) {
  						log.error(sMsg);
  					} else {
  						throw new Error(sMsg);
  					}
  				}
  
  				// call notification hook
  				ui5Require.load({ completeLoad:noop, async: false }, oModule.url, oSplitName.baseID);
  
  				loadSyncXHR(oModule);
  			}
  
  			if ( oModule.state === LOADING ) {
  				// transition to FAILED
  				oModule.fail(
  					makeNestedError("failed to load '" + sModuleName +  "' from " + oModule.url, oModule.error));
  			} else if ( oModule.state === LOADED ) {
  				// execute module __after__ loading it, this reduces the required stack space!
  				execModule(sModuleName, bAsync);
  			}
  
  			measure && measure.end(sModuleName);
  
  			if ( oModule.state !== READY ) {
  				// loading or executing failed for some reason, load again as script for better error reporting
  				// (but without further eventing)
  				if ( fnIgnorePreload ) {
  					loadScript(oModule);
  				}
  				throw oModule.error;
  			}
  
  			return wrapExport(oModule.value());
  
  		} else {
  
  			oModule.url = getResourcePath(oSplitName.baseID, aExtensions[0] + oSplitName.subType);
  			// in debug mode, fall back to the non-dbg source, otherwise try the same source again (for SSO re-connect)
  			var sAltUrl = bDebugSources ? getResourcePath(oSplitName.baseID, aExtensions[1] + oSplitName.subType) : oModule.url;
  
  			if ( log.isLoggable() ) {
  				log.debug(sLogPrefix + "loading '" + sModuleName + "' from '" + oModule.url + "' (using <script>)");
  			}
  
  			// call notification hook only once
  			ui5Require.load({ completeLoad:noop, async: true }, sAltUrl, oSplitName.baseID);
  			loadScript(oModule, /* sAlternativeURL= */ sAltUrl);
  
  			// process dep cache info
  			preloadDependencies(sModuleName);
  
  			return oModule.deferred().promise;
  		}
  	}
  
  	// sModuleName must be a normalized resource name of type .js
  	function execModule(sModuleName, bAsync) {
  
  		var oModule = mModules[sModuleName],
  			bLoggable = log.isLoggable(),
  			sOldPrefix, sScript, oMatch, bOldForceSyncDefines;
  
  		if ( oModule && oModule.state === LOADED && typeof oModule.data !== "undefined" ) {
  
  			bOldForceSyncDefines = bForceSyncDefines;
  
  			try {
  
  				bForceSyncDefines = !bAsync;
  
  				if ( bLoggable ) {
  					if ( typeof oModule.data === "string" ) {
  						log.warning(sLogPrefix + "executing '" + sModuleName + "' (using eval)");
  					} else {
  						log.debug(sLogPrefix + "executing '" + sModuleName + "'");
  					}
  					sOldPrefix = sLogPrefix;
  					sLogPrefix = sLogPrefix + ": ";
  				}
  
  				// execute the script in the __global context
  				oModule.state = EXECUTING;
  				_execStack.push({
  					name: sModuleName,
  					used: false
  				});
  				if ( typeof oModule.data === "function" ) {
  					oModule.data.call(__global);
  				} else if ( Array.isArray(oModule.data) ) {
  					ui5Define.apply(null, oModule.data);
  				} else {
  
  					sScript = oModule.data;
  
  					// sourceURL: Firebug, Chrome, Safari and IE11 debugging help, appending the string seems to cost ZERO performance
  					// Note: IE11 supports sourceURL even when running in IE9 or IE10 mode
  					// Note: make URL absolute so Chrome displays the file tree correctly
  					// Note: do not append if there is already a sourceURL / sourceMappingURL
  					// Note: Safari fails, if sourceURL is the same as an existing XHR URL
  					// Note: Chrome ignores debug files when the same URL has already been load via sourcemap of the bootstrap file (sap-ui-core)
  					// Note: sourcemap annotations URLs in eval'ed sources are resolved relative to the page, not relative to the source
  					if (sScript ) {
  						oMatch = /\/\/[#@] source(Mapping)?URL=(.*)$/.exec(sScript);
  						if ( oMatch && oMatch[1] && /^[^/]+\.js\.map$/.test(oMatch[2]) ) {
  							// found a sourcemap annotation with a typical UI5 generated relative URL
  							sScript = sScript.slice(0, oMatch.index) + oMatch[0].slice(0, -oMatch[2].length) + resolveURL(oMatch[2], oModule.url);
  						}
  						// @evo-todo use only sourceMappingURL, sourceURL or both?
  						if ( !oMatch || oMatch[1] ) {
  							// write sourceURL if no annotation was there or when it was a sourceMappingURL
  							sScript += "\n//# sourceURL=" + resolveURL(oModule.url) + "?eval";
  						}
  					}
  
  					// framework internal hook to intercept the loaded script and modify
  					// it before executing the script - e.g. useful for client side coverage
  					if (typeof translate === "function") {
  						sScript = translate(sScript, sModuleName);
  					}
  
  					if (__global.execScript && (!oModule.data || oModule.data.length < MAX_EXEC_SCRIPT_LENGTH) ) {
  						try {
  							oModule.data && __global.execScript(sScript); // execScript fails if data is empty
  						} catch (e) {
  							_execStack.pop();
  							// eval again with different approach - should fail with a more informative exception
  							/* eslint-disable no-eval */
  							eval(oModule.data);
  							/* eslint-enable no-eval */
  							throw e; // rethrow err in case globalEval succeeded unexpectedly
  						}
  					} else {
  						__global.eval(sScript);
  					}
  				}
  				_execStack.pop();
  				queue.process(oModule, "after eval");
  
  				if ( bLoggable ) {
  					sLogPrefix = sOldPrefix;
  					log.debug(sLogPrefix + "finished executing '" + sModuleName + "'");
  				}
  
  			} catch (err) {
  				if ( bLoggable ) {
  					sLogPrefix = sOldPrefix;
  				}
  				oModule.data = undefined;
  				oModule.fail(err);
  			} finally {
  
  				bForceSyncDefines = bOldForceSyncDefines;
  			}
  		}
  	}
  
  	function requireAll(oRequestingModule, aDependencies, fnCallback, fnErrCallback, bAsync) {
  
  		var sBaseName, aModules = [],
  			i, sDepModName, oError, oPromise;
  
  		try {
  			// calculate the base name for relative module names
  			if ( oRequestingModule instanceof Module ) {
  				sBaseName = oRequestingModule.name;
  			} else {
  				sBaseName = oRequestingModule;
  				oRequestingModule = null;
  			}
  			aDependencies = aDependencies.slice();
  			for (i = 0; i < aDependencies.length; i++) {
  				aDependencies[i] = getMappedName(aDependencies[i] + '.js', sBaseName);
  			}
  			if ( oRequestingModule ) {
  				// remember outgoing dependencies to be able to detect cycles, but ignore pseudo-dependencies
  				aDependencies.forEach(function(dep) {
  					if ( !/^(require|exports|module)\.js$/.test(dep) ) {
  						oRequestingModule.addPending(dep);
  					}
  				});
  			}
  
  			for (i = 0; i < aDependencies.length; i++) {
  				sDepModName = aDependencies[i];
  				if ( oRequestingModule ) {
  					switch ( sDepModName ) {
  					case 'require.js':
  						// the injected local require should behave like the Standard require (2nd argument = true)
  						aModules[i] = wrapExport(createContextualRequire(sBaseName, true));
  						break;
  					case 'module.js':
  						aModules[i] = wrapExport(oRequestingModule.api());
  						break;
  					case 'exports.js':
  						oRequestingModule.api();
  						aModules[i] = wrapExport(oRequestingModule._exports);
  						break;
  					default:
  						break;
  					}
  				}
  				if ( !aModules[i] ) {
  					aModules[i] = requireModule(oRequestingModule, sDepModName, bAsync);
  				}
  			}
  
  		} catch (err) {
  			oError = err;
  		}
  
  		if ( bAsync ) {
  			oPromise = oError ? Promise.reject(oError) : Promise.all(aModules);
  			return oPromise.then(fnCallback, fnErrCallback);
  		} else {
  			if ( oError ) {
  				fnErrCallback(oError);
  			} else {
  				return fnCallback(aModules);
  			}
  		}
  	}
  
  	function executeModuleDefinition(sResourceName, aDependencies, vFactory, bExport, bAsync) {
  		var bLoggable = log.isLoggable();
  		sResourceName = normalize(sResourceName);
  
  		if ( bLoggable ) {
  			log.debug(sLogPrefix + "define('" + sResourceName + "', " + "['" + aDependencies.join("','") + "']" + ")");
  		}
  
  		var oModule = declareModule(sResourceName);
  
  		var repeatedExecutionReported = false;
  
  		function shouldSkipExecution() {
  			if ( oModule.settled ) {
  				// avoid double execution of the module, e.g. when async/sync conflict occurred before queue processing
  				if ( oModule.state >= READY && bAsync && oModule.async === false ) {
  					log.warning("Repeated module execution skipped after async/sync conflict for " + oModule.name);
  					return true;
  				}
  
  				// when an inline module definition is executed repeatedly, this is reported but not prevented
  				// Standard AMD loaders don't support this scenario, it needs to be fixed on caller side
  				if ( strictModuleDefinitions && bAsync ) {
  					log.warning("Module '" + oModule.name + "' has been defined more than once. " +
  							"All but the first definition will be ignored, don't try to define the same module again.");
  					return true;
  				}
  
  				if ( !repeatedExecutionReported ) {
  					log.error(
  						"Module '" + oModule.name + "' is executed more than once. " +
  						"This is an unsupported scenario and will fail in future versions of UI5 or " +
  						"when a standard AMD loader is used. Don't define the same module again.");
  					repeatedExecutionReported = true;
  				}
  			}
  		}
  
  		if ( shouldSkipExecution() ) {
  			return;
  		}
  
  		// avoid early evaluation of the module value
  		oModule.content = undefined;
  
  		// Note: dependencies will be resolved and converted from RJS to URN inside requireAll
  		requireAll(oModule, aDependencies, function(aModules) {
  
  			// avoid double execution of the module, e.g. when async/sync conflict occurred while waiting for dependencies
  			if ( shouldSkipExecution() ) {
  				return;
  			}
  
  			// factory
  			if ( bLoggable ) {
  				log.debug(sLogPrefix + "define('" + sResourceName + "'): dependencies resolved, calling factory " + typeof vFactory);
  			}
  
  			if ( bExport && syncCallBehavior !== 2 ) {
  				// ensure parent namespace
  				var aPackages = sResourceName.split('/');
  				if ( aPackages.length > 1 ) {
  					getGlobalObject(__global, aPackages, aPackages.length - 1, true);
  				}
  			}
  
  			if ( typeof vFactory === 'function' ) {
  				// from https://github.com/amdjs/amdjs-api/blob/master/AMD.md
  				// "If the factory function returns a value (an object, function, or any value that coerces to true),
  				//  then that value should be assigned as the exported value for the module."
  				try {
  					aModules = aModules.map(unwrapExport);
  					var exports = vFactory.apply(__global, aModules);
  					if ( oModule._api && oModule._api.exports !== undefined && oModule._api.exports !== oModule._exports ) {
  						exports = oModule._api.exports;
  					} else if ( exports === undefined && oModule._exports ) {
  						exports = oModule._exports;
  					}
  					oModule.content = exports;
  				} catch (error) {
  					oModule.fail(error);
  					if ( bAsync ) {
  						return;
  					}
  					throw error;
  				}
  			} else {
  				oModule.content = vFactory;
  			}
  
  			// HACK: global export
  			if ( bExport && syncCallBehavior !== 2 ) {
  				if ( oModule.content == null ) {
  					log.error("Module '" + sResourceName + "' returned no content, but should export to global?");
  				} else {
  					if ( bLoggable ) {
  						log.debug("exporting content of '" + sResourceName + "': as global object");
  					}
  					// convert module name to UI5 module name syntax (might fail!)
  					var sModuleName = urnToUI5(sResourceName);
  					setGlobalProperty(sModuleName, oModule.content);
  				}
  			}
  
  			oModule.ready();
  
  		}, function(oErr) {
  			// @evo-todo wrap error with current module?
  			oModule.fail(oErr);
  			if ( !bAsync ) {
  				throw oErr;
  			}
  		}, /* bAsync = */ bAsync);
  
  	}
  
  	function ui5Define(sModuleName, aDependencies, vFactory, bExport) {
  		var sResourceName,
  			oCurrentExecInfo;
  
  		// optional id
  		if ( typeof sModuleName === 'string' ) {
  			sResourceName = sModuleName + '.js';
  		} else {
  			// shift parameters
  			bExport = vFactory;
  			vFactory = aDependencies;
  			aDependencies = sModuleName;
  			sResourceName = null;
  		}
  
  		// optional array of dependencies
  		if ( !Array.isArray(aDependencies) ) {
  			// shift parameters
  			bExport = vFactory;
  			vFactory = aDependencies;
  			if ( typeof vFactory === 'function' && vFactory.length > 0 ) {
  				aDependencies = ['require', 'exports', 'module'].slice(0, vFactory.length);
  			} else {
  				aDependencies = [];
  			}
  		}
  
  		if ( bForceSyncDefines === false || (bForceSyncDefines == null && bGlobalAsyncMode) ) {
  			queue.push(sResourceName, aDependencies, vFactory, bExport);
  			if ( sResourceName != null ) {
  				var oModule = Module.get(sResourceName);
  				if ( oModule.state === INITIAL ) {
  					oModule.state = EXECUTING;
  					oModule.async = true;
  				}
  			}
  			return;
  		}
  
  		// immediate, synchronous execution
  		oCurrentExecInfo = _execStack.length > 0 ? _execStack[_execStack.length - 1] : null;
  		if ( !sResourceName ) {
  
  			if ( oCurrentExecInfo && !oCurrentExecInfo.used ) {
  				sResourceName = oCurrentExecInfo.name;
  				oCurrentExecInfo.used = true;
  			} else {
  				// give anonymous modules a unique pseudo ID
  				sResourceName = '~anonymous~' + (++iAnonymousModuleCount) + '.js';
  				if ( oCurrentExecInfo ) {
  					sResourceName = oCurrentExecInfo.name.slice(0, oCurrentExecInfo.name.lastIndexOf('/') + 1) + sResourceName;
  				}
  				log.error(
  					"Modules that use an anonymous define() call must be loaded with a require() call; " +
  					"they must not be executed via script tag or nested into other modules. " +
  					"All other usages will fail in future releases or when standard AMD loaders are used " +
  					"or when ui5loader runs in async mode. Now using substitute name " + sResourceName);
  			}
  		} else if ( oCurrentExecInfo && !oCurrentExecInfo.used && sResourceName !== oCurrentExecInfo.name ) {
  			log.debug("module names don't match: requested: " + sModuleName + ", defined: ", oCurrentExecInfo.name);
  			Module.get(oCurrentExecInfo.name).addAlias(sModuleName);
  		}
  		executeModuleDefinition(sResourceName, aDependencies, vFactory, bExport, /* bAsync = */ false);
  
  	}
  
  	/**
  	 * The amdDefine() function is closer to the AMD spec, as opposed to sap.ui.define.
  	 * It's later assigned as the global define() if the loader is running in amd=true
  	 * mode (has to be configured explicitly).
  	 */
  	function amdDefine(sModuleName, aDependencies, vFactory) {
  		var oArgs = arguments;
  		var bExportIsSet = typeof oArgs[oArgs.length - 1] === "boolean";
  
  		// bExport parameter is proprietary and should not be used for an AMD compliant define()
  		if (bExportIsSet) {
  			oArgs = Array.prototype.slice.call(oArgs, 0, oArgs.length - 1);
  		}
  
  		ui5Define.apply(this, oArgs);
  	}
  	amdDefine.amd = {}; // identify as AMD-spec compliant loader
  	amdDefine.ui5 = {}; // identify as ui5loader
  
  
  	/**
  	 * Create a require() function which acts in the context of the given resource.
  	 *
  	 * @param {string|null} sContextName Name of the context resource (module) in URN syntax, incl. extension
  	 * @param {boolean} bAMDCompliance If set to true, the behavior of the require() function is closer to the AMD specification.
  	 * @returns {function} Require function.
  	 */
  	function createContextualRequire(sContextName, bAMDCompliance) {
  		var fnRequire = function(vDependencies, fnCallback, fnErrCallback) {
  			var sModuleName;
  
  			assert(typeof vDependencies === 'string' || Array.isArray(vDependencies), "dependency param either must be a single string or an array of strings");
  			assert(fnCallback == null || typeof fnCallback === 'function', "callback must be a function or null/undefined");
  			assert(fnErrCallback == null || typeof fnErrCallback === 'function', "error callback must be a function or null/undefined");
  
  			// Probing for existing module
  			if ( typeof vDependencies === 'string' ) {
  				sModuleName = getMappedName(vDependencies + '.js', sContextName);
  				var oModule = Module.get(sModuleName);
  
  				// check the modules internal state
  				// everything from PRELOADED to LOADED (incl. FAILED) is considered erroneous
  				if (bAMDCompliance && oModule.state !== EXECUTING && oModule.state !== READY) {
  					throw new Error(
  						"Module '" + sModuleName + "' has not been loaded yet. " +
  						"Use require(['" + sModuleName + "']) to load it."
  					);
  				}
  
  				// Module is in state READY or EXECUTING; or require() was called from sap.ui.require().
  				// A modules value might be undefined (no return statement) even though the state is READY.
  				return oModule.value();
  			}
  
  			requireAll(sContextName, vDependencies, function(aModules) {
  				aModules = aModules.map(unwrapExport);
  				if ( typeof fnCallback === 'function' ) {
  					if ( bGlobalAsyncMode ) {
  						fnCallback.apply(__global, aModules);
  					} else {
  						// enforce asynchronous execution of callback even in sync mode
  						simulateAsyncCallback(function() {
  							fnCallback.apply(__global, aModules);
  						});
  					}
  				}
  			}, function(oErr) {
  				if ( typeof fnErrCallback === 'function' ) {
  					if ( bGlobalAsyncMode ) {
  						fnErrCallback.call(__global, oErr);
  					} else {
  						simulateAsyncCallback(function() {
  							fnErrCallback.call(__global, oErr);
  						});
  					}
  				} else {
  					throw oErr;
  				}
  			}, /* bAsync = */ bGlobalAsyncMode);
  
  			// return undefined;
  		};
  		fnRequire.toUrl = function(sName) {
  			var sMappedName = ensureTrailingSlash(getMappedName(sName, sContextName), sName);
  			return toUrl(sMappedName);
  		};
  		return fnRequire;
  	}
  
  	function ensureTrailingSlash(sName, sInput) {
  		//restore trailing slash
  		if (sInput.slice(-1) === "/" && sName.slice(-1) !== "/") {
  			return sName + "/";
  		}
  		return sName;
  	}
  
  	function toUrl(sName) {
  		if (sName.indexOf("/") === 0) {
  			throw new Error("The provided argument '" + sName + "' may not start with a slash");
  		}
  		return ensureTrailingSlash(getResourcePath(sName), sName);
  	}
  
  	/*
  	 * UI5 version of require (sap.ui.require)
  	 */
  	var ui5Require = createContextualRequire(null, false);
  
  	/*
  	 * AMD version of require (window.require)
  	 *
  	 * Difference between require (sap.ui.require) and amdRequire (window.require):
  	 * - require("my/module"), returns undefined if the module was not loaded yet
  	 * - amdRequire("my/module"), throws an error if the module was not loaded yet
  	 */
  	var amdRequire = createContextualRequire(null, true);
  
  	function requireSync(sModuleName) {
  		sModuleName = getMappedName(sModuleName + '.js');
  		if ( log.isLoggable() ) {
  			log.warning("sync require of '" + sModuleName + "'");
  		}
  		return unwrapExport(requireModule(null, sModuleName, /* bAsync = */ false));
  	}
  
  	function predefine(sModuleName, aDependencies, vFactory, bExport) {
  		if ( typeof sModuleName !== 'string' ) {
  			throw new Error("predefine requires a module name");
  		}
  		sModuleName = normalize(sModuleName);
  		Module.get(sModuleName + '.js').preload("<unknown>/" + sModuleName, [sModuleName, aDependencies, vFactory, bExport], null);
  	}
  
  	function preload(modules, group, url) {
  		group = group || null;
  		url = url || "<unknown>";
  		for ( var name in modules ) {
  			name = normalize(name);
  			Module.get(name).preload(url + "/" + name, modules[name], group);
  		}
  	}
  
  	/**
  	 * Dumps information about the current set of modules and their state.
  	 *
  	 * @param {int} [iThreshold=-1] Earliest module state for which odules should be reported
  	 * @private
  	 */
  	function dumpInternals(iThreshold) {
  
  		var states = [PRELOADED, INITIAL, LOADED, READY, FAILED, EXECUTING, LOADING];
  		var stateNames = {};
  		stateNames[PRELOADED] = 'PRELOADED';
  		stateNames[INITIAL] = 'INITIAL';
  		stateNames[LOADING] = 'LOADING';
  		stateNames[LOADED] = 'LOADED';
  		stateNames[EXECUTING] = 'EXECUTING';
  		stateNames[READY] = 'READY';
  		stateNames[FAILED] = 'FAILED';
  
  		if ( iThreshold == null ) {
  			iThreshold = PRELOADED;
  		}
  
  		/*eslint-disable no-console */
  		var info = log.isLoggable('INFO') ? log.info.bind(log) : console.info.bind(console);
  		/*eslint-enable no-console */
  
  		var aModuleNames = Object.keys(mModules).sort();
  		states.forEach(function(state) {
  			if ( state  < iThreshold ) {
  				return;
  			}
  			var count = 0;
  			info(stateNames[state] + ":");
  			aModuleNames.forEach(function(sModule, idx) {
  				var oModule = mModules[sModule];
  				if ( oModule.state === state ) {
  					var addtlInfo;
  					if ( oModule.state === LOADING ) {
  						var pending = oModule.pending && oModule.pending.reduce(function(acc, dep) {
  							var oDepModule = Module.get(dep);
  							if ( oDepModule.state !== READY ) {
  								acc.push( dep + "(" + stateNames[oDepModule.state] + ")");
  							}
  							return acc;
  						}, []);
  						if ( pending && pending.length > 0 ) {
  							addtlInfo = "waiting for " + pending.join(", ");
  						}
  					} else if ( oModule.state === FAILED ) {
  						addtlInfo = (oModule.error.name || "Error") + ": " + oModule.error.message;
  					}
  					info("  " + (idx + 1) + " " + sModule + (addtlInfo ? " (" + addtlInfo + ")" : ""));
  					count++;
  				}
  			});
  			if ( count === 0 ) {
  				info("  none");
  			}
  		});
  
  	}
  
  	/**
  	 * Returns a flat copy of the current set of URL prefixes.
  	 *
  	 * @private
  	 */
  	function getUrlPrefixes() {
  		var mUrlPrefixesCopy = Object.create(null);
  		forEach(mUrlPrefixes, function(sNamePrefix, oUrlInfo) {
  			mUrlPrefixesCopy[sNamePrefix] = oUrlInfo.url;
  		});
  		return mUrlPrefixesCopy;
  	}
  
  	/**
  	 * Removes a set of resources from the resource cache.
  	 *
  	 * @param {string} sName unified resource name of a resource or the name of a preload group to be removed
  	 * @param {boolean} [bPreloadGroup=true] whether the name specifies a preload group, defaults to true
  	 * @param {boolean} [bUnloadAll] Whether all matching resources should be unloaded, even if they have been executed already.
  	 * @param {boolean} [bDeleteExports] Whether exports (global variables) should be destroyed as well. Will be done for UI5 module names only.
  	 * @experimental Since 1.16.3 API might change completely, apps must not develop against it.
  	 * @private
  	 */
  	function unloadResources(sName, bPreloadGroup, bUnloadAll, bDeleteExports) {
  		var aModules = [],
  			sURN, oModule;
  
  		if ( bPreloadGroup == null ) {
  			bPreloadGroup = true;
  		}
  
  		if ( bPreloadGroup ) {
  			// collect modules that belong to the given group
  			for ( sURN in mModules ) {
  				oModule = mModules[sURN];
  				if ( oModule && oModule.group === sName ) {
  					aModules.push(sURN);
  				}
  			}
  
  		} else {
  			// single module
  			if ( mModules[sName] ) {
  				aModules.push(sName);
  			}
  		}
  
  		aModules.forEach(function(sURN) {
  			var oModule = mModules[sURN];
  			if ( oModule && bDeleteExports && sURN.match(/\.js$/) ) {
  				// @evo-todo move to compat layer?
  				setGlobalProperty(urnToUI5(sURN), undefined);
  			}
  			if ( oModule && (bUnloadAll || oModule.state === PRELOADED) ) {
  			  delete mModules[sURN];
  			}
  		});
  
  	}
  
  	function getModuleContent(name, url) {
  		if ( name ) {
  			name = getMappedName(name);
  		} else {
  			name = guessResourceName(url);
  		}
  		var oModule = name && mModules[name];
  		if ( oModule ) {
  			oModule.state = LOADED;
  			return oModule.data;
  		} else {
  			return undefined;
  		}
  	}
  
  	/**
  	 * Returns an info about all known resources keyed by their URN.
  	 *
  	 * If the URN can be converted to a UI5 module name, then the value in the map
  	 * will be that name. Otherwise it will be null or undefined.
  	 *
  	 * @return {Object.<string,string>} Map of all module names keyed by their resource name
  	 * @see isDeclared
  	 * @private
  	 */
  	function getAllModules() {
  		var mSnapshot = Object.create(null);
  		forEach(mModules, function(sURN, oModule) {
  			mSnapshot[sURN] = {
  				state: oModule.state,
  				ui5: urnToUI5(sURN)
  			};
  		});
  		return mSnapshot;
  	}
  
  	function loadJSResourceAsync(sResource, bIgnoreErrors) {
  		sResource = getMappedName(sResource);
  		var promise = requireModule(null, sResource, /* bAsync = */ true).then(unwrapExport);
  		return bIgnoreErrors ? promise.catch(noop) : promise;
  	}
  
  	// ---- config --------------------------------------------------------------------------------
  
  	var mUI5ConfigHandlers = {
  		baseUrl: function(url) {
  			registerResourcePath("", url);
  		},
  		paths: registerResourcePath, // has length 2
  		shim: function(module, shim) {
  			if ( Array.isArray(shim) ) {
  				shim = { deps : shim };
  			}
  			mShims[module + '.js'] = shim;
  		},
  		amd: function(bValue) {
  			bValue = !!bValue;
  			if ( bExposeAsAMDLoader !== bValue ) {
  				bExposeAsAMDLoader = bValue;
  				if (bValue) {
  					vOriginalDefine = __global.define;
  					vOriginalRequire = __global.require;
  					__global.define = amdDefine;
  					__global.require = amdRequire;
  
  					// Enable async loading behaviour implicitly when switching to amd mode
  					bGlobalAsyncMode = true;
  				} else {
  					__global.define = vOriginalDefine;
  					__global.require = vOriginalRequire;
  					// NOTE: Do not set async mode back to false when amd mode gets deactivated
  				}
  			}
  		},
  		async: function(async) {
  			if (bGlobalAsyncMode && !async) {
  				throw new Error("Changing the ui5loader config from async to sync is not supported. Only a change from sync to async is allowed.");
  			}
  			bGlobalAsyncMode = !!async;
  		},
  		debugSources: function(debug) {
  			bDebugSources = !!debug;
  		},
  		depCache: function(module, deps) {
  			mDepCache[module + '.js'] = deps.map(function(dep) { return dep + '.js'; });
  		},
  		depCacheUI5: function(module, deps) {
  			mDepCache[module] = deps;
  		},
  		ignoreBundledResources: function(filter) {
  			if ( filter == null || typeof filter === 'function' ) {
  				fnIgnorePreload = filter;
  			}
  		},
  		map: function(context, map) {
  			// @evo-todo ignore empty context, empty prefix?
  			if ( map == null ) {
  				delete mMaps[context];
  			} else if ( typeof map === 'string' ) {
  				// SystemJS style config
  				mMaps['*'][context] = map;
  			} else {
  				mMaps[context] = mMaps[context] || Object.create(null);
  				forEach(map, function(alias, name) {
  					mMaps[context][alias] = name;
  				});
  			}
  		},
  		reportSyncCalls: function(report) {
  			if ( report === 0 || report === 1 || report === 2 ) {
  				syncCallBehavior = report;
  			}
  		},
  		noConflict: function(bValue) {
  			log.warning("Config option 'noConflict' has been deprecated, use option 'amd' instead, if still needed.");
  			mUI5ConfigHandlers.amd(!bValue);
  		}
  	};
  
  	/**
  	 * Config handlers used when amd mode is enabled.
  	 * References only methods defined in the AMD spec.
  	 */
  	var mAMDConfigHandlers = {
  		baseUrl: mUI5ConfigHandlers.baseUrl,
  		paths: function (module, url) {
  			registerResourcePath(module, resolveURL(url, getResourcePath("") + "/"));
  		},
  		map: mUI5ConfigHandlers.map,
  		shim: mUI5ConfigHandlers.shim
  	};
  
  	/**
  	 * Executes all available handlers which are defined in the config object
  	 *
  	 * @param {object} oCfg config to handle
  	 * @param {map} mHandlers all available handlers
  	 */
  	function handleConfigObject(oCfg, mHandlers) {
  
  		function processConfig(key, value) {
  			var handler = mHandlers[key];
  			if ( typeof handler === 'function' ) {
  				if ( handler.length === 1) {
  					handler(value);
  				} else if ( value != null ) {
  					forEach(value, handler);
  				}
  			} else {
  				log.warning("configuration option " + key + " not supported (ignored)");
  			}
  		}
  
  		// Make sure the 'baseUrl' handler is called first as
  		// other handlers (e.g. paths) depend on it
  		if (oCfg.baseUrl) {
  			processConfig("baseUrl", oCfg.baseUrl);
  		}
  
  		forEach(oCfg, function(key, value) {
  			// Ignore "baseUrl" here as it will be handled above
  			if (key !== "baseUrl") {
  				processConfig(key, value);
  			}
  		});
  	}
  
  	function ui5Config(cfg) {
  		if ( cfg === undefined ) {
  			return {
  				amd: bExposeAsAMDLoader,
  				async: bGlobalAsyncMode,
  				noConflict: !bExposeAsAMDLoader // TODO needed?
  			};
  		}
  		handleConfigObject(cfg, mUI5ConfigHandlers);
  	}
  
  	function amdConfig(cfg) {
  		if ( cfg === undefined ) {
  			return undefined;
  		}
  		handleConfigObject(cfg, mAMDConfigHandlers);
  	}
  
  	// expose preload function as property of sap.ui.require
  	ui5Require.preload = preload;
  
  	// @evo-todo really use this hook for loading. But how to differentiate between sync and async?
  	// for now, it is only a notification hook to attach load tests
  	ui5Require.load = function(context, url, id) {
  	};
  
  	var privateAPI = {
  		amdDefine: amdDefine,
  		amdRequire: amdRequire,
  		config: ui5Config,
  		declareModule: function(sResourceName) {
  			/* void */ declareModule( normalize(sResourceName) );
  		},
  		defineModuleSync: defineModuleSync,
  		dump: dumpInternals,
  		getAllModules: getAllModules,
  		getModuleContent: getModuleContent,
  		getModuleState: function(sResourceName) {
  			return mModules[sResourceName] ? mModules[sResourceName].state : INITIAL;
  		},
  		getResourcePath: getResourcePath,
  		getSyncCallBehavior: getSyncCallBehavior,
  		getUrlPrefixes: getUrlPrefixes,
  		loadJSResourceAsync: loadJSResourceAsync,
  		resolveURL: resolveURL,
  		toUrl: toUrl,
  		unloadResources: unloadResources
  	};
  	Object.defineProperties(privateAPI, {
  		logger: {
  			get: function() {
  				return log;
  			},
  			set: function(v) {
  				log = v;
  			}
  		},
  		measure: {
  			get: function() {
  				return measure;
  			},
  			set: function(v) {
  				measure = v;
  			}
  		},
  		assert: {
  			get: function() {
  				return assert;
  			},
  			set: function(v) {
  				assert = v;
  			}
  		},
  		translate: {
  			get: function() {
  				return translate;
  			},
  			set: function(v) {
  				translate = v;
  			}
  		},
  		callbackInMicroTask: {
  			get: function() {
  				return simulateAsyncCallback === executeInMicroTask;
  			},
  			set: function(v) {
  				simulateAsyncCallback = v ? executeInMicroTask : executeInSeparateTask;
  			}
  		}
  	});
  
  	// establish APIs in the sap.ui namespace
  
  	__global.sap = __global.sap || {};
  	sap.ui = sap.ui || {};
  
  	/**
  	 * Provides access to UI5 loader configuration.
  	 *
  	 * The configuration is used by {@link sap.ui.require} and {@link sap.ui.define}.
  	 *
  	 * @public
  	 * @namespace
  	 */
  	sap.ui.loader = {
  
  		/**
  		 * Sets the configuration for the UI5 loader. The configuration can be updated multiple times.
  		 * Later changes do not impact modules that have been loaded before.
  		 *
  		 * If no parameter is given, a partial copy of UI5 loader configuration in use is returned.
  		 *
  		 * The configuration options are aligned with the "Common Config" draft of the AMD spec
  		 * (https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md).
  		 *
  		 * The following code shows an example of what a UI5 loader configuration might look like:
  		 * <pre>
  		 *
  		 *   sap.ui.loader.config({
  		 *
  		 *     // location from where to load all modules by default
  		 *     baseUrl: '../../resources/',
  		 *
  		 *     paths: {
  		 *       // load modules whose ID equals to or starts with 'my/module' from example.com
  		 *       'my/module': 'https://example.com/resources/my/module'
  		 *     },
  		 *
  		 *     map: {
  		 *       // if any module requires 'sinon', load module 'sap/ui/thirdparty/sinon-4'
  		 *       '*': {
  		 *         'sinon': 'sap/ui/thirdparty/sinon-4'
  		 *       },
  		 *       // but if a module whose ID equals to or starts with 'app' requires 'sinon'
  		 *       // then load a legacy version instead
  		 *       "app": {
  		 *         'sinon': 'sap/ui/legacy/sinon'
  		 *       }
  		 *     },
  		 *
  		 *     // activate real async loading and module definitions
  		 *     async: true,
  		 *
  		 *     // provide dependency and export metadata for non-UI5 modules
  		 *     shim: {
  		 *       'sap/ui/thirdparty/blanket': {
  		 *         amd: true,
  		 *         exports: 'blanket'
  		 *       }
  		 *     }
  		 *
  		 *   });
  		 *
  		 * </pre>
  		 *
  		 * @param {object|undefined} [cfg]
  		 *   The provided configuration gets merged with the UI5 loader configuration in use.
  		 *   If <code>cfg</code> is omitted or <code>undefined</code>, a copy of the current configuration
  		 *   gets returned, containing at least the properties <code>amd</code> and <code>async</code>.
  		 *
  		 * @param {string} [cfg.baseUrl='./']
  		 *   Default location to load modules from. If none of the configured <code>paths</code> prefixes
  		 *   matches a module ID, the module will be loaded from the concatenation of the <code>baseUrl</code>
  		 *   and the module ID.
  		 *
  		 *   If the <code>baseUrl</code> itself is a relative URL, it is evaluated relative to <code>document.baseURI</code>.
  		 *
  		 * @param {Object.<string, string>} [cfg.paths]
  		 *   A map of resource locations keyed by a corresponding module ID prefix.
  		 *   When a module is to be loaded, the longest key in <code>paths</code> is searched that is a
  		 *   prefix of the module ID. The module will be loaded from the concatenation of the corresponding
  		 *   value in <code>paths</code> and the remainder of the module ID (after the prefix). If no entry
  		 *   in <code>paths</code> matches, then the module will be loaded from the <code>baseUrl</code>.
  		 *
  		 *   The prefixes (keys) must not contain relative segments (./ or ../), a trailing slash will be
  		 *   removed, and only full name segment matches are considered a match (prefix 'sap/m' does not
  		 *   match a module ID 'sap/main').
  		 *
  		 *   <b>Note</b>: In contrast to the "Common Config" of the AMD spec, the paths (values in the map)
  		 *   are interpreted relative to <code>document.baseURI</code>, not relative to <code>cfg.baseUrl</code>.
  		 *
  		 * @param {Object.<string, Object.<string, string>>} [cfg.map]
  		 *   A map of maps that defines how to map module IDs to other module IDs (inner maps)
  		 *   in the context of a specific set of modules (keys of outer map).
  		 *
  		 *   Each key of the outer map represents a module ID prefix that describes the context for which
  		 *   its value (inner map) has to be used. The special key <code>*</code> describes the default
  		 *   context which applies for any module. Only the most specific matching context will be taken
  		 *   into account.
  		 *
  		 *   Each inner map maps a module ID or module ID prefix to another module ID or module ID prefix.
  		 *   Again, only the most specific match is taken into account and only one mapping is evaluated
  		 *   (the evaluation of the mappings is not done recursively).
  		 *
  		 *   Matches are always complete matches, a prefix 'a/b/c' does not match the module ID 'a/b/com'.
  		 *
  		 * @param {Object.<string, {amd: boolean, deps: string[], exports: (string|string[])}>} [cfg.shim]
  		 *   Defines additional metadata for modules for which the normal behavior of the AMD APIs is
  		 *   not sufficient.
  		 *
  		 *   A typical example are scripts that don't use <code>define</code> or <code>sap.ui.define</code>,
  		 *   but export to a global name. With the <code>exports</code> property, one or more export
  		 *   names can be specified, and the loader can retrieve the exported value after executing the
  		 *   corresponding module. If such a module has dependencies, they can be specified in the
  		 *   <code>deps</code> array and are loaded and executed before executing the module.
  		 *
  		 *   The <code>amd</code> flag of a shim is a ui5loader-specific extension of the standard AMD shims.
  		 *   If set, the ui5loader hides a currently active AMD loader before executing the module
  		 *   and restores it afterwards. Otherwise, it might miss the export of third party modules that
  		 *   check for an AMD loader and register with it instead of exporting to a global name. A future
  		 *   version of the ui5loader might ignore this flag when it acts as an AMD loader by itself.
  		 *
  		 *   <b>Note:</b> The ui5loader does not support the <code>init</code> option described by the
  		 *   "Common Config" section of the AMD spec.
  		 *
  		 * @param {boolean} [cfg.async=false]
  		 *   When set to true, <code>sap.ui.require</code> loads modules asynchronously via script tags and
  		 *   <code>sap.ui.define</code> executes asynchronously. To enable this feature, it is recommended to
  		 *   set the attribute <code>data-sap-ui-async="true"</code> on the application bootstrap tag.
  		 *
  		 *   <b>Note:</b> Switching back from async to sync is not supported and trying to do so will throw
  		 *   an <code>Error</code>
  		 *
  		 * @param {boolean} [cfg.amd=false]
  		 *   When set to true, the ui5loader will overwrite the global properties <code>define</code>
  		 *   and <code>require</code> with its own implementations. Any previously active AMD loader will
  		 *   be remembered internally and can be restored by setting <code>amd</code> to false again.
  		 *
  		 *   <b>Note:</b> Switching to the <code>amd</code> mode, the ui5loader will set <code>async</code>
  		 *   to true implicitly for activating asynchronous loading. Once the loading behaviour has been
  		 *   defined to be asynchronous, it can not be changed to synchronous behaviour again, also not
  		 *   via setting <code>amd</code> to false.
  		 *
  		 * @returns {object|undefined} UI5 loader configuration in use.
  		 * @throws {Error} When trying to switch back from async mode to sync mode.
  		 * @public
  		 * @since 1.56.0
  		 * @function
  		 */
  		config: ui5Config,
  
  		/**
  		 * Internal API of the UI5 loader.
  		 *
  		 * Must not be used by code outside sap.ui.core.
  		 * @private
  		 */
  		_: privateAPI
  	};
  
  	/**
  	 * Sets the configuration of the ui5loader. The configuration can be updated multiple times.
  	 * Later changes do not impact modules that have been loaded before.
  	 *
  	 * Setting the <code>amd</code> option of the sap.ui.loader.config to <code>true</code> is a
  	 * prerequisite to use the <code>require.config</code> function
  	 * (see {@link sap.ui.loader.config sap.ui.loader.config option amd}).
  	 *
  	 * The ui5loader acts more AMD compliant in relation to resolution of paths defined as
  	 * part of the <code>paths</code> configuration option.
  	 *
  	 * @param {object} cfg The provided configuration gets merged with the UI5 loader configuration in use.
  	 *
  	 * @param {string} [cfg.baseUrl='./']
  	 *   Default location to load modules from. If none of the configured <code>paths</code> prefixes
  	 *   matches a module ID, the module will be loaded from the concatenation of the <code>baseUrl</code>
  	 *   and the module ID.
  	 *
  	 *   If the <code>baseUrl</code> itself is a relative URL, it is evaluated relative to <code>document.baseURI</code>.
  	 *
  	 * @param {object} [cfg.paths]
  	 *   A map of resource locations keyed by a corresponding module ID prefix.
  	 *   When a module is to be loaded, the longest key in <code>paths</code> is searched that is a
  	 *   prefix of the module ID. The module will be loaded from the concatenation of the corresponding
  	 *   value in <code>paths</code> and the remainder of the module ID (after the prefix). If no entry
  	 *   in <code>paths</code> matches, then the module will be loaded from the <code>baseUrl</code>.
  	 *
  	 *   The prefixes (keys) must not contain relative segments (./ or ../), a trailing slash will be
  	 *   removed, and only full name segment matches are considered a match (prefix 'sap/m' does not
  	 *   match a module ID 'sap/main').
  	 *
  	 *   <b>Note</b>: In contrast to the {@link sap.ui.loader.config sap.ui.loader.config option paths},
  	 *   the paths (values in the map) are interpreted relative to <code>cfg.baseUrl</code>,
  	 *   not relative to <code>document.baseURI</code>. The behaviour is exactly as described in the "Common Config" draft
  	 *   of the AMD spec (https://github.com/amdjs/amdjs-api/blob/master/CommonConfig.md).
  	 *
  	 * @param {Object.<string, Object.<string, string>>} [cfg.map]
  	 *   A map of maps that defines how to map module IDs to other module IDs (inner maps)
  	 *   in the context of a specific set of modules (keys of outer map).
  	 *
  	 *   Each key of the outer map represents a module ID prefix that describes the context for which
  	 *   its value (inner map) has to be used. The special key <code>*</code> describes the default
  	 *   context which applies for any module. Only the most specific matching context will be taken
  	 *   into account.
  	 *
  	 *   Each inner map maps a module ID or module ID prefix to another module ID or module ID prefix.
  	 *   Again, only the most specific match is taken into account and only one mapping is evaluated
  	 *   (the evaluation of the mappings is not done recursively).
  	 *
  	 *   Matches are always complete matches, a prefix 'a/b/c' does not match the module ID 'a/b/com'.
  	 *
  	 * @param {Object.<string, {deps: string[], exports: (string|string[])}>} [cfg.shim]
  	 *   Defines additional metadata for modules for which the normal behavior of the AMD APIs is
  	 *   not sufficient.
  	 *
  	 *   A typical example are scripts that don't use <code>define</code> or <code>sap.ui.define</code>,
  	 *   but export to a global name. With the <code>exports</code> property, one or more export
  	 *   names can be specified, and the loader can retrieve the exported value after executing the
  	 *   corresponding module. If such a module has dependencies, they can be specified in the
  	 *   <code>deps</code> array and are loaded and executed before executing the module.
  	 *
  	 *   <b>Note:</b> The ui5loader does not support the <code>init</code> option described by the
  	 *   "Common Config" section of the AMD spec.
  	 *
  	 * @returns {undefined}
  	 * @public
  	 * @name require_config
  	 * @function
  	 */
  	amdRequire.config = amdConfig;
  
  	/**
  	 * Defines a JavaScript module with its ID, its dependencies and a module export value or factory.
  	 *
  	 * The typical and only suggested usage of this method is to have one single, top level call to
  	 * <code>sap.ui.define</code> in one JavaScript resource (file). When a module is requested by its
  	 * module ID for the first time, the corresponding resource is determined from the ID and the current
  	 * {@link sap.ui.loader.config configuration}. The resource will be loaded and executed
  	 * which in turn will execute the top level <code>sap.ui.define</code> call.
  	 *
  	 * If the module ID was omitted from that call, it will be substituted by the ID that was used to
  	 * request the module. As a preparation step, the dependencies as well as their transitive dependencies,
  	 * will be loaded. Then, the module value (its export) will be determined: if a static value (object, literal)
  	 * was given as <code>vFactory</code>, that value will be the module value. If a function was given, that
  	 * function will be called (providing the module exports of the declared dependencies as parameters
  	 * to the function) and its return value will be used as module export value. The framework internally
  	 * associates the resulting value with the module ID and provides it to the original requester of the module.
  	 * Whenever the module is requested again, the same export value will be returned (modules are executed only once).
  	 *
  	 * <i>Example:</i><br>
  	 * The following example defines a module, but doesn't hard code the module ID.
  	 * If stored in a file 'sap/mylib/SomeClass.js', it can be requested with the ID 'sap/mylib/SomeClass'.
  	 * <pre>
  	 *   sap.ui.define(['./Helper', 'sap/m/Bar'], function(Helper,Bar) {
  	 *
  	 *     // create a new class
  	 *     var SomeClass = function() {};
  	 *
  	 *     // add methods to its prototype
  	 *     SomeClass.prototype.foo = function() {
  	 *
  	 *         // use a function from the dependency 'Helper' in the same package (e.g. 'sap/mylib/Helper' )
  	 *         var mSettings = Helper.foo();
  	 *
  	 *         // create and return an sap.m.Bar (using its local name 'Bar')
  	 *         return new Bar(mSettings);
  	 *
  	 *     }
  	 *
  	 *     // return the class as module value
  	 *     return SomeClass;
  	 *
  	 *   });
  	 * </pre>
  	 *
  	 * In another module or in an application HTML page, the {@link sap.ui.require} API can be used
  	 * to load the sap/mylib/Something module and to work with it:
  	 *
  	 * <pre>
  	 * sap.ui.require(['sap/mylib/Something'], function(Something) {
  	 *
  	 *   // instantiate a Something and call foo() on it
  	 *   new Something().foo();
  	 *
  	 * });
  	 * </pre>
  	 *
  	 *
  	 * <h3>Module Name Syntax</h3>
  	 *
  	 * <code>sap.ui.define</code> uses a simplified variant of the {@link jQuery.sap.getResourcePath
  	 * unified resource name} syntax for the module's own name as well as for its dependencies.
  	 * The only difference to that syntax is, that for <code>sap.ui.define</code> and
  	 * <code>sap.ui.require</code>, the extension (which always would be '.js') has to be omitted.
  	 * Both methods always add this extension internally.
  	 *
  	 * As a convenience, the name of a dependency can start with the segment './' which will be
  	 * replaced by the name of the package that contains the currently defined module (relative name).
  	 *
  	 * It is best practice to omit the name of the defined module (first parameter) and to use
  	 * relative names for the dependencies whenever possible. This reduces the necessary configuration,
  	 * simplifies renaming of packages and allows to map them to a different namespace.
  	 *
  	 *
  	 * <h3>Dependency to Modules</h3>
  	 *
  	 * If a dependencies array is given, each entry represents the name of another module that
  	 * the currently defined module depends on. All dependency modules are loaded before the export
  	 * of the currently defined module is determined. The module export of each dependency module
  	 * will be provided as a parameter to a factory function, the order of the parameters will match
  	 * the order of the modules in the dependencies array.
  	 *
  	 * <b>Note:</b> The order in which the dependency modules are <i>executed</i> is <b>not</b>
  	 * defined by the order in the dependencies array! The execution order is affected by dependencies
  	 * <i>between</i> the dependency modules as well as by their current state (whether a module
  	 * already has been loaded or not). Neither module implementations nor dependents that require
  	 * a module set must make any assumption about the execution order (other than expressed by
  	 * their dependencies).
  	 *
  	 * <b>Note:</b> A static module export (a literal provided to <code>sap.ui.define</code>) cannot
  	 * depend on the module exports of the dependency modules as it has to be calculated before
  	 * the dependencies are resolved. As an alternative, modules can define a factory function,
  	 * calculate a static export value in that function, potentially based on the dependencies, and
  	 * return the result as module export value. The same approach must be taken when the module
  	 * export is supposed to be a function.
  	 *
  	 *
  	 * <h3>Asynchronous Contract</h3>
  	 *
  	 * <code>sap.ui.define</code> is designed to support real Asynchronous Module Definitions (AMD)
  	 * in future, although it internally still might use synchronous module loading, depending on
  	 * configuration and context. However, callers of <code>sap.ui.define</code> must never rely on
  	 * any synchronous behavior that they might observe in a specific test scenario.
  	 *
  	 * For example, callers of <code>sap.ui.define</code> must not use the module export value
  	 * immediately after invoking <code>sap.ui.define</code>:
  	 *
  	 * <pre>
  	 *   // COUNTER EXAMPLE HOW __NOT__ TO DO IT
  	 *
  	 *   // define a class Something as AMD module
  	 *   sap.ui.define('Something', [], function() {
  	 *     var Something = function() {};
  	 *     return Something;
  	 *   });
  	 *
  	 *   // DON'T DO THAT!
  	 *   // accessing the class _synchronously_ after sap.ui.define was called
  	 *   new Something();
  	 *
  	 * </pre>
  	 *
  	 * Applications that need to ensure synchronous module definition or synchronous loading of dependencies
  	 * <b>MUST</b> use the deprecated legacy APIs {@link jQuery.sap.declare} and {@link jQuery.sap.require}.
  	 *
  	 *
  	 * <h3>(No) Global References</h3>
  	 *
  	 * To be in line with AMD best practices, modules defined with <code>sap.ui.define</code>
  	 * should not make any use of global variables if those variables are also available as module
  	 * exports. Instead, they should add dependencies to those modules and use the corresponding parameter
  	 * of the factory function to access the module exports.
  	 *
  	 * As the current programming model and the documentation of UI5 heavily rely on global names,
  	 * there will be a transition phase where UI5 enables AMD modules and local references to module
  	 * exports in parallel to the old global names. The fourth parameter of <code>sap.ui.define</code>
  	 * has been added to support that transition phase. When this parameter is set to true, the framework
  	 * provides two additional features
  	 *
  	 * <ol>
  	 * <li>Before the factory function is called, the existence of the global parent namespace for
  	 *     the current module is ensured</li>
  	 * <li>The module export returned by the module's factory function will be automatically exported
  	 *     under the global name which is derived from the ID of the module</li>
  	 * </ol>
  	 *
  	 * The parameter lets the framework know whether any of those two operations is needed or not.
  	 * In future versions of UI5, a central configuration option is planned to suppress those 'exports'.
  	 *
  	 *
  	 * <h3>Third Party Modules</h3>
  	 * Although third party modules don't use UI5 APIs, they still can be listed as dependencies in
  	 * a <code>sap.ui.define</code> call. They will be requested and executed like UI5 modules, but to
  	 * make their exports available, so called <em>shims</em> have to be defined.
  	 *
  	 * Note that UI5 temporarily deactivates an existing AMD loader while it executes third party modules
  	 * known to support AMD. This sounds contradictorily at a first glance as UI5 wants to support AMD,
  	 * but for now it is necessary to fully support UI5 applications that rely on global names for such modules.
  	 *
  	 * For third-party modules that UI5 delivers (e.g. those in namespace <code>sap/ui/thirdparty/</code>),
  	 * the necessary shims are defined by UI5 itself by executing the private module <code>ui5loader-autoconfig.js</code>
  	 * during bootstrap.
  	 *
  	 * Example:
  	 * <pre>
  	 *   // module 'Something' wants to use third party library 'URI.js'
  	 *   // It is packaged by UI5 as non-UI5-module 'sap/ui/thirdparty/URI'
  	 *   // the following shim helps UI5 to correctly load URI.js and to retrieve the module's export value
  	 *   // Apps don't have to define that shim, it is already applied by ui5loader-autconfig.js
  	 *   sap.ui.loader.config({
  	 *     shim: {
  	 *       'sap/ui/thirdparty/URI': {
  	 *          amd: true, // URI.js reacts on an AMD loader, this flag lets UI5 temp. disable such loaders
  	 *          exports: 'URI' // name of the global variable under which URI.js exports its module value
  	 *       }
  	 *     }
  	 *   });
  	 *
  	 *   // now the module can be retrieved like other modules
  	 *   sap.ui.define('Something', ['sap/ui/thirdparty/URI'], function(URIModuleValue) {
  	 *
  	 *     new URIModuleValue(...); // same as the global 'URI' name: new URI(...)
  	 *
  	 *     ...
  	 *   });
  	 * </pre>
  	 *
  	 *
  	 * <h3>Differences to Standard AMD</h3>
  	 *
  	 * The current implementation of <code>sap.ui.define</code> differs from the AMD specification
  	 * (https://github.com/amdjs/amdjs-api) or from concrete AMD loaders like <code>requireJS</code>
  	 * in several aspects:
  	 * <ul>
  	 * <li>The name <code>sap.ui.define</code> is different from the plain <code>define</code>.
  	 * This has two reasons: first, it avoids the impression that <code>sap.ui.define</code> is
  	 * an exact implementation of an AMD loader. And second, it allows the coexistence of an AMD
  	 * loader (e.g. requireJS) and <code>sap.ui.define</code> in one application as long as UI5 or
  	 * applications using UI5 are not fully prepared to run with an AMD loader.
  	 * Note that the difference of the API names also implies that the UI5 loader can't be used
  	 * to load 'real' AMD modules as they expect methods <code>define</code> and <code>require</code>
  	 * to be available. Modules that use Unified Module Definition (UMD) syntax, can be loaded,
  	 * but only when no AMD loader is present or when they expose their export also to the global
  	 * namespace, even when an AMD loader is present (as e.g. jQuery does) or when a shim is
  	 * defined for them using the <code>amd:true</code> flag (see example above)</li>
  	 * <li>Depending on configuration and the current context, <code>sap.ui.define</code> loads
  	 * the dependencies of a module either synchronously using a sync XHR call + eval or asynchronously
  	 * via script tags. The sync loading is basically a tribute to the synchronous history of UI5.
  	 * There's no way for a module developer to enforce synchronous loading of the dependencies and
  	 * on the long run, sync loading will be faded out.
  	 * Applications that need to ensure synchronous loading of dependencies <b>MUST</b> use the
  	 * deprecated legacy APIs like {@link jQuery.sap.require}.</li>
  	 * <li><code>sap.ui.define</code> does not support plugins to use other file types, formats or
  	 * protocols. It is not planned to support this in future</li>
  	 * <li><code>sap.ui.define</code> does not support absolute URLs as module names (dependencies)
  	 * nor does it allow module names that start with a slash. To refer to a module at an absolute
  	 * URL, a resource root can be registered that points to that URL (or to a prefix of it).</li>
  	 * <li><code>sap.ui.define</code> does <b>not</b> support the 'sugar' of requireJS where CommonJS
  	 * style dependency declarations using <code>sap.ui.require("something")</code> are automagically
  	 * converted into <code>sap.ui.define</code> dependencies before executing the factory function.</li>
  	 * </ul>
  	 *
  	 *
  	 * <h3>Limitations, Design Considerations</h3>
  	 * <ul>
  	 * <li><b>Limitation</b>: as dependency management is not supported for Non-UI5 modules, the only way
  	 *     to ensure proper execution order for such modules currently is to rely on the order in the
  	 *     dependency array. Obviously, this only works as long as <code>sap.ui.define</code> uses
  	 *     synchronous loading. It will be enhanced when asynchronous loading is implemented.</li>
  	 * <li>It was discussed to enforce asynchronous execution of the module factory function (e.g. with a
  	 *     timeout of 0). But this would have invalidated the current migration scenario where a
  	 *     sync <code>jQuery.sap.require</code> call can load a <code>sap.ui.define</code>'ed module.
  	 *     If the module definition would not execute synchronously, the synchronous contract of the
  	 *     require call would be broken (default behavior in existing UI5 applications)</li>
  	 * <li>A single file must not contain multiple calls to <code>sap.ui.define</code>. Multiple calls
  	 *     currently are only supported in the so called 'preload' files that the UI5 merge tooling produces.
  	 *     The exact details of how this works might be changed in future implementations and are not
  	 *     part of the API contract</li>
  	 * </ul>
  	 * @param {string} [sModuleName] ID of the module in simplified resource name syntax.
  	 *        When omitted, the loader determines the ID from the request.
  	 * @param {string[]} [aDependencies] List of dependencies of the module
  	 * @param {function|any} vFactory The module export value or a function that calculates that value
  	 * @param {boolean} [bExport] Whether an export to global names is required - should be used by SAP-owned code only
  	 * @since 1.27.0
  	 * @public
  	 * @see https://github.com/amdjs/amdjs-api
  	 * @function
  	 */
  	sap.ui.define = ui5Define;
  
  	/**
  	 * @private
  	 * @function
  	 */
  	sap.ui.predefine = predefine;
  
  	/**
  	 * Resolves one or more module dependencies.
  	 *
  	 * <h3>Synchronous Retrieval of a Single Module Export Value (Probing)</h3>
  	 *
  	 * When called with a single string, that string is assumed to be the ID of an already loaded
  	 * module and the export of that module is returned. If the module has not been loaded yet,
  	 * or if it is a Non-UI5 module (e.g. third-party module) without a shim, <code>undefined</code>
  	 * is returned.
  	 *
  	 * This signature variant allows synchronous access to module exports without initiating module loading.
  	 *
  	 * Sample:
  	 * <pre>
  	 *   var JSONModel = sap.ui.require("sap/ui/model/json/JSONModel");
  	 * </pre>
  	 *
  	 * For modules that are known to be UI5 modules, this signature variant can be used to check whether
  	 * the module has been loaded.
  	 *
  	 *
  	 * <h3>Asynchronous Loading of Multiple Modules</h3>
  	 *
  	 * If an array of strings is given and (optionally) a callback function, then the strings
  	 * are interpreted as module IDs and the corresponding modules (and their transitive
  	 * dependencies) are loaded. Then the callback function will be called asynchronously.
  	 * The module exports of the specified modules will be provided as parameters to the callback
  	 * function in the same order in which they appeared in the dependencies array.
  	 *
  	 * The return value for the asynchronous use case is <code>undefined</code>.
  	 *
  	 * <pre>
  	 *   sap.ui.require(['sap/ui/model/json/JSONModel', 'sap/ui/core/UIComponent'], function(JSONModel,UIComponent) {
  	 *
  	 *     var MyComponent = UIComponent.extend('MyComponent', {
  	 *       ...
  	 *     });
  	 *     ...
  	 *
  	 *   });
  	 * </pre>
  	 *
  	 * This method uses the same variation of the {@link jQuery.sap.getResourcePath unified resource name}
  	 * syntax that {@link sap.ui.define} uses: module names are specified without the implicit extension '.js'.
  	 * Relative module names are not supported.
  	 *
  	 * @param {string|string[]} vDependencies Dependency (dependencies) to resolve
  	 * @param {function} [fnCallback] Callback function to execute after resolving an array of dependencies
  	 * @param {function} [fnErrback] Callback function to execute if an error was detected while loading the
  	 *                      dependencies or executing the factory function. Note that due to browser limitations
  	 *                      not all errors will be reported via this callback. In general, module loading is
  	 *                      designed for the non-error case. Error handling is not complete.
  	 * @returns {any|undefined} A single module export value (sync probing variant) or undefined (async loading variant)
  	 * @public
  	 * @function
  	 */
  	sap.ui.require = ui5Require;
  
  	/**
  	 * Calculates a URL from the provided resource name.
  	 *
  	 * The calculation takes any configured ID mappings or resource paths into account
  	 * (see {@link sap.ui.loader.config config options map and paths}. It also supports relative
  	 * segments such as <code>./</code> and <code>../</code> within the path, but not at its beginning.
  	 * If relative navigation would cross the root namespace (e.g. <code>sap.ui.require.toUrl("../")</code>)
  	 * or when the resource name starts with a slash or with a relative segment, an error is thrown.
  	 *
  	 * <b>Note:</b> <code>toUrl</code> does not resolve the returned URL; whether it is an absolute
  	 * URL or a relative URL depends on the configured <code>baseUrl</code> and <code>paths</code>.
  	 *
  	 * @example
  	 *   sap.ui.loader.config({
  	 *     baseUrl: "/home"
  	 *   });
  	 *
  	 *   sap.ui.require.toUrl("app/data")              === "/home/app/data"
  	 *   sap.ui.require.toUrl("app/data.json")         === "/home/app/data.json"
  	 *   sap.ui.require.toUrl("app/data/")             === "/home/app/data/"
  	 *   sap.ui.require.toUrl("app/.config")           === "/home/app/.config"
  	 *   sap.ui.require.toUrl("app/test/../data.json") === "/home/data.json"
  	 *   sap.ui.require.toUrl("app/test/./data.json")  === "/home/test/data.json"
  	 *   sap.ui.require.toUrl("app/../../data")        throws Error because root namespace is left
  	 *   sap.ui.require.toUrl("/app")                  throws Error because first character is a slash
  	 *
  	 * @param {string} sName Name of a resource e.g. <code>'app/data.json'</code>
  	 * @returns {string} Path to the resource, e.g. <code>'/home/app/data.json'</code>
  	 * @see https://github.com/amdjs/amdjs-api/wiki/require#requiretourlstring-
  	 * @throws {Error} If the input name is absolute (starts with a slash character <code>'/'</code>),
  	 *   starts with a relative segment or if resolving relative segments would cross the root
  	 *   namespace
  	 * @public
  	 * @name sap.ui.require.toUrl
  	 * @function
  	 */
  
  	/**
  	 * Load a single module synchronously and return its module value.
  	 *
  	 * Basically, this method is a combination of {@link jQuery.sap.require} and {@link sap.ui.require}.
  	 * Its main purpose is to simplify the migration of modules to AMD style in those cases where some dependencies
  	 * have to be loaded late (lazy) and synchronously.
  	 *
  	 * The method accepts a single module name in the same syntax that {@link sap.ui.define} and {@link sap.ui.require}
  	 * already use (a simplified variation of the {@link jQuery.sap.getResourcePath unified resource name}:
  	 * slash separated names without the implicit extension '.js'). As for <code>sap.ui.require</code>,
  	 * relative names (using <code>./</code> or <code>../</code>) are not supported.
  	 * If not loaded yet, the named module will be loaded synchronously and the export value of the module will be returned.
  	 * While a module is executing, a value of <code>undefined</code> will be returned in case it is required again during
  	 * that period of time (e.g. in case of cyclic dependencies).
  	 *
  	 * <b>Note:</b> Applications are strongly encouraged to use this method only when synchronous loading is unavoidable.
  	 * Any code that uses this method won't benefit from future performance improvements that require asynchronous
  	 * module loading (e.g. HTTP/2). And such code never can comply with stronger content security policies (CSPs)
  	 * that forbid 'eval'.
  	 *
  	 * @param {string} sModuleName Module name in requireJS syntax
  	 * @returns {any} value of the loaded module or undefined
  	 * @private
  	 * @function
  	 */
  	sap.ui.requireSync = requireSync;
  
  }(window));
  //@ui5-bundle-raw-include ui5loader-autoconfig.js
  /*!
   * OpenUI5
   * (c) Copyright 2009-2019 SAP SE or an SAP affiliate company.
   * Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
   */
  /*
   * IMPORTANT: This is a private module, its API must not be used and is subject to change.
   * Code other than the OpenUI5 libraries must not introduce dependencies to this module.
   */
  (function() {
  
  	/*
  	 * This module tries to detect a bootstrap script tag in the current page and
  	 * to derive the path for 'resources/' from it. For that purpose it checks for a
  	 * hard coded set of well-known bootstrap script names:
  	 *  - sap-ui-custom(-suffix)?.js
  	 *  - sap-ui-core(-suffix)?.js
  	 *  - jquery.sap.global.js
  	 *  - ui5loader-autoconfig.js
  	 */
  
  	/*global console, document, ES6Promise, jQuery, sap, window */
  	"use strict";
  
  	var ui5loader = window.sap && window.sap.ui && window.sap.ui.loader,
  		oCfg = window['sap-ui-config'] || {},
  		sBaseUrl, bNojQuery,
  		aScripts, rBootScripts, i,
  		oBootstrapScript, sBootstrapUrl, bExposeAsAMDLoader = false;
  
  	function findBaseUrl(oScript, rUrlPattern) {
  		var sUrl = oScript && oScript.getAttribute("src"),
  			oMatch = rUrlPattern.exec(sUrl);
  		if ( oMatch ) {
  			sBaseUrl = oMatch[1] || "";
  			oBootstrapScript = oScript;
  			sBootstrapUrl = sUrl;
  			bNojQuery = /sap-ui-core-nojQuery\.js(?:[?#]|$)/.test(sUrl);
  			return true;
  		}
  	}
  
  	function ensureSlash(path) {
  		return path && path[path.length - 1] !== '/' ? path + '/' : path;
  	}
  
  	if (ui5loader == null) {
  		throw new Error("ui5loader-autoconfig.js: ui5loader is needed, but could not be found");
  	}
  
  	// Prefer script tags which have the sap-ui-bootstrap ID
  	// This prevents issues when multiple script tags point to files named
  	// "sap-ui-core.js", for example when using the cache buster for UI5 resources
  	if ( !findBaseUrl(document.querySelector('SCRIPT[src][id=sap-ui-bootstrap]'), /^((?:[^?#]*\/)?resources\/)/ ) ) {
  
  		// only when there's no such script tag, check all script tags
  		rBootScripts = /^([^?#]*\/)?(?:sap-ui-(?:core|custom|boot|merged)(?:-[^?#/]*)?|jquery.sap.global|ui5loader(?:-autoconfig)?)\.js(?:[?#]|$)/;
  		aScripts = document.scripts;
  		for ( i = 0; i < aScripts.length; i++ ) {
  			if ( findBaseUrl(aScripts[i], rBootScripts) ) {
  				break;
  			}
  		}
  	}
  
  	// configuration via window['sap-ui-config'] always overrides an auto detected base URL
  	if ( typeof oCfg === 'object'
  		 && typeof oCfg.resourceRoots === 'object'
  		 && typeof oCfg.resourceRoots[''] === 'string' ) {
  		sBaseUrl = oCfg.resourceRoots[''];
  	}
  
  	if (sBaseUrl == null) {
  		throw new Error("ui5loader-autoconfig.js: could not determine base URL. No known script tag and no configuration found!");
  	}
  
  	/**
  	 * Determine whether a bootstrap reboot URL is set to reboot UI5 from a different URL
  	 */
  	(function() {
  		var sRebootUrl;
  		try { // Necessary for FF when Cookies are disabled
  			sRebootUrl = window.localStorage.getItem("sap-ui-reboot-URL");
  		} catch (e) { /* no warning, as this will happen on every startup, depending on browser settings */ }
  
  		/*
  		* Determine whether sap-bootstrap-debug is set, run debugger statement
  		* to allow early debugging in browsers with broken dev tools
  		*/
  		if (/sap-bootstrap-debug=(true|x|X)/.test(location.search)) {
  			/*eslint-disable no-debugger */
  			debugger;
  			/*eslint-enable no-debugger */
  		}
  
  		if (sRebootUrl) {
  			var sDebugRebootPath = ensureSlash(sBaseUrl) + 'sap/ui/core/support/debugReboot.js';
  
  			// This won't work in case this script is loaded async (e.g. dynamic script tag)
  			document.write("<script src=\"" + sDebugRebootPath + "\"></script>");
  
  			var oRestart = new Error("This is not a real error. Aborting UI5 bootstrap and rebooting from: " + sRebootUrl);
  			oRestart.name = "Restart";
  			throw oRestart;
  		}
  
  	})();
  
  	/**
  	 * Determine whether to use debug sources depending on URL parameter, local storage
  	 * and script tag attribute.
  	 * If full debug mode is required, restart with a debug version of the bootstrap.
  	 */
  	(function() {
  		// check URI param
  		var mUrlMatch = /(?:^|\?|&)sap-ui-debug=([^&]*)(?:&|$)/.exec(window.location.search),
  			vDebugInfo = mUrlMatch && decodeURIComponent(mUrlMatch[1]);
  
  		// check local storage
  		try {
  			vDebugInfo = vDebugInfo || window.localStorage.getItem("sap-ui-debug");
  		} catch (e) {
  			// access to localStorage might be disallowed
  		}
  
  		// check bootstrapScript attribute
  		vDebugInfo = vDebugInfo || (oBootstrapScript && oBootstrapScript.getAttribute("data-sap-ui-debug"));
  
  		// normalize vDebugInfo; afterwards, it either is a boolean or a string not representing a boolean
  		if ( typeof vDebugInfo === 'string' ) {
  			if ( /^(?:false|true|x|X)$/.test(vDebugInfo) ) {
  				vDebugInfo = vDebugInfo !== 'false';
  			}
  		} else {
  			vDebugInfo = !!vDebugInfo;
  		}
  
  		// if bootstrap URL explicitly refers to a debug source, generally use debug sources
  		if ( /-dbg\.js([?#]|$)/.test(sBootstrapUrl) ) {
  			window['sap-ui-loaddbg'] = true;
  			vDebugInfo = vDebugInfo || true;
  		}
  
  		// export resulting debug mode under legacy property
  		window["sap-ui-debug"] = vDebugInfo;
  
  		// check for optimized sources by testing variable names in a local function
  		// (check for native API ".location" to make sure that the function's source can be retrieved)
  		window["sap-ui-optimized"] = window["sap-ui-optimized"] ||
  			(/\.location/.test(_getOption) && !/oBootstrapScript/.test(_getOption));
  
  		if ( window["sap-ui-optimized"] && vDebugInfo ) {
  			// if current sources are optimized and any debug sources should be used, enable the "-dbg" suffix
  			window['sap-ui-loaddbg'] = true;
  			// if debug sources should be used in general, restart with debug URL (if not disabled, e.g. by test runner)
  			if ( vDebugInfo === true && !window["sap-ui-debug-no-reboot"] ) {
  				var sDebugUrl;
  				if ( sBootstrapUrl != null ) {
  					sDebugUrl = sBootstrapUrl.replace(/\/(?:sap-ui-cachebuster\/)?([^\/]+)\.js/, "/$1-dbg.js");
  				} else {
  					// when no boot script could be identified, we can't derive the name of the
  					// debug boot script from it, so fall back to a default debug boot script
  					sDebugUrl = ensureSlash(sBaseUrl) + 'sap-ui-core.js';
  				}
  				// revert changes to global names
  				ui5loader.config({
  					amd:false
  				});
  				window["sap-ui-optimized"] = false;
  
  				if (ui5loader.config().async) {
  					var script = document.createElement("script");
  					script.src = sDebugUrl;
  					document.head.appendChild(script);
  				} else {
  					document.write("<script src=\"" + sDebugUrl + "\"></script>");
  				}
  
  				var oRestart = new Error("This is not a real error. Aborting UI5 bootstrap and restarting from: " + sDebugUrl);
  				oRestart.name = "Restart";
  				throw oRestart;
  			}
  		}
  
  		function makeRegExp(sGlobPattern) {
  			if (!/\/\*\*\/$/.test(sGlobPattern)) {
  				sGlobPattern = sGlobPattern.replace(/\/$/, '/**/');
  			}
  			return sGlobPattern.replace(/\*\*\/|\*|[[\]{}()+?.\\^$|]/g, function(sMatch) {
  				switch (sMatch) {
  					case '**/': return '(?:[^/]+/)*';
  					case '*': return '[^/]*';
  					default: return '\\' + sMatch;
  				}
  			});
  		}
  
  		var fnIgnorePreload;
  
  		if (typeof vDebugInfo === 'string') {
  			var sPattern = "^(?:" + vDebugInfo.split(/,/).map(makeRegExp).join("|") + ")",
  				rFilter = new RegExp(sPattern);
  
  			fnIgnorePreload = function(sModuleName) {
  				return rFilter.test(sModuleName);
  			};
  
  			ui5loader._.logger.debug("Modules that should be excluded from preload: '" + sPattern + "'");
  
  		} else if (vDebugInfo === true) {
  
  			fnIgnorePreload = function() {
  				return true;
  			};
  
  			ui5loader._.logger.debug("All modules should be excluded from preload");
  
  		}
  
  		ui5loader.config({
  			debugSources: !!window['sap-ui-loaddbg'],
  			ignoreBundledResources: fnIgnorePreload
  		});
  
  	})();
  
  	function _getOption(name, defaultValue, pattern) {
  		// check for an URL parameter ...
  		var match = window.location.search.match(new RegExp("(?:^\\??|&)sap-ui-" + name + "=([^&]*)(?:&|$)"));
  		if ( match && (pattern == null || pattern.test(match[1])) ) {
  			return match[1];
  		}
  		// ... or an attribute of the bootstrap tag
  		var attrValue = oBootstrapScript && oBootstrapScript.getAttribute("data-sap-ui-" + name.toLowerCase());
  		if ( attrValue != null && (pattern == null || pattern.test(attrValue)) ) {
  			return attrValue;
  		}
  		// ... or an entry in the global config object
  		if ( Object.prototype.hasOwnProperty.call(oCfg, name) && (pattern == null || pattern.test(oCfg[name])) ) {
  			return oCfg[name];
  		}
  		// compat fallback
  		if ( name.slice(0,3) !== "xx-" ) {
  			return _getOption("xx-" + name, defaultValue, pattern);
  		}
  		// if no valid config value is found, fall back to a system default value
  		return defaultValue;
  	}
  
  	function _getBooleanOption(name, defaultValue) {
  		return /^(?:true|x|X)$/.test( _getOption(name, defaultValue, /^(?:true|x|X|false)$/) );
  	}
  
  	if ( _getBooleanOption("async", false) ) {
  		ui5loader.config({
  			async: true
  		});
  	}
  
  	// support legacy switch 'noLoaderConflict', but 'amdLoader' has higher precedence
  	bExposeAsAMDLoader = _getBooleanOption("amd", !_getBooleanOption("noLoaderConflict", true));
  
  	ui5loader.config({
  		baseUrl: sBaseUrl,
  
  		amd: bExposeAsAMDLoader,
  
  		map: {
  			"*": {
  				'blanket': 'sap/ui/thirdparty/blanket',
  				'crossroads': 'sap/ui/thirdparty/crossroads',
  				'd3': 'sap/ui/thirdparty/d3',
  				'handlebars': 'sap/ui/thirdparty/handlebars',
  				'hasher': 'sap/ui/thirdparty/hasher',
  				'IPv6': 'sap/ui/thirdparty/IPv6',
  				'jquery': 'sap/ui/thirdparty/jquery',
  				'jszip': 'sap/ui/thirdparty/jszip',
  				'less': 'sap/ui/thirdparty/less',
  				'OData': 'sap/ui/thirdparty/datajs',
  				'punycode': 'sap/ui/thirdparty/punycode',
  				'SecondLevelDomains': 'sap/ui/thirdparty/SecondLevelDomains',
  				'sinon': 'sap/ui/thirdparty/sinon',
  				'signals': 'sap/ui/thirdparty/signals',
  				'URI': 'sap/ui/thirdparty/URI',
  				'URITemplate': 'sap/ui/thirdparty/URITemplate',
  				'esprima': 'sap/ui/documentation/sdk/thirdparty/esprima'
  			}
  		},
  
  		shim: {
  			'sap/ui/thirdparty/bignumber': {
  				amd: true,
  				exports: 'BigNumber'
  			},
  			'sap/ui/thirdparty/blanket': {
  				amd: true,
  				exports: 'blanket' // '_blanket', 'esprima', 'falafel', 'inBrowser', 'parseAndModify'
  			},
  			'sap/ui/thirdparty/caja-html-sanitizer': {
  				amd: false,
  				exports: 'html' // 'html_sanitizer', 'html4'
  			},
  			'sap/ui/thirdparty/crossroads': {
  				amd: true,
  				exports: 'crossroads',
  				deps: ['sap/ui/thirdparty/signals']
  			},
  			'sap/ui/thirdparty/d3': {
  				amd: true,
  				exports: 'd3'
  			},
  			'sap/ui/thirdparty/datajs': {
  				amd: true,
  				exports: 'OData' // 'datajs'
  			},
  			'sap/ui/thirdparty/es6-promise': {
  				amd: true,
  				exports: 'ES6Promise'
  			},
  			'sap/ui/thirdparty/flexie': {
  				amd: false,
  				exports: 'Flexie'
  			},
  			'sap/ui/thirdparty/handlebars': {
  				amd: true,
  				exports: 'Handlebars'
  			},
  			'sap/ui/thirdparty/hasher': {
  				amd: true,
  				exports: 'hasher',
  				deps: ['sap/ui/thirdparty/signals']
  			},
  			'sap/ui/thirdparty/IPv6': {
  				amd: true,
  				exports: 'IPv6'
  			},
  			'sap/ui/thirdparty/iscroll-lite': {
  				amd: false,
  				exports: 'iScroll'
  			},
  			'sap/ui/thirdparty/iscroll': {
  				amd: false,
  				exports: 'iScroll'
  			},
  			'sap/ui/thirdparty/jquery': {
  				amd: true,
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-datepicker': {
  				deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-core'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-draggable': {
  				deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-droppable': {
  				deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse', 'sap/ui/thirdparty/jqueryui/jquery-ui-draggable'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-effect': {
  				deps: ['sap/ui/thirdparty/jquery'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-mouse': {
  				deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-core', 'sap/ui/thirdparty/jqueryui/jquery-ui-widget'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-position': {
  				deps: ['sap/ui/thirdparty/jquery'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-resizable': {
  				deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-selectable': {
  				deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-sortable': {
  				deps: ['sap/ui/thirdparty/jqueryui/jquery-ui-mouse'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jqueryui/jquery-ui-widget': {
  				deps: ['sap/ui/thirdparty/jquery'],
  				exports: 'jQuery'
  			},
  			'sap/ui/thirdparty/jquery-mobile-custom': {
  				amd: true,
  				deps: ['sap/ui/thirdparty/jquery', 'sap/ui/Device'],
  				exports: 'jQuery.mobile'
  			},
  			'sap/ui/thirdparty/jszip': {
  				amd: true,
  				exports: 'JSZip'
  			},
  			'sap/ui/thirdparty/less': {
  				amd: true,
  				exports: 'less'
  			},
  			'sap/ui/thirdparty/mobify-carousel': {
  				amd: false,
  				exports: 'Mobify' // or Mobify.UI.Carousel?
  			},
  			'sap/ui/thirdparty/qunit-2': {
  				amd: false,
  				exports: 'QUnit'
  			},
  			'sap/ui/thirdparty/punycode': {
  				amd: true,
  				exports: 'punycode'
  			},
  			'sap/ui/thirdparty/RequestRecorder': {
  				amd: true,
  				exports: 'RequestRecorder',
  				deps: ['sap/ui/thirdparty/URI', 'sap/ui/thirdparty/sinon']
  			},
  			'sap/ui/thirdparty/require': {
  				exports: 'define' // 'require', 'requirejs'
  			},
  			'sap/ui/thirdparty/SecondLevelDomains': {
  				amd: true,
  				exports: 'SecondLevelDomains'
  			},
  			'sap/ui/thirdparty/signals': {
  				amd: true,
  				exports: 'signals'
  			},
  			'sap/ui/thirdparty/sinon': {
  				amd: true,
  				exports: 'sinon'
  			},
  			'sap/ui/thirdparty/sinon-4': {
  				amd: true,
  				exports: 'sinon'
  			},
  			'sap/ui/thirdparty/sinon-server': {
  				amd: true,
  				exports: 'sinon' // really sinon! sinon-server is a subset of server and uses the same global for export
  			},
  			'sap/ui/thirdparty/unorm': {
  				amd: false,
  				exports: 'UNorm'
  			},
  			'sap/ui/thirdparty/unormdata': {
  				exports: 'UNorm', // really 'UNorm'! module extends UNorm
  				deps: ['sap/ui/thirdparty/unorm']
  			},
  			'sap/ui/thirdparty/URI': {
  				amd: true,
  				exports: 'URI'
  			},
  			'sap/ui/thirdparty/URITemplate': {
  				amd: true,
  				exports: 'URITemplate',
  				deps: ['sap/ui/thirdparty/URI']
  			},
  			'sap/ui/thirdparty/vkbeautify': {
  				amd: false,
  				exports: 'vkbeautify'
  			},
  			'sap/ui/thirdparty/zyngascroll': {
  				amd: false,
  				exports: 'Scroller' // 'requestAnimationFrame', 'cancelRequestAnimationFrame', 'core'
  			},
  			'sap/ui/demokit/js/esprima': {
  				amd: true,
  				exports: 'esprima'
  			},
  			'sap/ui/documentation/sdk/thirdparty/esprima': {
  				amd: true,
  				exports: 'esprima'
  			},
  			'sap/viz/libs/canvg': {
  				deps: ['sap/viz/libs/rgbcolor']
  			},
  			'sap/viz/libs/rgbcolor': {
  			},
  			'sap/viz/libs/sap-viz': {
  				deps: ['sap/viz/library', 'sap/ui/thirdparty/jquery', 'sap/ui/thirdparty/d3', 'sap/viz/libs/canvg']
  			},
  			'sap/viz/libs/sap-viz-info-charts': {
  				deps: ['sap/viz/libs/sap-viz-info-framework']
  			},
  			'sap/viz/libs/sap-viz-info-framework': {
  				deps: ['sap/ui/thirdparty/jquery', 'sap/ui/thirdparty/d3']
  			},
  			'sap/viz/ui5/container/libs/sap-viz-controls-vizcontainer': {
  				deps: ['sap/viz/libs/sap-viz', 'sap/viz/ui5/container/libs/common/libs/rgbcolor/rgbcolor_static']
  			},
  			'sap/viz/ui5/controls/libs/sap-viz-vizframe/sap-viz-vizframe': {
  				deps: ['sap/viz/libs/sap-viz-info-charts']
  			},
  			'sap/viz/ui5/controls/libs/sap-viz-vizservices/sap-viz-vizservices': {
  				deps: ['sap/viz/libs/sap-viz-info-charts']
  			},
  			'sap/viz/resources/chart/templates/standard_fiori/template': {
  				deps: ['sap/viz/libs/sap-viz-info-charts']
  			}
  		}
  	});
  
  	var defineModuleSync = ui5loader._.defineModuleSync;
  	defineModuleSync('sap/ui/thirdparty/baseuri.js', null);
  	if ( typeof ES6Promise !== 'undefined' ) {
  		defineModuleSync('sap/ui/thirdparty/es6-promise.js', ES6Promise);
  	}
  	defineModuleSync('sap/ui/thirdparty/es6-shim-nopromise.js', null);
  
  	defineModuleSync('ui5loader.js', null);
  	defineModuleSync('ui5loader-autoconfig.js', null);
  
  	if (bNojQuery && typeof jQuery === 'function') {
  		// when we're executed in the context of the sap-ui-core-noJQuery file,
  		// we try to detect an existing jQuery / jQuery position plugin and register them as modules
  		defineModuleSync('sap/ui/thirdparty/jquery.js', jQuery);
  		if (jQuery.ui && jQuery.ui.position) {
  			defineModuleSync('sap/ui/thirdparty/jqueryui/jquery-ui-position.js', jQuery);
  		}
  	}
  
  	var sMainModule = oBootstrapScript && oBootstrapScript.getAttribute('data-sap-ui-main');
  	if ( sMainModule ) {
  		sap.ui.require(sMainModule.trim().split(/\s*,\s*/));
  	}
  
  }());
  sap.ui.requireSync("sap/ui/core/Core");
  // as this module contains the Core, we ensure that the Core has been booted
  sap.ui.getCore().boot && sap.ui.getCore().boot();
  