UNPKG

scorm-again

Version:

A modern SCORM JavaScript run-time library for AICC, SCORM 1.2, and SCORM 2004

1,330 lines (1,098 loc) 246 kB
/******/ (function() { // webpackBootstrap /******/ var __webpack_modules__ = ({ /***/ "./node_modules/lodash.debounce/index.js": /*!***********************************************!*\ !*** ./node_modules/lodash.debounce/index.js ***! \***********************************************/ /***/ (function(module, __unused_webpack_exports, __webpack_require__) { function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } /** * lodash (Custom Build) <https://lodash.com/> * Build: `lodash modularize exports="npm" -o ./` * Copyright jQuery Foundation and other contributors <https://jquery.org/> * Released under MIT license <https://lodash.com/license> * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE> * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors */ /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; /** Used as references for various `Number` constants. */ var NAN = 0 / 0; /** `Object#toString` result references. */ var symbolTag = '[object Symbol]'; /** Used to match leading and trailing whitespace. */ var reTrim = /^\s+|\s+$/g; /** Used to detect bad signed hexadecimal string values. */ var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; /** Used to detect binary string values. */ var reIsBinary = /^0b[01]+$/i; /** Used to detect octal string values. */ var reIsOctal = /^0o[0-7]+$/i; /** Built-in method references without a dependency on `root`. */ var freeParseInt = parseInt; /** Detect free variable `global` from Node.js. */ var freeGlobal = (typeof __webpack_require__.g === "undefined" ? "undefined" : _typeof(__webpack_require__.g)) == 'object' && __webpack_require__.g && __webpack_require__.g.Object === Object && __webpack_require__.g; /** Detect free variable `self`. */ var freeSelf = (typeof self === "undefined" ? "undefined" : _typeof(self)) == 'object' && self && self.Object === Object && self; /** Used as a reference to the global object. */ var root = freeGlobal || freeSelf || Function('return this')(); /** Used for built-in method references. */ var objectProto = Object.prototype; /** * Used to resolve the * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring) * of values. */ var objectToString = objectProto.toString; /* Built-in method references for those with the same name as other `lodash` methods. */ var nativeMax = Math.max, nativeMin = Math.min; /** * Gets the timestamp of the number of milliseconds that have elapsed since * the Unix epoch (1 January 1970 00:00:00 UTC). * * @static * @memberOf _ * @since 2.4.0 * @category Date * @returns {number} Returns the timestamp. * @example * * _.defer(function(stamp) { * console.log(_.now() - stamp); * }, _.now()); * // => Logs the number of milliseconds it took for the deferred invocation. */ var now = function now() { return root.Date.now(); }; /** * Creates a debounced function that delays invoking `func` until after `wait` * milliseconds have elapsed since the last time the debounced function was * invoked. The debounced function comes with a `cancel` method to cancel * delayed `func` invocations and a `flush` method to immediately invoke them. * Provide `options` to indicate whether `func` should be invoked on the * leading and/or trailing edge of the `wait` timeout. The `func` is invoked * with the last arguments provided to the debounced function. Subsequent * calls to the debounced function return the result of the last `func` * invocation. * * **Note:** If `leading` and `trailing` options are `true`, `func` is * invoked on the trailing edge of the timeout only if the debounced function * is invoked more than once during the `wait` timeout. * * If `wait` is `0` and `leading` is `false`, `func` invocation is deferred * until to the next tick, similar to `setTimeout` with a timeout of `0`. * * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/) * for details over the differences between `_.debounce` and `_.throttle`. * * @static * @memberOf _ * @since 0.1.0 * @category Function * @param {Function} func The function to debounce. * @param {number} [wait=0] The number of milliseconds to delay. * @param {Object} [options={}] The options object. * @param {boolean} [options.leading=false] * Specify invoking on the leading edge of the timeout. * @param {number} [options.maxWait] * The maximum time `func` is allowed to be delayed before it's invoked. * @param {boolean} [options.trailing=true] * Specify invoking on the trailing edge of the timeout. * @returns {Function} Returns the new debounced function. * @example * * // Avoid costly calculations while the window size is in flux. * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); * * // Invoke `sendMail` when clicked, debouncing subsequent calls. * jQuery(element).on('click', _.debounce(sendMail, 300, { * 'leading': true, * 'trailing': false * })); * * // Ensure `batchLog` is invoked once after 1 second of debounced calls. * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 }); * var source = new EventSource('/stream'); * jQuery(source).on('message', debounced); * * // Cancel the trailing debounced invocation. * jQuery(window).on('popstate', debounced.cancel); */ function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != 'function') { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = 'maxWait' in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = 'trailing' in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = undefined; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { // Reset any `maxWait` timer. lastInvokeTime = time; // Start the timer for the trailing edge. timerId = setTimeout(timerExpired, wait); // Invoke the leading edge. return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, result = wait - timeSinceLastCall; return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; // Either this is the first call, activity has stopped and we're at the // trailing edge, the system time has gone backwards and we're treating // it as the trailing edge, or we've hit the `maxWait` limit. return lastCallTime === undefined || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } // Restart the timer. timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = undefined; // Only invoke if we have `lastArgs` which means `func` has been // debounced at least once. if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = undefined; return result; } function cancel() { if (timerId !== undefined) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = undefined; } function flush() { return timerId === undefined ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === undefined) { return leadingEdge(lastCallTime); } if (maxing) { // Handle invocations in a tight loop. timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === undefined) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } /** * Checks if `value` is the * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types) * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * @static * @memberOf _ * @since 0.1.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(_.noop); * // => true * * _.isObject(null); * // => false */ function isObject(value) { var type = _typeof(value); return !!value && (type == 'object' || type == 'function'); } /** * Checks if `value` is object-like. A value is object-like if it's not `null` * and has a `typeof` result of "object". * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is object-like, else `false`. * @example * * _.isObjectLike({}); * // => true * * _.isObjectLike([1, 2, 3]); * // => true * * _.isObjectLike(_.noop); * // => false * * _.isObjectLike(null); * // => false */ function isObjectLike(value) { return !!value && _typeof(value) == 'object'; } /** * Checks if `value` is classified as a `Symbol` primitive or object. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is a symbol, else `false`. * @example * * _.isSymbol(Symbol.iterator); * // => true * * _.isSymbol('abc'); * // => false */ function isSymbol(value) { return _typeof(value) == 'symbol' || isObjectLike(value) && objectToString.call(value) == symbolTag; } /** * Converts `value` to a number. * * @static * @memberOf _ * @since 4.0.0 * @category Lang * @param {*} value The value to process. * @returns {number} Returns the number. * @example * * _.toNumber(3.2); * // => 3.2 * * _.toNumber(Number.MIN_VALUE); * // => 5e-324 * * _.toNumber(Infinity); * // => Infinity * * _.toNumber('3.2'); * // => 3.2 */ function toNumber(value) { if (typeof value == 'number') { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == 'function' ? value.valueOf() : value; value = isObject(other) ? other + '' : other; } if (typeof value != 'string') { return value === 0 ? value : +value; } value = value.replace(reTrim, ''); var isBinary = reIsBinary.test(value); return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; } module.exports = debounce; /***/ }), /***/ "./src/AICC.js": /*!*********************!*\ !*** ./src/AICC.js ***! \*********************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ AICC; } /* harmony export */ }); /* harmony import */ var _Scorm12API__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Scorm12API */ "./src/Scorm12API.js"); /* harmony import */ var _cmi_aicc_cmi__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./cmi/aicc_cmi */ "./src/cmi/aicc_cmi.js"); /* harmony import */ var _cmi_scorm12_cmi__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./cmi/scorm12_cmi */ "./src/cmi/scorm12_cmi.js"); function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _get() { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get.bind(); } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(arguments.length < 3 ? target : receiver); } return desc.value; }; } return _get.apply(this, arguments); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); Object.defineProperty(subClass, "prototype", { writable: false }); if (superClass) _setPrototypeOf(subClass, superClass); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } else if (call !== void 0) { throw new TypeError("Derived constructors may only return object or undefined"); } return _assertThisInitialized(self); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf.bind() : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } /** * The AICC API class */ var AICC = /*#__PURE__*/function (_Scorm12API) { _inherits(AICC, _Scorm12API); var _super = _createSuper(AICC); /** * Constructor to create AICC API object * @param {object} settings */ function AICC(settings) { var _this; _classCallCheck(this, AICC); var finalSettings = _objectSpread(_objectSpread({}, { mastery_override: false }), settings); _this = _super.call(this, finalSettings); _this.cmi = new _cmi_aicc_cmi__WEBPACK_IMPORTED_MODULE_1__.CMI(); _this.nav = new _cmi_scorm12_cmi__WEBPACK_IMPORTED_MODULE_2__.NAV(); return _this; } /** * Gets or builds a new child element to add to the array. * * @param {string} CMIElement * @param {any} value * @param {boolean} foundFirstIndex * @return {object} */ _createClass(AICC, [{ key: "getChildElement", value: function getChildElement(CMIElement, value, foundFirstIndex) { var newChild = _get(_getPrototypeOf(AICC.prototype), "getChildElement", this).call(this, CMIElement, value, foundFirstIndex); if (!newChild) { if (this.stringMatches(CMIElement, 'cmi\\.evaluation\\.comments\\.\\d+')) { newChild = new _cmi_aicc_cmi__WEBPACK_IMPORTED_MODULE_1__.CMIEvaluationCommentsObject(); } else if (this.stringMatches(CMIElement, 'cmi\\.student_data\\.tries\\.\\d+')) { newChild = new _cmi_aicc_cmi__WEBPACK_IMPORTED_MODULE_1__.CMITriesObject(); } else if (this.stringMatches(CMIElement, 'cmi\\.student_data\\.attempt_records\\.\\d+')) { newChild = new _cmi_aicc_cmi__WEBPACK_IMPORTED_MODULE_1__.CMIAttemptRecordsObject(); } } return newChild; } /** * Replace the whole API with another * * @param {AICC} newAPI */ }, { key: "replaceWithAnotherScormAPI", value: function replaceWithAnotherScormAPI(newAPI) { // Data Model this.cmi = newAPI.cmi; this.nav = newAPI.nav; } }]); return AICC; }(_Scorm12API__WEBPACK_IMPORTED_MODULE_0__["default"]); /***/ }), /***/ "./src/BaseAPI.js": /*!************************!*\ !*** ./src/BaseAPI.js ***! \************************/ /***/ (function(__unused_webpack_module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export */ __webpack_require__.d(__webpack_exports__, { /* harmony export */ "default": function() { return /* binding */ BaseAPI; } /* harmony export */ }); /* harmony import */ var _cmi_common__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./cmi/common */ "./src/cmi/common.js"); /* harmony import */ var _exceptions__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./exceptions */ "./src/exceptions.js"); /* harmony import */ var _constants_error_codes__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./constants/error_codes */ "./src/constants/error_codes.js"); /* harmony import */ var _constants_api_constants__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./constants/api_constants */ "./src/constants/api_constants.js"); /* harmony import */ var _utilities__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./utilities */ "./src/utilities.js"); /* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! lodash.debounce */ "./node_modules/lodash.debounce/index.js"); /* harmony import */ var lodash_debounce__WEBPACK_IMPORTED_MODULE_5___default = /*#__PURE__*/__webpack_require__.n(lodash_debounce__WEBPACK_IMPORTED_MODULE_5__); function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedeclaration(obj, privateMap); privateMap.set(obj, value); } function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } } function _classPrivateFieldGet(receiver, privateMap) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "get"); return _classApplyDescriptorGet(receiver, descriptor); } function _classApplyDescriptorGet(receiver, descriptor) { if (descriptor.get) { return descriptor.get.call(receiver); } return descriptor.value; } function _classPrivateFieldSet(receiver, privateMap, value) { var descriptor = _classExtractFieldDescriptor(receiver, privateMap, "set"); _classApplyDescriptorSet(receiver, descriptor, value); return value; } function _classExtractFieldDescriptor(receiver, privateMap, action) { if (!privateMap.has(receiver)) { throw new TypeError("attempted to " + action + " private field on non-instance"); } return privateMap.get(receiver); } function _classApplyDescriptorSet(receiver, descriptor, value) { if (descriptor.set) { descriptor.set.call(receiver, value); } else { if (!descriptor.writable) { throw new TypeError("attempted to set read only private field"); } descriptor.value = value; } } var global_constants = _constants_api_constants__WEBPACK_IMPORTED_MODULE_3__["default"].global; var scorm12_error_codes = _constants_error_codes__WEBPACK_IMPORTED_MODULE_2__["default"].scorm12; /** * Base API class for AICC, SCORM 1.2, and SCORM 2004. Should be considered * abstract, and never initialized on it's own. */ var _timeout = /*#__PURE__*/new WeakMap(); var _error_codes = /*#__PURE__*/new WeakMap(); var _settings = /*#__PURE__*/new WeakMap(); var BaseAPI = /*#__PURE__*/function () { /** * Constructor for Base API class. Sets some shared API fields, as well as * sets up options for the API. * @param {object} error_codes * @param {object} settings */ function BaseAPI(error_codes, settings) { _classCallCheck(this, BaseAPI); _classPrivateFieldInitSpec(this, _timeout, { writable: true, value: void 0 }); _classPrivateFieldInitSpec(this, _error_codes, { writable: true, value: void 0 }); _classPrivateFieldInitSpec(this, _settings, { writable: true, value: { autocommit: false, autocommitSeconds: 10, asyncCommit: false, sendBeaconCommit: false, lmsCommitUrl: false, dataCommitFormat: 'json', // valid formats are 'json' or 'flattened', 'params' commitRequestDataType: 'application/json;charset=UTF-8', autoProgress: false, logLevel: global_constants.LOG_LEVEL_ERROR, selfReportSessionTime: false, alwaysSendTotalTime: false, strict_errors: true, xhrHeaders: {}, xhrWithCredentials: false, responseHandler: function responseHandler(xhr) { var result; if (typeof xhr !== 'undefined') { result = JSON.parse(xhr.responseText); if (result === null || !{}.hasOwnProperty.call(result, 'result')) { result = {}; if (xhr.status === 200) { result.result = global_constants.SCORM_TRUE; result.errorCode = 0; } else { result.result = global_constants.SCORM_FALSE; result.errorCode = 101; } } } return result; }, requestHandler: function requestHandler(commitObject) { return commitObject; }, onLogMessage: function onLogMessage(messageLevel, logMessage) { switch (messageLevel) { case global_constants.LOG_LEVEL_ERROR: console.error(logMessage); break; case global_constants.LOG_LEVEL_WARNING: console.warn(logMessage); break; case global_constants.LOG_LEVEL_INFO: console.info(logMessage); break; case global_constants.LOG_LEVEL_DEBUG: if (console.debug) { console.debug(logMessage); } else { console.log(logMessage); } break; } } } }); _defineProperty(this, "cmi", void 0); _defineProperty(this, "startingData", void 0); if ((this instanceof BaseAPI ? this.constructor : void 0) === BaseAPI) { throw new TypeError('Cannot construct BaseAPI instances directly'); } this.currentState = global_constants.STATE_NOT_INITIALIZED; this.lastErrorCode = 0; this.listenerArray = []; _classPrivateFieldSet(this, _timeout, null); _classPrivateFieldSet(this, _error_codes, error_codes); this.settings = settings; this.apiLogLevel = this.settings.logLevel; this.selfReportSessionTime = this.settings.selfReportSessionTime; } /** * Initialize the API * @param {string} callbackName * @param {string} initializeMessage * @param {string} terminationMessage * @return {string} */ _createClass(BaseAPI, [{ key: "initialize", value: function initialize(callbackName, initializeMessage, terminationMessage) { var returnValue = global_constants.SCORM_FALSE; if (this.isInitialized()) { this.throwSCORMError(_classPrivateFieldGet(this, _error_codes).INITIALIZED, initializeMessage); } else if (this.isTerminated()) { this.throwSCORMError(_classPrivateFieldGet(this, _error_codes).TERMINATED, terminationMessage); } else { if (this.selfReportSessionTime) { this.cmi.setStartTime(); } this.currentState = global_constants.STATE_INITIALIZED; this.lastErrorCode = 0; returnValue = global_constants.SCORM_TRUE; this.processListeners(callbackName); } this.apiLog(callbackName, null, 'returned: ' + returnValue, global_constants.LOG_LEVEL_INFO); this.clearSCORMError(returnValue); return returnValue; } /** * Getter for #error_codes * @return {object} */ }, { key: "error_codes", get: function get() { return _classPrivateFieldGet(this, _error_codes); } /** * Getter for #settings * @return {object} */ }, { key: "settings", get: function get() { return _classPrivateFieldGet(this, _settings); } /** * Setter for #settings * @param {object} settings */ , set: function set(settings) { _classPrivateFieldSet(this, _settings, _objectSpread(_objectSpread({}, _classPrivateFieldGet(this, _settings)), settings)); } /** * Terminates the current run of the API * @param {string} callbackName * @param {boolean} checkTerminated * @return {string} */ }, { key: "terminate", value: function terminate(callbackName, checkTerminated) { var returnValue = global_constants.SCORM_FALSE; if (this.checkState(checkTerminated, _classPrivateFieldGet(this, _error_codes).TERMINATION_BEFORE_INIT, _classPrivateFieldGet(this, _error_codes).MULTIPLE_TERMINATION)) { this.currentState = global_constants.STATE_TERMINATED; var result = this.storeData(true); if (!this.settings.sendBeaconCommit && !this.settings.asyncCommit && typeof result.errorCode !== 'undefined' && result.errorCode > 0) { this.throwSCORMError(result.errorCode); } returnValue = typeof result !== 'undefined' && result.result ? result.result : global_constants.SCORM_FALSE; if (checkTerminated) this.lastErrorCode = 0; returnValue = global_constants.SCORM_TRUE; this.processListeners(callbackName); } this.apiLog(callbackName, null, 'returned: ' + returnValue, global_constants.LOG_LEVEL_INFO); this.clearSCORMError(returnValue); return returnValue; } /** * Get the value of the CMIElement. * * @param {string} callbackName * @param {boolean} checkTerminated * @param {string} CMIElement * @return {string} */ }, { key: "getValue", value: function getValue(callbackName, checkTerminated, CMIElement) { var returnValue; if (this.checkState(checkTerminated, _classPrivateFieldGet(this, _error_codes).RETRIEVE_BEFORE_INIT, _classPrivateFieldGet(this, _error_codes).RETRIEVE_AFTER_TERM)) { if (checkTerminated) this.lastErrorCode = 0; try { returnValue = this.getCMIValue(CMIElement); } catch (e) { if (e instanceof _exceptions__WEBPACK_IMPORTED_MODULE_1__.ValidationError) { this.lastErrorCode = e.errorCode; returnValue = global_constants.SCORM_FALSE; } else { if (e.message) { console.error(e.message); } else { console.error(e); } this.throwSCORMError(_classPrivateFieldGet(this, _error_codes).GENERAL); } } this.processListeners(callbackName, CMIElement); } this.apiLog(callbackName, CMIElement, ': returned: ' + returnValue, global_constants.LOG_LEVEL_INFO); this.clearSCORMError(returnValue); return returnValue; } /** * Sets the value of the CMIElement. * * @param {string} callbackName * @param {string} commitCallback * @param {boolean} checkTerminated * @param {string} CMIElement * @param {*} value * @return {string} */ }, { key: "setValue", value: function setValue(callbackName, commitCallback, checkTerminated, CMIElement, value) { if (value !== undefined) { value = String(value); } var returnValue = global_constants.SCORM_FALSE; if (this.checkState(checkTerminated, _classPrivateFieldGet(this, _error_codes).STORE_BEFORE_INIT, _classPrivateFieldGet(this, _error_codes).STORE_AFTER_TERM)) { if (checkTerminated) this.lastErrorCode = 0; try { returnValue = this.setCMIValue(CMIElement, value); } catch (e) { if (e instanceof _exceptions__WEBPACK_IMPORTED_MODULE_1__.ValidationError) { this.lastErrorCode = e.errorCode; returnValue = global_constants.SCORM_FALSE; } else { if (e.message) { console.error(e.message); } else { console.error(e); } this.throwSCORMError(_classPrivateFieldGet(this, _error_codes).GENERAL); } } this.processListeners(callbackName, CMIElement, value); } if (returnValue === undefined) { returnValue = global_constants.SCORM_FALSE; } // If we didn't have any errors while setting the data, go ahead and // schedule a commit, if autocommit is turned on if (String(this.lastErrorCode) === '0') { if (this.settings.autocommit && !_classPrivateFieldGet(this, _timeout)) { this.scheduleCommit(this.settings.autocommitSeconds * 1000, commitCallback); } } this.apiLog(callbackName, CMIElement, ': ' + value + ': result: ' + returnValue, global_constants.LOG_LEVEL_INFO); this.clearSCORMError(returnValue); return returnValue; } /** * Orders LMS to store all content parameters * @param {string} callbackName * @param {boolean} checkTerminated * @return {string} */ }, { key: "commit", value: function commit(callbackName, checkTerminated) { this.clearScheduledCommit(); var returnValue = global_constants.SCORM_FALSE; if (this.checkState(checkTerminated, _classPrivateFieldGet(this, _error_codes).COMMIT_BEFORE_INIT, _classPrivateFieldGet(this, _error_codes).COMMIT_AFTER_TERM)) { var result = this.storeData(false); if (!this.settings.sendBeaconCommit && !this.settings.asyncCommit && result.errorCode && result.errorCode > 0) { this.throwSCORMError(result.errorCode); } returnValue = typeof result !== 'undefined' && result.result ? result.result : global_constants.SCORM_FALSE; this.apiLog(callbackName, 'HttpRequest', ' Result: ' + returnValue, global_constants.LOG_LEVEL_DEBUG); if (checkTerminated) this.lastErrorCode = 0; this.processListeners(callbackName); } this.apiLog(callbackName, null, 'returned: ' + returnValue, global_constants.LOG_LEVEL_INFO); this.clearSCORMError(returnValue); return returnValue; } /** * Returns last error code * @param {string} callbackName * @return {string} */ }, { key: "getLastError", value: function getLastError(callbackName) { var returnValue = String(this.lastErrorCode); this.processListeners(callbackName); this.apiLog(callbackName, null, 'returned: ' + returnValue, global_constants.LOG_LEVEL_INFO); return returnValue; } /** * Returns the errorNumber error description * * @param {string} callbackName * @param {(string|number)} CMIErrorCode * @return {string} */ }, { key: "getErrorString", value: function getErrorString(callbackName, CMIErrorCode) { var returnValue = ''; if (CMIErrorCode !== null && CMIErrorCode !== '') { returnValue = this.getLmsErrorMessageDetails(CMIErrorCode); this.processListeners(callbackName); } this.apiLog(callbackName, null, 'returned: ' + returnValue, global_constants.LOG_LEVEL_INFO); return returnValue; } /** * Returns a comprehensive description of the errorNumber error. * * @param {string} callbackName * @param {(string|number)} CMIErrorCode * @return {string} */ }, { key: "getDiagnostic", value: function getDiagnostic(callbackName, CMIErrorCode) { var returnValue = ''; if (CMIErrorCode !== null && CMIErrorCode !== '') { returnValue = this.getLmsErrorMessageDetails(CMIErrorCode, true); this.processListeners(callbackName); } this.apiLog(callbackName, null, 'returned: ' + returnValue, global_constants.LOG_LEVEL_INFO); return returnValue; } /** * Checks the LMS state and ensures it has been initialized. * * @param {boolean} checkTerminated * @param {number} beforeInitError * @param {number} afterTermError * @return {boolean} */ }, { key: "checkState", value: function checkState(checkTerminated, beforeInitError, afterTermError) { if (this.isNotInitialized()) { this.throwSCORMError(beforeInitError); return false; } else if (checkTerminated && this.isTerminated()) { this.throwSCORMError(afterTermError); return false; } return true; } /** * Logging for all SCORM actions * * @param {string} functionName * @param {string} CMIElement * @param {string} logMessage * @param {number}messageLevel */ }, { key: "apiLog", value: function apiLog(functionName, CMIElement, logMessage, messageLevel) { logMessage = this.formatMessage(functionName, CMIElement, logMessage); if (messageLevel >= this.apiLogLevel) { this.settings.onLogMessage(messageLevel, logMessage); } } /** * Formats the SCORM messages for easy reading * * @param {string} functionName * @param {string} CMIElement * @param {string} message * @return {string} */ }, { key: "formatMessage", value: function formatMessage(functionName, CMIElement, message) { var baseLength = 20; var messageString = ''; messageString += functionName; var fillChars = baseLength - messageString.length; for (var i = 0; i < fillChars; i++) { messageString += ' '; } messageString += ': '; if (CMIElement) { var CMIElementBaseLength = 70; messageString += CMIElement; fillChars = CMIElementBaseLength - messageString.length; for (var j = 0; j < fillChars; j++) { messageString += ' '; } } if (message) { messageString += message; } return messageString; } /** * Checks to see if {str} contains {tester} * * @param {string} str String to check against * @param {string} tester String to check for * @return {boolean} */ }, { key: "stringMatches", value: function stringMatches(str, tester) { return str && tester && str.match(tester); } /** * Check to see if the specific object has the given property * @param {*} refObject * @param {string} attribute * @return {boolean} * @private */ }, { key: "_checkObjectHasProperty", value: function _checkObjectHasProperty(refObject, attribute) { return Object.hasOwnProperty.call(refObject, attribute) || Object.getOwnPropertyDescriptor(Object.getPrototypeOf(refObject), attribute) || attribute in refObject; } /** * Returns the message that corresponds to errorNumber * APIs that inherit BaseAPI should override this function * * @param {(string|number)} _errorNumber * @param {boolean} _detail * @return {string} * @abstract */ }, { key: "getLmsErrorMessageDetails", value: function getLmsErrorMessageDetails(_errorNumber, _detail) { throw new Error('The getLmsErrorMessageDetails method has not been implemented'); } /** * Gets the value for the specific element. * APIs that inherit BaseAPI should override this function * * @param {string} _CMIElement * @return {string} * @abstract */ }, { key: "getCMIValue", value: function getCMIValue(_CMIElement) { throw new Error('The getCMIValue method has not been implemented'); } /** * Sets the value for the specific element. * APIs that inherit BaseAPI should override this function * * @param {string} _CMIElement * @param {any} _value * @return {string} * @abstract */ }, { key: "setCMIValue", value: function setCMIValue(_CMIElement, _value) { throw new Error('The setCMIValue method has not been implemented'); } /** * Shared API method to set a valid for a given element. * * @param {string} methodName * @param {boolean} scorm2004 * @param {string} CMIElement * @param {*} value * @return {string} */ }, { key: "_commonSetCMIValue", value: function _commonSetCMIValue(methodName, scorm2004, CMIElement, value) { if (!CMIElement || CMIElement === '') { return global_constants.SCORM_FALSE; } var structure = CMIElement.split('.'); var refObject = this; var returnValue = global_constants.SCORM_FALSE; var foundFirstIndex = false; var invalidErrorMessage = "The data model element passed to ".concat(methodName, " (").concat(CMIElement, ") is not a valid SCORM data model element."); var invalidErrorCode = scorm2004 ? _classPrivateFieldGet(this, _error_codes).UNDEFINED_DATA_MODEL : _classPrivateFieldGet(this, _error_codes).GENERAL; for (var i = 0; i < structure.length; i++) { var attribute = structure[i]; if (i === structure.length - 1) { if (scorm2004 && attribute.substr(0, 8) === '{target=' && typeof refObject._isTargetValid == 'function') { this.throwSCORMError(_classPrivateFieldGet(this, _error_codes).READ_ONLY_ELEMENT); } else if (!this._checkObjectHasProperty(refObject, attribute)) { this.throwSCORMError(invalidErrorCode, invalidErrorMessage); } else { if (this.isInitialized() && this.stringMatches(CMIElement, '\\.correct_responses\\.\\d+')) { this.validateCorrectResponse(CMIElement, value); } if (!scorm2004 || this.lastErrorCode === 0) { refObject[attribute] = value; returnValue = global_constants.SCORM_TRUE; } } } else { refObject = refObject[attribute]; if (!refObject) { this.throwSCORMError(invalidErrorCode, invalidErrorMessage); break; } if (refObject instanceof _cmi_common__WEBPACK_IMPORTED_MODULE_0__.CMIArray) { var index = parseInt(structure[i + 1], 10); // SCO is trying to set an item on an array if (!isNaN(index)) { var item = refObject.childArray[index]; if (item) { refObject = item; foundFirstIndex = true; } else { var newChild = this.getChildElement(CMIElement, value, foundFirstIndex); foundFirstIndex = true; if (!newChild) { this.throwSCORMError(invalidErrorCode, invalidErrorMessage); } else { if (refObject.initialized) newChild.initialize(); refObject.childArray.push(newChild); refObject = newChild; } } // Have to update i value to skip the array position i++; } } } } if (returnValue === global_constants.SCORM_FALSE) { this.apiLog(methodName, null, "There was an error setting the value for: ".concat(CMIElement, ", value of: ").concat(value), global_constants.LOG_LEVEL_WARNING); } return returnValue; } /** * Abstract method for validating that a response is correct. * * @param {string} _CMIElement * @param {*} _value */ }, { key: "validateCorrectResponse", value: function validateCorrectResponse(_CMIElement, _value) {// just a stub method } /** * Gets or builds a new child element to add to the array. * APIs that inherit BaseAPI should override this method. * * @param {string} _CMIElement - unused * @param {*} _value - unused * @param {boolean} _foundFirstIndex - unused * @return {*} * @abstract */ }, { key: "getChildElement", value: function getChildElement(_CMIElement, _value, _foundFirstIndex) { throw new Error('The getChildElement method has not been implemented'); } /** * Gets a value from the CMI Object * * @param {string} methodName * @param {boolean} scorm2004 * @param {string} CMIElement * @return {*} */ }, { key: "_commonGetCMIValue", value: function _commonGetCMIValue(methodName, scorm2004, CMIElement) { if (!CMIElement || CMIElement === '') { return ''; } var structure = CMIElement.split('.'); var refObject = this; var attribute = null; var uninitializedErrorMessage = "The data model element passed to ".concat(methodName, " (").concat(CMIElement, ") has not been initialized."); var invalidErrorMessage = "The data model element passed to ".concat(methodName, " (").concat(CMIElement, ") is not a valid SCORM data model element."); var invalidErrorCode = scorm2004 ? _classPrivateFieldGet(this, _error_codes).UNDEFINED_DATA_MODEL : _classPrivateFieldGet(this, _error_codes).GENERAL; for (var i = 0; i < structure.length; i++) { attribute = structure[i]; if (!scorm2004) { if (i === structure.length - 1) { if (!this._checkObjectHasProperty(refObject, attribute)) { this.throwSCORMError(invalidErrorCode, invalidErrorMessage); return; } } } else { if (String(attribute).substr(0, 8) === '{target=' && typeof refObject._isTargetValid == 'function') { var target = String(attribute).substr(8, String(attribute).length - 9); return refObject._isTargetValid(target); } else if (!this._checkObjectHasProperty(refObject, attribute)) { this.throwSCORMError(invalidErrorCode, invalidErrorMessage); return; } } refObject = refObject[attribute]; if (refObject === undefined) { this.throwSCORMError(invalidErrorCode, invalidErrorMessage); break; } if (refObject instanceof _cmi_common__WEBPACK_IMPORTED_MODULE_0__.CMIArray) { var index = parseInt(structure[i + 1], 10); // SCO is trying to set an item on an array if (!isNaN(index)) { var item = refObject.childArray[index]; if (item) { refObject = item; } else { this.throwSCORMError(_classPrivateFieldGet(this, _error_codes).VALUE_NOT_INITIALIZED, uninitializedErrorMessage); break; } // Have to update i value to skip the array position i++; } } } if (refObject === null || refObject === undefined) { if (!scorm2004) { if (attribute === '_children') { this.throwSCORMError(scorm12_error_codes.CHILDREN_ERROR); } else if (attribute === '_count') { this.throwSCORMError(scorm12_error_codes.COUNT_ERROR); } } } else {