var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
import { r as registerInstance, c as createEvent, g as getContext, h, d as getElement } from './core-e0edbf68.js';
import './_commonjsHelpers-97e6d7b1.js';
import { b as baseIsEqual, i as isArrayLike, a as isArray, c as isBuffer, d as isTypedArray, e as isArguments, g as getTag, f as isPrototype, h as baseKeys, j as isObject, k as isIndex, l as eq, m as isSymbol, P as PieLoader, V as VERSION, n as cloneDeep, p as parseNpm, o as pieContentFromConfig, q as complexRubricChecks, r as removeComplexRubricFromMarkup, C as COMPLEX_RUBRIC, s as addPackageToContent, t as addModelToContent, u as createTag, v as addComplexRubric, w as renderMath, x as addRubric, y as addMultiTraitRubric, D as DEFAULT_ENDPOINTS } from './version-4a0b58c6.js';
import { l as lib_3, a as lib_2, b as lib_5, c as lib_4, d as lib_1 } from './index-74202bbc.js';
/**
 * Performs a deep comparison between two values to determine if they are
 * equivalent.
 *
 * **Note:** This method supports comparing arrays, array buffers, booleans,
 * date objects, error objects, maps, numbers, `Object` objects, regexes,
 * sets, strings, symbols, and typed arrays. `Object` objects are compared
 * by their own, not inherited, enumerable properties. Functions and DOM
 * nodes are compared by strict equality, i.e. `===`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to compare.
 * @param {*} other The other value to compare.
 * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
 * @example
 *
 * var object = { 'a': 1 };
 * var other = { 'a': 1 };
 *
 * _.isEqual(object, other);
 * // => true
 *
 * object === other;
 * // => false
 */
function isEqual(value, other) {
    return baseIsEqual(value, other);
}
var isEqual_1 = isEqual;
/** `Object#toString` result references. */
var mapTag = '[object Map]', setTag = '[object Set]';
/** Used for built-in method references. */
var objectProto = Object.prototype;
/** Used to check objects for own properties. */
var hasOwnProperty = objectProto.hasOwnProperty;
/**
 * Checks if `value` is an empty object, collection, map, or set.
 *
 * Objects are considered empty if they have no own enumerable string keyed
 * properties.
 *
 * Array-like values such as `arguments` objects, arrays, buffers, strings, or
 * jQuery-like collections are considered empty if they have a `length` of `0`.
 * Similarly, maps and sets are considered empty if they have a `size` of `0`.
 *
 * @static
 * @memberOf _
 * @since 0.1.0
 * @category Lang
 * @param {*} value The value to check.
 * @returns {boolean} Returns `true` if `value` is empty, else `false`.
 * @example
 *
 * _.isEmpty(null);
 * // => true
 *
 * _.isEmpty(true);
 * // => true
 *
 * _.isEmpty(1);
 * // => true
 *
 * _.isEmpty([1, 2, 3]);
 * // => false
 *
 * _.isEmpty({ 'a': 1 });
 * // => false
 */
function isEmpty(value) {
    if (value == null) {
        return true;
    }
    if (isArrayLike(value) &&
        (isArray(value) || typeof value == 'string' || typeof value.splice == 'function' ||
            isBuffer(value) || isTypedArray(value) || isArguments(value))) {
        return !value.length;
    }
    var tag = getTag(value);
    if (tag == mapTag || tag == setTag) {
        return !value.size;
    }
    if (isPrototype(value)) {
        return !baseKeys(value).length;
    }
    for (var key in value) {
        if (hasOwnProperty.call(value, key)) {
            return false;
        }
    }
    return true;
}
var isEmpty_1 = isEmpty;
/* Built-in method references for those with the same name as other `lodash` methods. */
var nativeCeil = Math.ceil, nativeMax = Math.max;
/**
 * The base implementation of `_.range` and `_.rangeRight` which doesn't
 * coerce arguments.
 *
 * @private
 * @param {number} start The start of the range.
 * @param {number} end The end of the range.
 * @param {number} step The value to increment or decrement by.
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Array} Returns the range of numbers.
 */
function baseRange(start, end, step, fromRight) {
    var index = -1, length = nativeMax(nativeCeil((end - start) / (step || 1)), 0), result = Array(length);
    while (length--) {
        result[fromRight ? length : ++index] = start;
        start += step;
    }
    return result;
}
var _baseRange = baseRange;
/**
 * Checks if the given arguments are from an iteratee call.
 *
 * @private
 * @param {*} value The potential iteratee value argument.
 * @param {*} index The potential iteratee index or key argument.
 * @param {*} object The potential iteratee object argument.
 * @returns {boolean} Returns `true` if the arguments are from an iteratee call,
 *  else `false`.
 */
function isIterateeCall(value, index, object) {
    if (!isObject(object)) {
        return false;
    }
    var type = typeof index;
    if (type == 'number'
        ? (isArrayLike(object) && isIndex(index, object.length))
        : (type == 'string' && index in object)) {
        return eq(object[index], value);
    }
    return false;
}
var _isIterateeCall = isIterateeCall;
/** Used to match a single whitespace character. */
var reWhitespace = /\s/;
/**
 * Used by `_.trim` and `_.trimEnd` to get the index of the last non-whitespace
 * character of `string`.
 *
 * @private
 * @param {string} string The string to inspect.
 * @returns {number} Returns the index of the last non-whitespace character.
 */
function trimmedEndIndex(string) {
    var index = string.length;
    while (index-- && reWhitespace.test(string.charAt(index))) { }
    return index;
}
var _trimmedEndIndex = trimmedEndIndex;
/** Used to match leading whitespace. */
var reTrimStart = /^\s+/;
/**
 * The base implementation of `_.trim`.
 *
 * @private
 * @param {string} string The string to trim.
 * @returns {string} Returns the trimmed string.
 */
function baseTrim(string) {
    return string
        ? string.slice(0, _trimmedEndIndex(string) + 1).replace(reTrimStart, '')
        : string;
}
var _baseTrim = baseTrim;
/** Used as references for various `Number` constants. */
var NAN = 0 / 0;
/** 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;
/**
 * 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 = _baseTrim(value);
    var isBinary = reIsBinary.test(value);
    return (isBinary || reIsOctal.test(value))
        ? freeParseInt(value.slice(2), isBinary ? 2 : 8)
        : (reIsBadHex.test(value) ? NAN : +value);
}
var toNumber_1 = toNumber;
/** Used as references for various `Number` constants. */
var INFINITY = 1 / 0, MAX_INTEGER = 1.7976931348623157e+308;
/**
 * Converts `value` to a finite number.
 *
 * @static
 * @memberOf _
 * @since 4.12.0
 * @category Lang
 * @param {*} value The value to convert.
 * @returns {number} Returns the converted number.
 * @example
 *
 * _.toFinite(3.2);
 * // => 3.2
 *
 * _.toFinite(Number.MIN_VALUE);
 * // => 5e-324
 *
 * _.toFinite(Infinity);
 * // => 1.7976931348623157e+308
 *
 * _.toFinite('3.2');
 * // => 3.2
 */
function toFinite(value) {
    if (!value) {
        return value === 0 ? value : 0;
    }
    value = toNumber_1(value);
    if (value === INFINITY || value === -INFINITY) {
        var sign = (value < 0 ? -1 : 1);
        return sign * MAX_INTEGER;
    }
    return value === value ? value : 0;
}
var toFinite_1 = toFinite;
/**
 * Creates a `_.range` or `_.rangeRight` function.
 *
 * @private
 * @param {boolean} [fromRight] Specify iterating from right to left.
 * @returns {Function} Returns the new range function.
 */
function createRange(fromRight) {
    return function (start, end, step) {
        if (step && typeof step != 'number' && _isIterateeCall(start, end, step)) {
            end = step = undefined;
        }
        // Ensure the sign of `-0` is preserved.
        start = toFinite_1(start);
        if (end === undefined) {
            end = start;
            start = 0;
        }
        else {
            end = toFinite_1(end);
        }
        step = step === undefined ? (start < end ? 1 : -1) : toFinite_1(step);
        return _baseRange(start, end, step, fromRight);
    };
}
var _createRange = createRange;
/**
 * Creates an array of numbers (positive and/or negative) progressing from
 * `start` up to, but not including, `end`. A step of `-1` is used if a negative
 * `start` is specified without an `end` or `step`. If `end` is not specified,
 * it's set to `start` with `start` then set to `0`.
 *
 * **Note:** JavaScript follows the IEEE-754 standard for resolving
 * floating-point values which can produce unexpected results.
 *
 * @static
 * @since 0.1.0
 * @memberOf _
 * @category Util
 * @param {number} [start=0] The start of the range.
 * @param {number} end The end of the range.
 * @param {number} [step=1] The value to increment or decrement by.
 * @returns {Array} Returns the range of numbers.
 * @see _.inRange, _.rangeRight
 * @example
 *
 * _.range(4);
 * // => [0, 1, 2, 3]
 *
 * _.range(-4);
 * // => [0, -1, -2, -3]
 *
 * _.range(1, 5);
 * // => [1, 2, 3, 4]
 *
 * _.range(0, 20, 5);
 * // => [0, 5, 10, 15]
 *
 * _.range(0, -4, -1);
 * // => [0, -1, -2, -3]
 *
 * _.range(1, 4, 0);
 * // => [1, 1, 1]
 *
 * _.range(0);
 * // => []
 */
var range = _createRange();
var range_1 = range;
var DataURLImageSupport = /** @class */ (function () {
    function DataURLImageSupport() {
    }
    DataURLImageSupport.prototype.insert = function (file, done, progressFn) {
        var reader = new FileReader();
        reader.onload = function () {
            var dataURL = reader.result;
            setTimeout(function () {
                done(null, dataURL.toString());
            }, 2000);
        };
        var progress = 0;
        progressFn(progress, 0, 100);
        range_1(1, 100).forEach(function (n) {
            setTimeout(function () {
                progressFn(n, n, 100);
            }, n * 20);
        });
        // if external asset support .. add reader.readAsArrayBuffer ..
        reader.readAsDataURL(file);
    };
    DataURLImageSupport.prototype.delete = function (src, done) {
        done();
    };
    return DataURLImageSupport;
}());
var DataURLUploadSoundSupport = /** @class */ (function () {
    function DataURLUploadSoundSupport() {
    }
    DataURLUploadSoundSupport.prototype.insert = function (file, done, progressFn) {
        var reader = new FileReader();
        reader.onload = function () {
            var dataURL = reader.result;
            setTimeout(function () {
                done(null, dataURL.toString());
            }, 2000);
        };
        var progress = 0;
        progressFn(progress, 0, 100);
        range_1(1, 100).forEach(function (n) {
            setTimeout(function () {
                progressFn(n, n, 100);
            }, n * 20);
        });
        // if external asset support .. add reader.readAsArrayBuffer ..
        reader.readAsDataURL(file);
    };
    DataURLUploadSoundSupport.prototype.delete = function (src, done) {
        done();
    };
    return DataURLUploadSoundSupport;
}());
var Author = /** @class */ (function () {
    function class_1(hostRef) {
        var _this = this;
        registerInstance(this, hostRef);
        this._modelLoadedState = false;
        /**
         * Allows disabling of the default behaviour which is to look up and load the JS bundle that define the Custom Elements
         * used by the item config.
         * This if for advanced use cases when using the pie-player in a container that is managing loading of Custom Elements and Controllers.
         */
        this.disableBundler = false;
        /**
         * Adds a preview view which will render the content in another tab as it may appear to a student or instructor.
         */
        this.addPreview = false;
        this.elementsLoaded = false;
        /**
         * If pie-author is used inside pie-api-author component. Do not set it manually.
         */
        this.isInsidePieApiAuthor = false;
        this.pieLoader = new PieLoader();
        this.fileInput = null;
        this.imageHandler = null;
        /** external providers can set this if they need to upload the assets to the cloud etc. by default we use data urls */
        this.imageSupport = new DataURLImageSupport();
        /** external providers can set this if they need to upload the assets to the cloud etc. by default we use data urls */
        this.uploadSoundSupport = new DataURLUploadSoundSupport();
        this.version = VERSION;
        /**
         * used in our demo environment to allow author to watch config settings and make updates
         * defaults to false (do not set it to true because it was not tested properly)
         * @type {boolean}
         * @private
         */
        this.canWatchConfigSettings = false;
        this.isAdvancedItemConfig = function (config) { return config.pie; };
        this.getPieContentModelWithToggledComplexRubric = function (_a) {
            var complexRubricCheckedValues = _a.complexRubricCheckedValues, pieContentModel = _a.pieContentModel;
            return __awaiter(_this, void 0, void 0, function () {
                var _b, shouldAddComplexRubric, shouldRemoveComplexRubric, complexRubricElements;
                return __generator(this, function (_c) {
                    _b = complexRubricCheckedValues || {}, shouldAddComplexRubric = _b.shouldAddComplexRubric, shouldRemoveComplexRubric = _b.shouldRemoveComplexRubric, complexRubricElements = _b.complexRubricElements;
                    if (shouldAddComplexRubric) {
                        // we add complex-rubric to config
                        return [2 /*return*/, this.addComplexRubric(cloneDeep(pieContentModel))];
                    }
                    if (shouldRemoveComplexRubric) {
                        // we remove complex-rubric from config
                        return [2 /*return*/, this.removeComplexRubricItemTypes(cloneDeep(pieContentModel), complexRubricElements)];
                    }
                    return [2 /*return*/, null];
                });
            });
        };
        this.getNewConfig = function (newConfig) {
            if (_this.isAdvancedItemConfig(_this.config)) {
                return Object.assign(Object.assign({}, _this.config), { pie: newConfig });
            }
            return newConfig;
        };
        this.setModelsAndConfigurations = function () {
            if (_this.pieContentModel && _this.pieContentModel.models) {
                _this.pieContentModel.models.map(function (model) {
                    var pieEl = _this.el.querySelector("[id='" + model.id + "']");
                    !pieEl && (pieEl = _this.el.querySelector("[pie-id='" + model.id + "']"));
                    if (pieEl) {
                        var pieElName = pieEl.tagName.toLowerCase().split("-config")[0];
                        try {
                            var packageName = parseNpm(_this.pieContentModel.elements[pieElName]).name;
                            pieEl.model = model;
                            if (_this.configSettings && _this.configSettings[packageName]) {
                                pieEl.configuration = _this.configSettings[packageName];
                            }
                        }
                        catch (e) {
                            console.log(e.toString(), pieElName, _this.pieContentModel.elements[pieElName]);
                        }
                    }
                });
            }
        };
        this.handleFileInputChange = function (e) {
            var input = e.target;
            if (!_this.imageHandler) {
                console.error("no image handler - but file input change triggered?");
                return;
            }
            var files = input.files;
            if (files.length < 1 || !files[0]) {
                _this.imageHandler.cancel();
                _this.imageHandler = null;
            }
            else {
                var file = files[0];
                _this.imageHandler.fileChosen(file);
                _this.fileInput.value = "";
                _this.imageSupport.insert(file, function (e, src) {
                    if (e) {
                        console.warn("error inserting image: ", e.message);
                        console.error(e);
                    }
                    _this.imageHandler.done(e, src);
                    _this.imageHandler = null;
                }, function (percent, bytes, total) { return _this.imageHandler.progress(percent, bytes, total); });
            }
        };
        this.handleInsertImage = function (e) {
            console.log("[handleInsertImage]", e);
            _this.imageHandler = e.detail;
            if (!e.detail.isPasted) {
                _this.fileInput.click();
            }
        };
        this.handleDeleteImage = function (e) {
            console.log("[handleDeleteImage ..]", e);
            _this.imageSupport.delete(e.detail.src, e.detail.done);
        };
        this.handleInsertSound = function (e) {
            console.log("[handleInsertSound]", e);
            _this.uploadSoundSupport.insert(e.detail.fileChosen, e.detail.done);
        };
        this.handleDeleteSound = function (e) {
            console.log("[handleDeleteSound ..]", e);
            _this.uploadSoundSupport.delete(e.detail.src, e.detail.done);
        };
        this.modelUpdated = createEvent(this, "modelUpdated", 7);
        this.modelLoaded = createEvent(this, "modelLoaded", 7);
        this.doc = getContext(this, "document");
    }
    class_1.prototype.validateModels = function () {
        return __awaiter(this, void 0, void 0, function () {
            var _this = this;
            return __generator(this, function (_a) {
                if (!this.pieContentModel || !this.pieContentModel.models) {
                    console.error('No pie content model');
                    return [2 /*return*/, { hasErrors: false, validatedModels: {} }];
                }
                return [2 /*return*/, (this.pieContentModel.models || []).reduce(function (acc, model) {
                        var _a, _b;
                        var pieEl = _this.el.querySelector("[id='" + model.id + "']");
                        !pieEl && (pieEl = _this.el.querySelector("[pie-id='" + model.id + "']"));
                        if (pieEl) {
                            var pieElName = pieEl.tagName.toLowerCase().split("-config")[0];
                            var controller = _this.pieLoader.getController(pieElName);
                            var packageName = parseNpm(_this.pieContentModel.elements[pieElName]).name;
                            var configuration = _this.configSettings && _this.configSettings[packageName] || {};
                            if (controller && controller.validate) {
                                // here we call controller.validate which returns an object with all the errors
                                var errors = controller.validate(model, configuration);
                                // here we can update the model in author, so we can set errors
                                pieEl.model = Object.assign(Object.assign({}, model), { errors: errors });
                                // for ebsr
                                if (errors && errors.partA && errors.partB) {
                                    acc.hasErrors = acc.hasErrors || (!isEmpty_1(errors.partA) || !isEmpty_1(errors.partB));
                                }
                                else {
                                    // here we return a boolean value if models are valid or not
                                    acc.hasErrors = acc.hasErrors || !isEmpty_1(errors);
                                }
                                acc.validatedModels = Object.assign(Object.assign({}, acc.validatedModels), (_a = {}, _a[model.id] = Object.assign(Object.assign({}, model), { errors: errors }), _a));
                            }
                            else {
                                acc.validatedModels = Object.assign(Object.assign({}, acc.validatedModels), (_b = {}, _b[model.id] = model, _b));
                            }
                        }
                        return acc;
                    }, { hasErrors: false, validatedModels: {} })];
            });
        });
    };
    class_1.prototype.getRenderMarkup = function () {
        var markup = this.pieContentModel ? this.pieContentModel.markup : "";
        if (markup) {
            Object.keys(this.pieContentModel.elements).forEach(function (key) {
                markup = markup.split(key).join(key + "-config");
            });
            return markup;
        }
    };
    class_1.prototype.watchConfig = function (newValue, oldValue) {
        return __awaiter(this, void 0, void 0, function () {
            var pieContentModel, complexRubricCheckedValues, _a, shouldAddComplexRubric, shouldRemoveComplexRubric, newConfig, error_1;
            return __generator(this, function (_b) {
                switch (_b.label) {
                    case 0:
                        if (!(newValue && !isEqual_1(newValue, oldValue))) return [3 /*break*/, 7];
                        _b.label = 1;
                    case 1:
                        _b.trys.push([1, 6, , 7]);
                        this.elementsLoaded = false;
                        this._modelLoadedState = false;
                        pieContentModel = pieContentFromConfig(newValue);
                        complexRubricCheckedValues = complexRubricChecks(pieContentModel, this.configSettings);
                        _a = complexRubricCheckedValues || {}, shouldAddComplexRubric = _a.shouldAddComplexRubric, shouldRemoveComplexRubric = _a.shouldRemoveComplexRubric;
                        if (!(shouldAddComplexRubric || shouldRemoveComplexRubric)) return [3 /*break*/, 3];
                        this.pieContentModel = null;
                        return [4 /*yield*/, this.getPieContentModelWithToggledComplexRubric({
                                complexRubricCheckedValues: complexRubricCheckedValues,
                                pieContentModel: pieContentModel
                            })];
                    case 2:
                        newConfig = _b.sent();
                        // and then we reset the config
                        if (newConfig) {
                            this.config = this.getNewConfig(newConfig);
                        }
                        return [3 /*break*/, 5];
                    case 3:
                        // if there's no change needed, we can proceed with updating the config and loading pie-elements
                        this.pieContentModel = pieContentModel;
                        this.addConfigTags(this.pieContentModel);
                        return [4 /*yield*/, this.loadPieElements()];
                    case 4:
                        _b.sent();
                        _b.label = 5;
                    case 5: return [3 /*break*/, 7];
                    case 6:
                        error_1 = _b.sent();
                        console.log("ERROR " + error_1);
                        return [3 /*break*/, 7];
                    case 7: return [2 /*return*/];
                }
            });
        });
    };
    class_1.prototype.removeComplexRubricItemTypes = function (pieContentModel, rubricElements) {
        return __awaiter(this, void 0, void 0, function () {
            var _a, markupWithoutComplexRubric, deletedComplexRubricItemIds;
            return __generator(this, function (_b) {
                if (!rubricElements.length || !pieContentModel.models) {
                    return [2 /*return*/, pieContentModel];
                }
                // delete the complex-rubric elements from elements object
                rubricElements.forEach(function (rubricElementKey) { return delete pieContentModel.elements[rubricElementKey]; });
                _a = removeComplexRubricFromMarkup(pieContentModel, rubricElements, this.doc), markupWithoutComplexRubric = _a.markupWithoutComplexRubric, deletedComplexRubricItemIds = _a.deletedComplexRubricItemIds;
                // delete the complex-rubric nodes from markup
                pieContentModel.markup = markupWithoutComplexRubric;
                // delete the complex-rubric models
                pieContentModel.models = pieContentModel.models.filter(function (model) { return !deletedComplexRubricItemIds.includes(model.id); });
                return [2 /*return*/, pieContentModel];
            });
        });
    };
    class_1.prototype.addComplexRubric = function (pieContentModel) {
        return __awaiter(this, void 0, void 0, function () {
            var complexRubricModel, packageName, content;
            return __generator(this, function (_a) {
                complexRubricModel = Object.assign({ id: COMPLEX_RUBRIC, element: "pie-" + COMPLEX_RUBRIC }, this.defaultComplexRubricModel || {});
                packageName = "@pie-element/" + COMPLEX_RUBRIC;
                content = addPackageToContent(pieContentModel, packageName, complexRubricModel);
                // but if complex-rubric is already in elements, then just add it in the models
                if (!content) {
                    content = addModelToContent(pieContentModel, createTag(packageName), complexRubricModel);
                }
                return [2 /*return*/, addComplexRubric(content)];
            });
        });
    };
    class_1.prototype.addConfigTags = function (c) {
        if (!c.markup && c.models) {
            var tags = c.models.map(function (model) {
                return "<" + model.element + "-config id=\"" + model.id + "\"></" + model.element + "-config>";
            });
            c.markup = tags.join("");
        }
    };
    class_1.prototype.watchElementsLoaded = function (newValue, oldValue) {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!(newValue && !oldValue)) return [3 /*break*/, 2];
                        return [4 /*yield*/, this.updateModels()];
                    case 1:
                        _a.sent();
                        _a.label = 2;
                    case 2: return [2 /*return*/];
                }
            });
        });
    };
    class_1.prototype.updateModels = function () {
        return __awaiter(this, void 0, void 0, function () {
            var tempDiv, elsWithId;
            var _this = this;
            return __generator(this, function (_a) {
                if (this.pieContentModel &&
                    this.pieContentModel.elements &&
                    this.pieContentModel.markup) {
                    if (!this.pieContentModel.models) {
                        this.pieContentModel.models = [];
                    }
                    tempDiv = this.doc.createElement("div");
                    tempDiv.innerHTML = this.pieContentModel.markup;
                    elsWithId = tempDiv.querySelectorAll("[id]");
                    // set up a model for each pie defined in the markup
                    elsWithId.forEach(function (el) {
                        var pieElName = el.tagName.toLowerCase().split("-config")[0];
                        // initialize emtpy model if this is a pie
                        if (_this.pieContentModel.elements[pieElName]) {
                            var elementId_1 = el.getAttribute("id");
                            if (!_this.pieContentModel.models.find(function (m) { return m.id === elementId_1; })) {
                                var model = { id: elementId_1, element: pieElName };
                                _this.pieContentModel.models.push(model);
                            }
                        }
                    });
                    tempDiv.remove();
                }
                if (this.pieContentModel && this.pieContentModel.models) {
                    this.setModelsAndConfigurations();
                    if (this._modelLoadedState === false) {
                        this._modelLoadedState = true;
                        this.modelLoaded.emit(this.pieContentModel);
                    }
                }
                return [2 /*return*/];
            });
        });
    };
    class_1.prototype.watchConfigSettings = function () {
        if (this.canWatchConfigSettings) {
            this.setModelsAndConfigurations();
        }
    };
    class_1.prototype.componentDidUnload = function () {
        this.el.removeEventListener(lib_3.TYPE, this.handleInsertImage);
        this.el.removeEventListener(lib_2.TYPE, this.handleDeleteImage);
        this.el.removeEventListener(lib_5.TYPE, this.handleInsertSound);
        this.el.removeEventListener(lib_4.TYPE, this.handleDeleteSound);
        if (this.fileInput) {
            this.fileInput.removeEventListener("change", this.handleFileInputChange);
        }
    };
    class_1.prototype.componentWillLoad = function () {
        return __awaiter(this, void 0, void 0, function () {
            var _this = this;
            return __generator(this, function (_a) {
                if (this.config) {
                    this.watchConfig(this.config, {});
                }
                // Note: cannot use the @Listen decorator as creates bundling problems due
                // to `.` in event name.
                this.el.addEventListener(lib_1.TYPE, function (e) { return __awaiter(_this, void 0, void 0, function () {
                    var rubricChanged, complexRubricCheckedValues, _a, shouldAddComplexRubric, shouldRemoveComplexRubric, newPieContentModel;
                    return __generator(this, function (_b) {
                        switch (_b.label) {
                            case 0:
                                if (this.pieContentModel && e.update) {
                                    this.pieContentModel.models.forEach(function (m) {
                                        if (m.id === e.update.id && m.element === e.update.element) {
                                            rubricChanged = rubricChanged || m.rubricEnabled !== e.update.rubricEnabled;
                                            Object.assign(m, e.update);
                                        }
                                    });
                                }
                                if (!this._modelLoadedState) return [3 /*break*/, 7];
                                if (!rubricChanged) return [3 /*break*/, 6];
                                if (!this.isInsidePieApiAuthor) return [3 /*break*/, 3];
                                complexRubricCheckedValues = complexRubricChecks(this.pieContentModel, this.configSettings);
                                _a = complexRubricCheckedValues || {}, shouldAddComplexRubric = _a.shouldAddComplexRubric, shouldRemoveComplexRubric = _a.shouldRemoveComplexRubric;
                                if (!(shouldAddComplexRubric || shouldRemoveComplexRubric)) return [3 /*break*/, 2];
                                return [4 /*yield*/, this.getPieContentModelWithToggledComplexRubric({
                                        complexRubricCheckedValues: complexRubricCheckedValues,
                                        pieContentModel: this.pieContentModel
                                    })];
                            case 1:
                                newPieContentModel = _b.sent();
                                // last thing to do is to make sure we send the updated pie content model to pie-api-author
                                // (which listens for this event) who will trigger watchConfig
                                if (newPieContentModel) {
                                    this.modelUpdated.emit(newPieContentModel);
                                }
                                _b.label = 2;
                            case 2: return [3 /*break*/, 5];
                            case 3: 
                            // however, if we only use pie-player-components, just force the call to watchConfig
                            return [4 /*yield*/, this.watchConfig(this.config, {})];
                            case 4:
                                // however, if we only use pie-player-components, just force the call to watchConfig
                                _b.sent();
                                _b.label = 5;
                            case 5: return [3 /*break*/, 7];
                            case 6:
                                // if rubricEnabled did not change, just behave as previously
                                // (pie-api-author listens for this event and triggers watchConfig)
                                this.modelUpdated.emit(this.pieContentModel);
                                _b.label = 7;
                            case 7: return [2 /*return*/];
                        }
                    });
                }); });
                this.el.addEventListener(lib_3.TYPE, this.handleInsertImage);
                this.el.addEventListener(lib_2.TYPE, this.handleDeleteImage);
                this.el.addEventListener(lib_5.TYPE, this.handleInsertSound);
                this.el.addEventListener(lib_4.TYPE, this.handleDeleteSound);
                return [2 /*return*/];
            });
        });
    };
    class_1.prototype.componentDidLoad = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.afterRender()];
                    case 1:
                        _a.sent();
                        return [2 /*return*/];
                }
            });
        });
    };
    class_1.prototype.componentDidUpdate = function () {
        return __awaiter(this, void 0, void 0, function () {
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, this.afterRender()];
                    case 1:
                        _a.sent();
                        if (this.fileInput) {
                            this.fileInput.addEventListener("change", this.handleFileInputChange);
                        }
                        return [2 /*return*/];
                }
            });
        });
    };
    class_1.prototype.loadPieElements = function () {
        return __awaiter(this, void 0, void 0, function () {
            var endpoints;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!(this.config && !this.disableBundler)) return [3 /*break*/, 2];
                        endpoints = DEFAULT_ENDPOINTS.prod;
                        if (this.bundleHost &&
                            ["dev", "stage", "prod"].includes(this.bundleHost)) {
                            endpoints = DEFAULT_ENDPOINTS[this.bundleHost];
                        }
                        if (this.bundleEndpoints) {
                            endpoints = this.bundleEndpoints;
                        }
                        return [4 /*yield*/, this.pieLoader.loadCloudPies({
                                content: this.pieContentModel,
                                doc: this.doc,
                                endpoints: endpoints,
                                useCdn: false
                            })];
                    case 1:
                        _a.sent();
                        _a.label = 2;
                    case 2: return [2 /*return*/];
                }
            });
        });
    };
    class_1.prototype.renderMath = function () {
        var _this = this;
        setTimeout(function () {
            renderMath(_this.el);
        }, 50);
    };
    class_1.prototype.afterRender = function () {
        return __awaiter(this, void 0, void 0, function () {
            var elements, loadedInfo;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!(this.pieContentModel &&
                            this.pieContentModel.markup &&
                            !this.elementsLoaded)) return [3 /*break*/, 2];
                        elements = Object.keys(this.pieContentModel.elements).map(function (el) { return ({
                            name: el,
                            tag: el + "-config"
                        }); });
                        return [4 /*yield*/, this.pieLoader.elementsHaveLoaded(elements)];
                    case 1:
                        loadedInfo = _a.sent();
                        if (loadedInfo.val &&
                            !!loadedInfo.elements.find(function (el) { return _this.pieContentModel.elements[el.name]; })) {
                            this.elementsLoaded = true;
                            this.renderMath();
                        }
                        _a.label = 2;
                    case 2: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Utility method to add a `@pie-element/rubric` section to an item config when creating an item should be used before setting the config.
     *
     * @deprecated this method is for temporary use, will be removed at next major release
     *
     * @param config the item config to mutate
     * @param rubricModel
     */
    class_1.prototype.addRubricToConfig = function (config, rubricModel) {
        return __awaiter(this, void 0, void 0, function () {
            var configPieContent;
            return __generator(this, function (_a) {
                console.warn('If you are using complex-rubric, stop using this function to prevent having duplicated rubrics.');
                if (!rubricModel) {
                    rubricModel = {
                        id: "rubric",
                        element: "pie-rubric",
                        points: ["", "", "", ""],
                        maxPoints: 4,
                        excludeZero: false
                    };
                }
                configPieContent = pieContentFromConfig(config);
                addPackageToContent(configPieContent, "@pie-element/rubric", rubricModel);
                return [2 /*return*/, addRubric(configPieContent)];
            });
        });
    };
    /**
     * Utility method to add a `@pie-element/multi-trait-rubric` section to an item config when creating an item should be used before setting the config.
     **
     * @param config the item config to mutate
     * @param multiTraitRubricModel
     */
    class_1.prototype.addMultiTraitRubricToConfig = function (config, multiTraitRubricModel) {
        return __awaiter(this, void 0, void 0, function () {
            var configPieContent;
            return __generator(this, function (_a) {
                console.warn('If you are using complex-rubric, stop using this function to prevent having duplicated rubrics.');
                if (!multiTraitRubricModel) {
                    multiTraitRubricModel = {
                        id: "multi-trait-rubric",
                        element: "pie-multi-trait-rubric",
                        visibleToStudent: true,
                        halfScoring: false,
                        excludeZero: true,
                        pointLabels: true,
                        description: false,
                        standards: false,
                        scales: [
                            {
                                maxPoints: 4,
                                scorePointsLabels: ['', '', '', ''],
                                traitLabel: 'Trait',
                                traits: [
                                    {
                                        name: '',
                                        standards: [],
                                        description: '',
                                        scorePointsDescriptors: [
                                            '',
                                            '',
                                            '',
                                            '',
                                            '',
                                        ],
                                    },
                                ]
                            }
                        ]
                    };
                }
                configPieContent = pieContentFromConfig(config);
                addPackageToContent(configPieContent, "@pie-element/multi-trait-rubric", multiTraitRubricModel);
                return [2 /*return*/, addMultiTraitRubric(configPieContent)];
            });
        });
    };
    class_1.prototype.render = function () {
        var _this = this;
        if (this.pieContentModel && this.pieContentModel.markup) {
            var markup = this.getRenderMarkup();
            if (this.addPreview) {
                return (h("pie-preview-layout", { config: this.config }, h("div", { slot: "configure" }, h("pie-spinner", { active: !this.elementsLoaded }, h("div", { class: 'author-container', innerHTML: markup }))), h("input", { type: "file", hidden: true, ref: function (r) { return (_this.fileInput = r); }, style: { display: 'none' } })));
            }
            else {
                return (h("pie-spinner", { active: !this.elementsLoaded }, h("div", { class: 'author-container', innerHTML: markup }), h("input", { type: "file", hidden: true, ref: function (r) { return (_this.fileInput = r); }, style: { display: 'none' } })));
            }
        }
        else {
            return h("pie-spinner", null);
        }
    };
    Object.defineProperty(class_1.prototype, "el", {
        get: function () { return getElement(this); },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(class_1, "watchers", {
        get: function () {
            return {
                "config": ["watchConfig"],
                "elementsLoaded": ["watchElementsLoaded"],
                "configSettings": ["watchConfigSettings"]
            };
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(class_1, "style", {
        get: function () { return ".pie-loading{position:absolute;height:100%;width:100%;background-color:#fff;bottom:0;left:0;right:0;top:0;z-index:9999;opacity:.4}.pie-loading.fixed{position:fixed}.pie-loading:before{-webkit-box-shadow:0 0 35px rgba(63,81,181,.9);box-shadow:0 0 35px rgba(63,81,181,.9);width:50px;height:50px;-moz-animation:spinPulse 1s infinite ease-in-out;-webkit-animation:spinPulse 1s linear infinite;margin:-25px 0 0 -25px}.pie-loading:after,.pie-loading:before{content:\"\";background-color:transparent;border:5px solid rgba(63,81,181,.9);opacity:.9;border-right:5px solid transparent;border-left:5px solid transparent;border-radius:50px;position:absolute;top:50%;left:50%}.pie-loading:after{-webkit-box-shadow:0 0 15px rgba(63,81,181,.9);box-shadow:0 0 15px rgba(63,81,181,.9);width:30px;height:30px;-moz-animation:spinoffPulse 1s infinite linear;-webkit-animation:spinoffPulse 1s linear infinite;margin:-15px 0 0 -15px}\@-webkit-keyframes spinPulse{0%{-webkit-transform:rotate(160deg);transform:rotate(160deg);opacity:0;-webkit-box-shadow:0 0 1px rgba(63,81,181,.9);box-shadow:0 0 1px rgba(63,81,181,.9)}50%{-webkit-transform:rotate(145deg);transform:rotate(145deg);opacity:1}to{-webkit-transform:rotate(-320deg);transform:rotate(-320deg);opacity:0}}\@keyframes spinPulse{0%{-webkit-transform:rotate(160deg);transform:rotate(160deg);opacity:0;-webkit-box-shadow:0 0 1px rgba(63,81,181,.9);box-shadow:0 0 1px rgba(63,81,181,.9)}50%{-webkit-transform:rotate(145deg);transform:rotate(145deg);opacity:1}to{-webkit-transform:rotate(-320deg);transform:rotate(-320deg);opacity:0}}\@-webkit-keyframes spinoffPulse{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}\@keyframes spinoffPulse{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(1turn);transform:rotate(1turn)}}.pie-api-player img{max-width:inherit;max-height:inherit}.book-title-k5{text-decoration:underline}.book-title{font-style:italic}.block-quote,.text-block{font-family:serif;margin-left:20%;margin-right:20%;margin-top:5px;margin-bottom:5px;width:60%;border:1px solid #000;padding:2px;display:block}.short-quote{font-weight:700}span.short-quote:before{content:open-quote}span.short-quote:after{content:close-quote}.word-callout{text-decoration:underline}.relative-emphasis{text-transform:uppercase}.content-emphasis{font-weight:700;color:red}span.passage-title:before{content:open-quote}span.passage-title:after{content:close-quote}.proper-name,.variable{font-style:italic}.equation-block{text-align:center;margin-left:20%;margin-right:20%;margin-top:5px;margin-bottom:5px;width:60%;padding:2px;display:block}.embedded-error{font-style:italic}div.passage-subtitle,div.passage-title{font-weight:700;text-align:center}div.passage-author{text-align:center}.p-number{float:left;font-size:.85em}.numbered-paragraph{margin-left:36px}\@media print{.kds-noprint,.noprint{display:none}}.abs,.kds-absolute{border-left:1px solid #000;border-right:1px solid #000;padding:0 .3em 0 .3em}.kds-border-1{border:1px solid #000}.kds-border-2{border:2px solid #000}.center,.kds-center{margin:0;text-align:center}.kds-exponent{font-size:85%}.kds-exponent,sup.frac{margin-left:-.4em;position:relative;top:-1.4em}sup.frac{font-size:70%}.kds-fillin{display:inline-block}.fillin,.kds-fillin{border:1px solid #000;margin:0 .2em;padding-left:1em}.fillin{display:inline-block;*display:inline}.kds-font-larger{font-size:larger}.kds-font-smaller{font-size:smaller}table.kds-fraction{border:0;display:inline-block;font-size:85%;margin:0;padding:0;vertical-align:middle}table.kds-fraction>tbody>tr>td.kds-numerator{border-bottom:1px solid #000;border-left:0;border-right:0;border-top:0;text-align:center}table.kds-fraction>tbody>tr>td.kds-denominator{border:0;text-align:center}table.frac{display:inline-block;*display:inline;vertical-align:middle;font-size:85%;border:0;margin:0;padding:0}.frac .nu{border-left:0;border-top:0;border-right:0;border-bottom:1px solid #000;text-align:center}.frac .de{border:0;text-align:center}.kds-hanging-indent{margin:0;padding-left:3em;text-indent:-3em}.kds-image-caption{font-family:Verdana,Arial,sans-serif;text-align:center}.kds-image-left{float:left;margin-right:5px}.kds-image-right{float:right;margin-left:5px}.indent,.kds-indent{text-indent:3em}.kds-nowrap{display:inline-block;white-space:nowrap}.kds-overline{text-decoration:overline}.kds-parentheses{font-family:Arial Narrow,Arial,sans-serif}.kds-parentheses,b.frac{font-size:300%;font-weight:400;position:relative;top:8px}b.frac{font-family:arial narrow}.kds-pi{font-family:Times New Roman,serif;font-size:1.2em}.newradical{border-collapse:collapse;display:inline-block;*display:inline;vertical-align:middle}.newradical td{border:0;padding:0;vertical-align:top}.newradical td.vinculum{border-top:1px solid #000;padding:0;vertical-align:top}.newradical div.exp{font-size:.7em;position:relative;left:7px;bottom:5px}.kds-underline,.under{text-decoration:underline}.kds-verdana2t,.Verdana2t{border:1px solid #fff;text-align:left;text-decoration:none;vertical-align:top}.kds-whole-number{display:inline-block}.kds-whole-number,.whole{font-size:120%;margin:0 0 0 .2em}.whole{display:inline-block;*display:inline}table.KdsTable01{border:1px solid #000;border-collapse:collapse;border-spacing:0}table.KdsTable01>tbody>tr>th{font-weight:400}table.KdsTable01>tbody>tr>th,table.KdsTable01>tbody>tr>th.bold{background-color:#d3d3d3;border:1px solid #000;padding:2px;text-align:center}table.KdsTable01>tbody>tr>th.bold{font-weight:700}table.KdsTable01>tbody>tr>td,table.KdsTable01>tbody>tr>td.bold{border:1px solid #000;padding:2px;text-align:center}table.KdsTable01>tbody>tr>td.bold{font-weight:700}table.KdsTable02{border:1px solid #000;border-collapse:collapse;border-spacing:0}table.KdsTable02>tbody>tr>th{background-color:#d3d3d3;font-weight:400}table.KdsTable02>tbody>tr>td,table.KdsTable02>tbody>tr>th{border:1px solid #000;padding:2px}.table{width:100%;margin-bottom:1em;background-color:transparent;border-collapse:collapse}.table td,.table th{padding:.75em;vertical-align:top;border-top:1px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}th{text-align:inherit}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.text-center{text-align:center!important}.h5,h5{font-size:1.25em}h1,h2,h3,h4,h5,h6{margin-top:0}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5em;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.lrn_feature h3{margin-top:0!important}#item,#stimulus{width:50%;float:left}.lrn_width_auto.table{width:auto}.TEX-S3{font-family:MJXZERO,MJXTEX-S3!important}.TEX-S2{font-family:MJXZERO,MJXTEX-S2!important}.TEX-S1{font-family:MJXZERO,MJXTEX-S1!important}.TEX-I{font-family:MJXZERO,MJXTEX-I!important}mjx-c.mjx-c2032{font-family:CerebriSans,serif!important}mjx-c.mjx-c22,mjx-c.mjx-c27{font-family:MJXZERO,serif!important}table{border-collapse:collapse}"; },
        enumerable: true,
        configurable: true
    });
    return class_1;
}());
export { Author as pie_author };
