survey-core
Version:
survey.js is a JavaScript Survey Library. It is a modern way to add a survey to your website. It uses JSON for survey metadata and results.
1 lines • 10.3 MB
Source Map (JSON)
{"version":3,"file":"survey-core.mjs","sources":["../../src/global_variables_utils.ts","../../src/helpers.ts","../../src/localization/english.ts","../../src/surveyStrings.ts","../../src/jsonobject.ts","../../src/conditionProcessValue.ts","../../src/console-warnings.ts","../../src/functionsfactory.ts","../../src/expressions/expressions.ts","../../src/expressions/expressionParser.ts","../../src/conditionsParser.ts","../../src/conditions.ts","../../src/base.ts","../../node_modules/tslib/tslib.es6.js","../../src/utils/taskmanager.ts","../../src/utils/responsivity-manager.ts","../../src/utils/cssClassBuilder.ts","../../src/actions/container.ts","../../src/element-helper.ts","../../src/utils/devices.ts","../../src/list.ts","../../src/popup.ts","../../src/actions/action.ts","../../src/actions/adaptive-container.ts","../../src/utils/animation.ts","../../src/survey-element.ts","../../src/localizablestring.ts","../../src/utils/utils.ts","../../src/settings.ts","../../src/survey-error.ts","../../src/error.ts","../../src/validator.ts","../../src/questionCustomWidgets.ts","../../src/rendererFactory.ts","../../src/utils/text-area.ts","../../src/question.ts","../../src/itemvalue.ts","../../src/calculatedValue.ts","../../src/expressionItems.ts","../../src/choicesRestful.ts","../../src/martixBase.ts","../../src/textPreProcessor.ts","../../src/question_custom.ts","../../src/questionfactory.ts","../../src/question_expression.ts","../../src/question_matrixdropdowncolumn.ts","../../src/question_matrixdropdownrendered.ts","../../src/question_matrixdropdownbase.ts","../../src/question_matrixdropdown.ts","../../src/dragdrop/dom-adapter.ts","../../src/dragdrop/core.ts","../../src/dragdrop/matrix-rows.ts","../../src/utils/dragOrClickHelper.ts","../../src/question_matrixdynamic.ts","../../src/defaultCss/defaultCss.ts","../../src/surveytimer.ts","../../src/surveyTimerModel.ts","../../src/notifier.ts","../../src/header.ts","../../src/surveyTaskManager.ts","../../src/panel-layout-column.ts","../../src/panel.ts","../../src/page.ts","../../src/progress-buttons.ts","../../src/surveyToc.ts","../../src/survey.ts","../../src/question_baseselect.ts","../../src/dropdownListModel.ts","../../src/question_dropdown.ts","../../src/question_matrix.ts","../../src/question_textbase.ts","../../src/mask/input_element_adapter.ts","../../src/mask/mask_utils.ts","../../src/question_text.ts","../../src/question_multipletext.ts","../../src/flowpanel.ts","../../src/defaultTitle.ts","../../src/questionnonvalue.ts","../../src/question_empty.ts","../../src/question_checkbox.ts","../../src/multiSelectListModel.ts","../../src/dropdownMultiSelectListModel.ts","../../src/question_tagbox.ts","../../src/dragdrop/choices.ts","../../src/dragdrop/ranking-choices.ts","../../src/dragdrop/ranking-select-to-rank.ts","../../src/question_ranking.ts","../../src/question_comment.ts","../../src/utils/camera.ts","../../src/question_file.ts","../../src/question_html.ts","../../src/question_radiogroup.ts","../../src/question_rating.ts","../../src/question_boolean.ts","../../src/question_imagepicker.ts","../../src/question_image.ts","../../node_modules/signature_pad/dist/signature_pad.js","../../src/question_signaturepad.ts","../../src/question_paneldynamic.ts","../../src/surveyProgress.ts","../../src/trigger.ts","../../src/popup-survey.ts","../../src/scroll.ts","../../src/popup-view-model.ts","../../src/utils/popup.ts","../../src/popup-dropdown-view-model.ts","../../src/popup-modal-view-model.ts","../../src/popup-utils.ts","../../src/question_buttongroup.ts","../../src/mask/mask_base.ts","../../src/mask/mask_pattern.ts","../../src/mask/mask_numeric.ts","../../src/mask/mask_datetime.ts","../../src/mask/mask_currency.ts","../../entries/chunks/model.ts","../../src/svgbundle.ts"],"sourcesContent":["/* eslint-disable no-restricted-globals */\nexport class DomWindowHelper {\n public static isAvailable(): boolean {\n return \"undefined\" !== typeof window;\n }\n public static isFileReaderAvailable(): boolean {\n if (!DomWindowHelper.isAvailable()) return false;\n return !!(<any>window)[\"FileReader\"];\n }\n public static getLocation(): Location {\n if (!DomWindowHelper.isAvailable()) return;\n return window.location;\n }\n public static getVisualViewport(): VisualViewport | null {\n if(!DomWindowHelper.isAvailable()) return null;\n return window.visualViewport;\n }\n public static getInnerWidth(): number {\n if(!DomWindowHelper.isAvailable()) return;\n return window.innerWidth;\n }\n public static getInnerHeight(): number {\n if(!DomWindowHelper.isAvailable()) return null;\n return window.innerHeight;\n }\n public static getDevicePixelRatio(): number {\n if(!DomWindowHelper.isAvailable()) return null;\n return window.devicePixelRatio;\n }\n public static getWindow(): Window {\n if(!DomWindowHelper.isAvailable()) return;\n return window;\n }\n public static hasOwn(propertyName: string): boolean {\n if(!DomWindowHelper.isAvailable()) return;\n return propertyName in window;\n }\n public static getSelection(): Selection | null {\n if (DomWindowHelper.isAvailable() && window.getSelection) {\n return window.getSelection();\n }\n }\n public static requestAnimationFrame(callback: FrameRequestCallback): number {\n if (DomWindowHelper.isAvailable()) {\n return window.requestAnimationFrame(callback);\n }\n }\n public static addEventListener(type: string, listener: (e?: any) => void): void {\n if(!DomWindowHelper.isAvailable()) return;\n window.addEventListener(type, listener);\n }\n public static removeEventListener(type: string, listener: (e?: any) => void): void {\n if(!DomWindowHelper.isAvailable()) return;\n window.removeEventListener(type, listener);\n }\n\n public static matchMedia(mediaQueryString: string): {matches:boolean} | null {\n if(!DomWindowHelper.isAvailable() || typeof window.matchMedia === \"undefined\") return null;\n return window.matchMedia(mediaQueryString);\n }\n}\n\nexport class DomDocumentHelper {\n public static isAvailable(): boolean {\n return \"undefined\" !== typeof document;\n }\n public static getBody(): HTMLElement {\n if(!DomDocumentHelper.isAvailable()) return;\n return document.body;\n }\n public static getDocumentElement(): HTMLElement {\n if(!DomDocumentHelper.isAvailable()) return;\n return document.documentElement;\n }\n public static getDocument(): Document {\n if(!DomDocumentHelper.isAvailable()) return;\n return document;\n }\n public static getCookie(): string {\n if(!DomDocumentHelper.isAvailable()) return;\n return document.cookie;\n }\n public static setCookie(newCookie: string): void {\n if(!DomDocumentHelper.isAvailable()) return;\n document.cookie = newCookie;\n }\n public static activeElementBlur(): Document {\n if(!DomDocumentHelper.isAvailable()) return;\n\n const activeElement = document.activeElement;\n if(!!activeElement && !!(<any>activeElement).blur) {\n (<any>activeElement).blur();\n }\n }\n public static createElement(tagName: string): HTMLElement {\n if(!DomDocumentHelper.isAvailable()) return;\n return document.createElement(tagName);\n }\n public static getComputedStyle(elt: Element): CSSStyleDeclaration {\n if(!DomDocumentHelper.isAvailable()) return new CSSStyleDeclaration();\n return document.defaultView.getComputedStyle(elt);\n }\n public static addEventListener(type: string, listener: (e?: any) => void): void {\n if(!DomDocumentHelper.isAvailable()) return;\n document.addEventListener(type, listener);\n }\n public static removeEventListener(type: string, listener: (e?: any) => void): void {\n if(!DomDocumentHelper.isAvailable()) return;\n document.removeEventListener(type, listener);\n }\n}","import { settings } from \"./settings\";\n\nexport interface HashTable<T = any> {\n [key: string]: T;\n}\nexport interface IEqualValuesParameters {\n ignoreOrder?: boolean;\n caseSensitive?: boolean;\n trimStrings?: boolean;\n doNotConvertNumbers?: boolean;\n}\nexport function createDate(reason: string, val?: number | string | Date): Date {\n if(!val) return new Date();\n if(!settings.storeUtcDates && typeof val === \"string\" && isISODateOnly(val)) {\n val += \"T00:00:00\";\n }\n const d = new Date(val);\n return settings.onDateCreated(d, reason, val);\n}\n\nfunction isISODateOnly(str: string): boolean {\n if(str.indexOf(\"T\") > 0) return false;\n if (!/\\d{4}-\\d{2}-\\d{2}/.test(str)) return false;\n return !isNaN(new Date(str).getTime());\n}\n\nexport class Helpers {\n /**\n * A static methods that returns true if a value undefined, null, empty string or empty array.\n * @param value\n */\n public static isValueEmpty(value: any): boolean {\n if (Array.isArray(value) && value.length === 0) return true;\n if (!!value && Helpers.isValueObject(value) && value.constructor === Object) {\n for (var key in value) {\n if (!Helpers.isValueEmpty(value[key])) return false;\n }\n return true;\n }\n return !value && value !== 0 && value !== false;\n }\n public static isValueUndefined(value: any): boolean {\n return (value === undefined || value === null) || (typeof value === \"number\" && isNaN(value));\n }\n public static isArrayContainsEqual(x: any, y: any): boolean {\n if (!Array.isArray(x) || !Array.isArray(y)) return false;\n if (x.length !== y.length) return false;\n for (var i = 0; i < x.length; i++) {\n var j = 0;\n for (; j < y.length; j++) {\n if (Helpers.isTwoValueEquals(x[i], y[j])) break;\n }\n if (j === y.length) return false;\n }\n return true;\n }\n public static checkIfArraysEqual(x: any, y: any, params: IEqualValuesParameters): boolean {\n if (!Array.isArray(x) || !Array.isArray(y)) return false;\n if (x.length !== y.length) return false;\n const ignoreOrder: boolean = params.ignoreOrder !== undefined ? params.ignoreOrder : false;\n if (ignoreOrder) {\n var xSorted = [];\n var ySorted = [];\n for (var i = 0; i < x.length; i++) {\n xSorted.push(x[i]);\n ySorted.push(y[i]);\n }\n xSorted.sort();\n ySorted.sort();\n x = xSorted;\n y = ySorted;\n }\n for (var i = 0; i < x.length; i++) {\n if (!Helpers.checkIfValuesEqual(x[i], y[i], params)) return false;\n }\n return true;\n }\n public static isArraysEqual(\n x: any,\n y: any,\n ignoreOrder: boolean = false,\n caseSensitive?: boolean,\n trimStrings? : boolean\n ): boolean {\n return Helpers.checkIfArraysEqual(x, y, { ignoreOrder: ignoreOrder, caseSensitive: caseSensitive, trimStrings: trimStrings });\n }\n public static compareStrings(x: string, y: string): number {\n const normalize = settings.comparator.normalizeTextCallback;\n if(!!x) x = normalize(x, \"compare\").trim();\n if(!!y) y = normalize(y, \"compare\").trim();\n if(!x && !y) return 0;\n if(!x) return -1;\n if(!y) return 1;\n if(x === y) return 0;\n let digitIndex = -1;\n for(let i = 0; i < x.length && i < y.length; i ++) {\n if(this.isCharDigit(x[i]) && this.isCharDigit(y[i])) {\n digitIndex = i;\n break;\n }\n if(x[i] !== y[i]) break;\n }\n if(digitIndex > -1) {\n let nX = this.getNumberFromStr(x, digitIndex);\n let nY = this.getNumberFromStr(y, digitIndex);\n if(!Number.isNaN(nX) && !Number.isNaN(nY) && nX !== nY) {\n return nX > nY ? 1 : -1;\n }\n }\n return x > y ? 1 : -1;\n }\n public static checkIfValuesEqual(x: any, y: any, params: IEqualValuesParameters): boolean {\n if (x === y) return true;\n\n if (Array.isArray(x) && x.length === 0 && typeof y === \"undefined\")\n return true;\n if (Array.isArray(y) && y.length === 0 && typeof x === \"undefined\")\n return true;\n if ((x === undefined || x === null) && y === \"\") return true;\n if ((y === undefined || y === null) && x === \"\") return true;\n const caseSensitive = params.caseSensitive !== undefined ? params.caseSensitive : settings.comparator.caseSensitive;\n const trimStrings = params.trimStrings !== undefined ? params.trimStrings : settings.comparator.trimStrings;\n\n if(typeof x === \"string\" && typeof y === \"string\") {\n const normalize = settings.comparator.normalizeTextCallback;\n x = normalize(x, \"compare\");\n y = normalize(y, \"compare\");\n if(trimStrings) {\n x = x.trim();\n y = y.trim();\n }\n if(!caseSensitive) {\n x = x.toLowerCase();\n y = y.toLowerCase();\n }\n return x === y;\n }\n if(x instanceof Date && y instanceof Date) return x.getTime() == y.getTime();\n const convertNumbers = !params.doNotConvertNumbers;\n if (convertNumbers && Helpers.isConvertibleToNumber(x) && Helpers.isConvertibleToNumber(y)) {\n if (parseInt(x) === parseInt(y) && parseFloat(x) === parseFloat(y)) {\n return true;\n }\n }\n\n if (\n (!Helpers.isValueEmpty(x) && Helpers.isValueEmpty(y)) ||\n (Helpers.isValueEmpty(x) && !Helpers.isValueEmpty(y))\n )\n return false;\n if ((x === true || x === false) && typeof y == \"string\") {\n return x.toString() === y.toLocaleLowerCase();\n }\n if ((y === true || y === false) && typeof x == \"string\") {\n return y.toString() === x.toLocaleLowerCase();\n }\n const isXObj = Helpers.isValueObject(x);\n const isYObj = Helpers.isValueObject(y);\n if (!isXObj && !isYObj && (convertNumbers || (typeof x !== \"number\" && typeof y !== \"number\"))) return x == y;\n if (!isXObj || !isYObj) return false;\n if (x[\"equals\"] && y[\"equals\"]) return x.equals(y);\n if (Array.isArray(x) && Array.isArray(y)) {\n return Helpers.checkIfArraysEqual(x, y, params);\n }\n\n for (var p in x) {\n if (!x.hasOwnProperty(p)) continue;\n if (!y.hasOwnProperty(p)) return false;\n if (!this.checkIfValuesEqual(x[p], y[p], params)) return false;\n }\n for (p in y) {\n if (y.hasOwnProperty(p) && !x.hasOwnProperty(p)) return false;\n }\n return true;\n }\n public static isTwoValueEquals(\n x: any,\n y: any,\n ignoreOrder: boolean = false,\n caseSensitive?: boolean,\n trimStrings? : boolean\n ): boolean {\n return this.checkIfValuesEqual(x, y, { ignoreOrder: ignoreOrder, caseSensitive: caseSensitive, trimStrings: trimStrings });\n }\n public static randomizeArray<T>(array: Array<T>): Array<T> {\n for (var i = array.length - 1; i > 0; i--) {\n var j = Math.floor(Math.random() * (i + 1));\n var temp = array[i];\n array[i] = array[j];\n array[j] = temp;\n }\n return array;\n }\n public static getUnbindValue(value: any): any {\n if(Array.isArray(value)) {\n const res = [];\n for(let i = 0; i < value.length; i ++) {\n res.push(Helpers.getUnbindValue(value[i]));\n }\n return res;\n }\n if (!!value && Helpers.isValueObject(value) && !(value instanceof Date)) {\n return JSON.parse(JSON.stringify(value));\n }\n return value;\n }\n public static createCopy(obj: any): any {\n var res: any = {};\n if (!obj) return res;\n for (var key in obj) {\n res[key] = obj[key];\n }\n return res;\n }\n public static isConvertibleToNumber(value: any): boolean {\n return (\n value !== undefined &&\n value !== null &&\n !Array.isArray(value) &&\n !isNaN(value)\n );\n }\n public static isValueObject(val: any, excludeArray?: boolean): boolean {\n return val instanceof Object && (!excludeArray || !Array.isArray(val));\n }\n public static isNumber(value: any): boolean {\n return !isNaN(this.getNumber(value));\n }\n public static getNumber(value: any): number {\n const newValue = Helpers.getNumberCore(value);\n return settings.parseNumber(value, newValue);\n }\n private static getNumberCore(value: any): number {\n if (typeof value == \"string\") {\n value = value.trim();\n if(!value) return NaN;\n if(value.indexOf(\"0x\") == 0) {\n if(value.length > 32) return NaN;\n return parseInt(value);\n }\n if(value.length > 15 && Helpers.isDigitsOnly(value)) return NaN;\n if(Helpers.isStringHasOperator(value)) return NaN;\n }\n value = this.prepareStringToNumber(value);\n const res = parseFloat(value);\n if(isNaN(res) || !isFinite(value)) return NaN;\n return res;\n }\n private static isStringHasOperator(str: string): boolean {\n if(str.lastIndexOf(\"-\") > 0) return false;\n if(str.lastIndexOf(\"+\") > 0) return false;\n const operators = \"*^/%\";\n for(let i = 0; i < operators.length; i ++) {\n if(str.indexOf(operators[i]) > -1) return true;\n }\n return false;\n }\n private static prepareStringToNumber(val: any): any {\n if(typeof val !== \"string\" || !val) return val;\n let i = val.indexOf(\",\");\n if(i > -1 && val.indexOf(\",\", i + 1) < 0) {\n return val.replace(\",\", \".\");\n }\n return val;\n }\n public static getMaxLength(maxLength: number, surveyLength: number): any {\n if (maxLength < 0) {\n maxLength = surveyLength;\n }\n return maxLength > 0 ? maxLength : null;\n }\n public static getRemainingCharacterCounterText(newValue: string | undefined, maxLength: number | null): string {\n if(!maxLength || maxLength <= 0 || !settings.showMaxLengthIndicator) {\n return \"\";\n }\n const value = newValue ? newValue.length : \"0\";\n return [value, maxLength].join(\"/\");\n }\n public static getNumberByIndex(index: number, startIndexStr: string, parentIndex?: number): string {\n if (index < 0) return \"\";\n var startIndex = 1;\n var prefix = \"\";\n var postfix = \".\";\n var isNumeric = true;\n var strIndex = \"A\";\n var str = \"\";\n const hasDigitFunc = (str: string): boolean => {\n if(!str) return false;\n for (var i = 0; i < str.length; i++) {\n if (Helpers.isCharDigit(str[i])) return true;\n }\n return false;\n };\n if (!!startIndexStr) {\n str = startIndexStr;\n var ind = str.length - 1;\n var hasDigit = hasDigitFunc(str);\n var checkLetter = function() {\n return (\n (hasDigit && !Helpers.isCharDigit(str[ind])) ||\n Helpers.isCharNotLetterAndDigit(str[ind])\n );\n };\n while (ind >= 0 && checkLetter()) ind--;\n var newPostfix = \"\";\n if (ind < str.length - 1) {\n newPostfix = str.substring(ind + 1);\n str = str.substring(0, ind + 1);\n }\n ind = str.length - 1;\n while (ind >= 0) {\n if (checkLetter()) break;\n ind--;\n if (!hasDigit) break;\n }\n strIndex = str.substring(ind + 1);\n prefix = str.substring(0, ind + 1);\n if (parseInt(strIndex)) startIndex = parseInt(strIndex);\n else if (strIndex.length == 1) isNumeric = false;\n if (!!newPostfix || !!prefix) {\n postfix = newPostfix;\n }\n }\n if(parentIndex > -1 && hasDigitFunc(prefix)) {\n prefix = this.getNumberByIndex(parentIndex, prefix);\n }\n if (isNumeric) {\n let val = (index + startIndex).toString();\n while(val.length < strIndex.length) val = \"0\" + val;\n return prefix + val + postfix;\n }\n return (\n prefix + String.fromCharCode(strIndex.charCodeAt(0) + index) + postfix\n );\n }\n public static isCharNotLetterAndDigit(ch: string): boolean {\n return ch.toUpperCase() == ch.toLowerCase() && !Helpers.isCharDigit(ch);\n }\n public static isCharDigit(ch: string): boolean {\n return ch >= \"0\" && ch <= \"9\";\n }\n public static isDigitsOnly(str: string): boolean {\n if(!str) return false;\n for(let i = 0; i < str.length; i ++) {\n if(!Helpers.isCharDigit(str[i])) return false;\n }\n return true;\n }\n private static getNumberFromStr(str: string, index: number): number {\n if(!this.isCharDigit(str[index])) return NaN;\n let nStr = \"\";\n while(index < str.length && this.isCharDigit(str[index])) {\n nStr += str[index];\n index ++;\n }\n if(!nStr) return NaN;\n return this.getNumber(nStr);\n }\n private static countDecimals(value: number): number {\n if (Helpers.isNumber(value) && Math.floor(value) !== value) {\n const strs = value.toString().split(\".\");\n return strs.length > 1 && strs[1].length || 0;\n }\n return 0;\n }\n public static correctAfterPlusMinis(a: number, b: number, res: number): number {\n const digitsA = Helpers.countDecimals(a);\n const digitsB = Helpers.countDecimals(b);\n if(digitsA > 0 || digitsB > 0) {\n const digits = Math.max(digitsA, digitsB);\n res = parseFloat(res.toFixed(digits));\n }\n return res;\n }\n public static sumAnyValues(a: any, b: any): any {\n if (!Helpers.isNumber(a) || !Helpers.isNumber(b)) {\n if(Array.isArray(a) && Array.isArray(b))\n return [].concat(a).concat(b);\n if(Array.isArray(a) || Array.isArray(b)) {\n const arr = Array.isArray(a) ? a : b;\n const val = arr === a ? b : a;\n if(typeof val === \"string\") {\n const str = arr.join(\", \");\n return arr === a ? str + val : val + str;\n }\n if(typeof val === \"number\") {\n let res = 0;\n for(var i = 0; i < arr.length; i ++) {\n if(typeof arr[i] === \"number\") {\n res = Helpers.correctAfterPlusMinis(res, arr[i], res + arr[i]);\n }\n }\n return Helpers.correctAfterPlusMinis(res, val, res + val);\n }\n }\n return a + b;\n }\n if(typeof a === \"string\" || typeof b === \"string\") return a + b;\n return Helpers.correctAfterPlusMinis(a, b, a + b);\n }\n public static correctAfterMultiple(a: number, b: number, res: number): number {\n const digits = Helpers.countDecimals(a) + Helpers.countDecimals(b);\n if(digits > 0) {\n res = parseFloat(res.toFixed(digits));\n }\n return res;\n }\n public static convertArrayValueToObject(src: Array<any>, propName: string, dest: Array<any> = undefined): Array<any> {\n const res = new Array<any>();\n if(!src || !Array.isArray(src)) return res;\n for(var i = 0; i < src.length; i ++) {\n let item: any;\n if(Array.isArray(dest)) {\n item = Helpers.findObjByPropValue(dest, propName, src[i]);\n }\n if(!item) {\n item = {};\n item[propName] = src[i];\n }\n res.push(item);\n }\n return res;\n }\n private static findObjByPropValue(arr: Array<any>, propName: string, val: any): any {\n for(var i = 0; i < arr.length; i ++) {\n if(Helpers.isTwoValueEquals(arr[i][propName], val)) return arr[i];\n }\n return undefined;\n }\n public static convertArrayObjectToValue(src: Array<any>, propName: string): Array<any> {\n const res = new Array<any>();\n if(!src || !Array.isArray(src)) return res;\n for(var i = 0; i < src.length; i ++) {\n const itemVal = !!src[i] ? src[i][propName] : undefined;\n if(!Helpers.isValueEmpty(itemVal)) res.push(itemVal);\n }\n return res;\n }\n public static convertDateToString(date: Date): string {\n const toStr = (val: number): string => {\n if(val < 10) return \"0\" + val.toString();\n return val.toString();\n };\n return date.getFullYear() + \"-\" + toStr(date.getMonth() + 1) + \"-\" + toStr(date.getDate());\n }\n public static convertDateTimeToString(date: Date): string {\n const toStr = (val: number): string => {\n if(val < 10) return \"0\" + val.toString();\n return val.toString();\n };\n return this.convertDateToString(date) + \" \" + toStr(date.getHours()) + \":\" + toStr(date.getMinutes());\n }\n public static convertValToQuestionVal(val: any, inputType?: string): any {\n if (val instanceof Date) {\n if(inputType === \"datetime-local\") return Helpers.convertDateTimeToString(val);\n return Helpers.convertDateToString(val);\n }\n return this.getUnbindValue(val);\n }\n public static compareVerions(ver1: string, ver2: string): number {\n if(!ver1 && !ver2) return 0;\n const ver1Ar = ver1.split(\".\");\n const ver2Ar = ver2.split(\".\");\n const len1 = ver1Ar.length;\n const len2 = ver2Ar.length;\n for(let i = 0; i < len1 && i < len2; i ++) {\n const str1 = ver1Ar[i];\n const str2 = ver2Ar[i];\n if(str1.length === str2.length) {\n if(str1 !== str2) {\n return str1 < str2 ? -1 : 1;\n }\n } else {\n return str1.length < str2.length ? -1 : 1;\n }\n }\n return len1 === len2 ? 0 : (len1 < len2 ? -1 : 1);\n }\n public static isUrlYoutubeVideo(url: string): boolean {\n if (!url) return false;\n const youtubeDomains = [\"www.youtube.com\", \"m.youtube.com\", \"youtube.com\", \"youtu.be\"];\n url = url.toLowerCase();\n url = url.replace(/^https?:\\/\\//, \"\");\n for (let i = 0; i < youtubeDomains.length; i++) {\n if (url.indexOf(youtubeDomains[i] + \"/\") === 0) return true;\n }\n return false;\n }\n}\nif (!(<any>String.prototype)[\"format\"]) {\n (<any>String.prototype)[\"format\"] = function() {\n var args = arguments;\n return this.replace(/{(\\d+)}/g, function(match: any, number: any) {\n return typeof args[number] != \"undefined\" ? args[number] : match;\n });\n };\n}\n","// Uncomment the line below if you create a custom dictionary\n// import { setupLocale } from \"survey-core\";\n\nexport var englishStrings = {\n pagePrevText: \"Previous\",\n pageNextText: \"Next\",\n completeText: \"Complete\",\n previewText: \"Preview\",\n editText: \"Edit\",\n startSurveyText: \"Start\",\n otherItemText: \"Other (describe)\",\n noneItemText: \"None\",\n refuseItemText: \"Refuse to answer\",\n dontKnowItemText: \"Don't know\",\n selectAllItemText: \"Select All\",\n deselectAllItemText: \"Deselect all\",\n progressText: \"Page {0} of {1}\",\n indexText: \"{0} of {1}\",\n panelDynamicProgressText: \"{0} of {1}\",\n panelDynamicTabTextFormat: \"Panel {panelIndex}\",\n questionsProgressText: \"Answered {0}/{1} questions\",\n emptySurvey: \"The survey doesn't contain any visible elements.\",\n completingSurvey: \"Thank you for completing the survey\",\n completingSurveyBefore: \"You have already completed this survey.\",\n loadingSurvey: \"Loading Survey...\",\n placeholder: \"Select...\",\n ratingOptionsCaption: \"Select...\",\n value: \"value\",\n requiredError: \"Response required.\",\n requiredErrorInPanel: \"Response required: answer at least one question.\",\n requiredInAllRowsError: \"Response required: answer questions in all rows.\",\n eachRowUniqueError: \"Each row must have a unique value.\",\n numericError: \"The value should be numeric.\",\n minError: \"The value should not be less than {0}\",\n maxError: \"The value should not be greater than {0}\",\n textNoDigitsAllow: \"Numbers are not allowed.\",\n textMinLength: \"Please enter at least {0} character(s).\",\n textMaxLength: \"Please enter no more than {0} character(s).\",\n textMinMaxLength: \"Please enter at least {0} and no more than {1} characters.\",\n minRowCountError: \"Please fill in at least {0} row(s).\",\n minSelectError: \"Please select at least {0} option(s).\",\n maxSelectError: \"Please select no more than {0} option(s).\",\n numericMinMax: \"The '{0}' should be at least {1} and at most {2}\",\n numericMin: \"The '{0}' should be at least {1}\",\n numericMax: \"The '{0}' should be at most {1}\",\n invalidEmail: \"Please enter a valid e-mail address.\",\n invalidExpression: \"The expression: {0} should return 'true'.\",\n urlRequestError: \"The request returned error '{0}'. {1}\",\n urlGetChoicesError: \"The request returned empty data or the 'path' property is incorrect\",\n exceedMaxSize: \"The file size should not exceed {0}.\",\n noUploadFilesHandler: \"Files cannot be uploaded. Please add a handler for the 'onUploadFiles' event.\",\n otherRequiredError: \"Response required: enter another value.\",\n uploadingFile: \"Your file is uploading. Please wait several seconds and try again.\",\n loadingFile: \"Loading...\",\n chooseFile: \"Choose file(s)...\",\n noFileChosen: \"No file selected\",\n filePlaceholder: \"Drag and drop a file here or click the button below to select a file to upload.\",\n confirmDelete: \"Are you sure you want to delete this record?\",\n keyDuplicationError: \"This value should be unique.\",\n addColumn: \"Add Column\",\n addRow: \"Add Row\",\n removeRow: \"Remove\",\n noRowsText: \"There are no rows.\",\n addPanel: \"Add new\",\n removePanel: \"Remove\",\n showDetails: \"Show Details\",\n hideDetails: \"Hide Details\",\n choices_Item: \"item\",\n choices_Choice: \"Choice option\",\n matrix_column: \"Column\",\n matrix_row: \"Row\",\n multipletext_itemname: \"text\",\n savingData: \"The results are being saved on the server...\",\n savingDataError: \"An error occurred and we could not save the results.\",\n savingDataSuccess: \"The results were saved successfully!\",\n savingExceedSize: \"Your response exceeds 64KB. Please reduce the size of your file(s) and try again or contact the survey owner.\",\n saveAgainButton: \"Try again\",\n timerMin: \"min\",\n timerSec: \"sec\",\n timerSpentAll: \"You have spent {0} on this page and {1} in total.\",\n timerSpentPage: \"You have spent {0} on this page.\",\n timerSpentSurvey: \"You have spent {0} in total.\",\n timerLimitAll: \"You have spent {0} of {1} on this page and {2} of {3} in total.\",\n timerLimitPage: \"You have spent {0} of {1} on this page.\",\n timerLimitSurvey: \"You have spent {0} of {1} in total.\",\n clearCaption: \"Clear\",\n signaturePlaceHolder: \"Sign here\",\n signaturePlaceHolderReadOnly: \"No signature\",\n chooseFileCaption: \"Select File\",\n takePhotoCaption: \"Take Photo\",\n photoPlaceholder: \"Click the button below to take a photo using the camera.\",\n fileOrPhotoPlaceholder: \"Drag and drop or select a file to upload or take a photo using the camera.\",\n replaceFileCaption: \"Replace file\",\n removeFileCaption: \"Remove this file\",\n booleanCheckedLabel: \"Yes\",\n booleanUncheckedLabel: \"No\",\n confirmRemoveFile: \"Are you sure that you want to remove this file: {0}?\",\n confirmRemoveAllFiles: \"Are you sure that you want to remove all files?\",\n questionTitlePatternText: \"Question Title\",\n modalCancelButtonText: \"Cancel\",\n modalApplyButtonText: \"Apply\",\n filterStringPlaceholder: \"Type to search...\",\n emptyMessage: \"No data to display\",\n loadingPage: \"Loading...\",\n loadingData: \"Loading...\",\n noEntriesText: \"No entries yet.\\nClick the button below to add a new entry.\",\n noEntriesReadonlyText: \"No entries\",\n tabTitlePlaceholder: \"New Panel\",\n more: \"More\",\n tagboxDoneButtonCaption: \"OK\",\n selectToRankEmptyRankedAreaText: \"All choices are selected for ranking\",\n selectToRankEmptyUnrankedAreaText: \"Drag choices here to rank them\",\n ok: \"OK\",\n cancel: \"Cancel\",\n createCustomItem: \"Create \\\"{0}\\\" item...\",\n};\n\n// Uncomment the lines below if you create a custom dictionary.\n// Replace \"en\" with a custom locale code (for example, \"fr\" or \"de\"),\n// Replace `englishStrings` with the name of the variable that contains the custom dictionary.\n//setupLocale({ localeCode: \"en\", strings: englishStrings, nativeName: \"English\", englishName: \"English\" });\n","import { englishStrings } from \"./localization/english\";\n\nexport var surveyLocalization = {\n currentLocaleValue: \"\",\n defaultLocaleValue: \"en\",\n locales: <{ [index: string]: any }>{},\n localeNames: <{ [index: string]: any }>{},\n localeNamesInEnglish: <{ [index: string]: any }>{},\n localeDirections: <{ [index: string]: any }>{},\n supportedLocales: <Array<any>>[],\n useEnglishNames: false,\n //TODO remove on next week\n get showNamesInEnglish(): boolean { return this.useEnglishNames; },\n set showNamesInEnglish(val: boolean) { this.useEnglishNames = val; },\n setupLocale(localeConfig: { localeCode: string, strings: any, nativeName: string, englishName: string, rtl?: boolean }): void {\n const loc = localeConfig.localeCode;\n this.locales[loc] = localeConfig.strings;\n this.localeNames[loc] = localeConfig.nativeName;\n this.localeNamesInEnglish[loc] = localeConfig.englishName;\n if (localeConfig.rtl !== undefined) {\n this.localeDirections[loc] = localeConfig.rtl ? \"rtl\" : \"ltr\";\n }\n },\n get currentLocale(): string {\n return this.currentLocaleValue === this.defaultLocaleValue ? \"\" : this.currentLocaleValue;\n },\n set currentLocale(val: string) {\n if (val === \"cz\") val = \"cs\";\n this.currentLocaleValue = val;\n },\n get defaultLocale() {\n return this.defaultLocaleValue;\n },\n set defaultLocale(val: string) {\n if (val === \"cz\") val = \"cs\";\n this.defaultLocaleValue = val;\n },\n getLocaleStrings(loc: string): any {\n return this.locales[loc];\n },\n getString: function (strName: string, locale: string = null) {\n const locs = new Array<any>();\n const addLocaleCore = (locName: string): void => {\n const strs = this.locales[locName];\n if (!!strs) locs.push(strs);\n };\n const addLocale = (locName: string): void => {\n if (!locName) return;\n addLocaleCore(locName);\n const index = locName.indexOf(\"-\");\n if (index < 1) return;\n locName = locName.substring(0, index);\n addLocaleCore(locName);\n };\n addLocale(locale);\n addLocale(this.currentLocale);\n addLocale(this.defaultLocale);\n if (this.defaultLocale !== \"en\") {\n addLocaleCore(\"en\");\n }\n for (let i = 0; i < locs.length; i++) {\n const res = locs[i][strName];\n if (res !== undefined) return res;\n }\n return this.onGetExternalString(strName, locale);\n },\n getLocaleName(loc: string, inEnglish?: boolean): string {\n if (!loc) return \"\";\n if (inEnglish === undefined) inEnglish = this.showNamesInEnglish;\n const firstNames = inEnglish ? this.localeNamesInEnglish : this.localeNames;\n const secondNames = inEnglish ? this.localeNames : this.localeNamesInEnglish;\n return firstNames[loc] || secondNames[loc] || loc;\n },\n getLocales: function (removeDefaultLoc: boolean = false): Array<string> {\n var res = [];\n res.push(\"\");\n var locs = this.locales;\n if (this.supportedLocales && this.supportedLocales.length > 0) {\n locs = {};\n for (var i = 0; i < this.supportedLocales.length; i++) {\n locs[this.supportedLocales[i]] = true;\n }\n }\n for (var key in locs) {\n if (removeDefaultLoc && key == this.defaultLocale) continue;\n res.push(key);\n }\n var locName = (loc: string): string => {\n return this.getLocaleName(loc).toLowerCase();\n };\n res.sort((a, b): number => {\n var str1 = locName(a);\n var str2 = locName(b);\n if (str1 === str2) return 0;\n return str1 < str2 ? -1 : 1;\n });\n return res;\n },\n onGetExternalString: function (name: string, locale: string): string { return undefined; }\n};\n\nexport function getLocaleString(strName: string, locale: string = null): string {\n return surveyLocalization.getString(strName, locale);\n}\nexport function getLocaleStrings(locale: string): any {\n return surveyLocalization.getLocaleStrings(locale);\n}\nexport function setupLocale(localeConfig: { localeCode: string, strings: any, nativeName: string, englishName: string, rtl?: boolean }): void {\n surveyLocalization.setupLocale(localeConfig);\n}\nexport var surveyStrings = englishStrings;\n(<any>surveyLocalization).locales[\"en\"] = englishStrings;\n(<any>surveyLocalization).localeNames[\"en\"] = \"english\";\n","import { getLocaleString } from \"./surveyStrings\";\nimport { Base, ComputedUpdater } from \"./base\";\nimport { Helpers, HashTable } from \"./helpers\";\nimport { ILoadFromJSONOptions, ISaveToJSONOptions } from \"./base-interfaces\";\n\nexport interface IPropertyDecoratorOptions<T = any> {\n defaultValue?: T;\n defaultSource?: string;\n getDefaultValue?: (objectInstance?: any) => T;\n localizable?:\n | { name?: string, onGetTextCallback?: (str: string) => string, defaultStr?: string }\n | boolean;\n onSet?: (val: T, objectInstance: any, prevVal?: T) => void;\n}\n\nfunction ensureLocString(\n target: any,\n options: IPropertyDecoratorOptions,\n key: string\n) {\n let locString = target.getLocalizableString(key);\n if (!locString) {\n let defaultStr: string;\n if (typeof options.localizable === \"object\" && options.localizable.defaultStr) {\n defaultStr = options.localizable.defaultStr;\n }\n locString = target.createLocalizableString(key, target, true, defaultStr);\n if (\n typeof options.localizable === \"object\" &&\n typeof options.localizable.onGetTextCallback === \"function\"\n ) {\n locString.onGetTextCallback = options.localizable.onGetTextCallback;\n }\n }\n}\nfunction getLocStringValue(\n target: any,\n options: IPropertyDecoratorOptions,\n key: string\n) {\n ensureLocString(target, options, key);\n let res = target.getLocalizableStringText(key);\n if (!!res) return res;\n if (typeof options.localizable === \"object\" && options.localizable.defaultStr) {\n const loc = !!target.getLocale ? target.getLocale() : \"\";\n return getLocaleString(options.localizable.defaultStr, loc);\n }\n return \"\";\n}\n\nexport function property(options: IPropertyDecoratorOptions = {}) {\n // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\n return function (target: any, key: string): void {\n let processComputedUpdater = (obj: any, val: any) => {\n if (!!val && typeof val === \"object\" && val.type === ComputedUpdater.ComputedUpdaterType) {\n Base.startCollectDependencies(() => obj[key] = val.updater(), obj, key);\n const result = val.updater();\n const dependencies = Base.finishCollectDependencies();\n val.setDependencies(dependencies);\n if (obj.dependencies[key]) {\n obj.dependencies[key].dispose();\n }\n obj.dependencies[key] = val;\n return result;\n }\n return val;\n };\n if (!options || !options.localizable) {\n Object.defineProperty(target, key, {\n get: function () {\n // const serializationProperty = Serializer.getProperty(target.getType(), key);\n // if(!!serializationProperty && options.defaultValue !== undefined) {\n // ConsoleWarnings.error(\"remove defaultValue from @property for class \" + target.getType() + \" property name is \" + key);\n // }\n let defaultVal = null;\n if (!!options) {\n if (typeof options.getDefaultValue === \"function\") {\n defaultVal = options.getDefaultValue(this);\n }\n if (options.defaultValue !== undefined) {\n defaultVal = options.defaultValue;\n }\n }\n return this.getPropertyValue(key, defaultVal);\n },\n set: function (val: any) {\n const newValue = processComputedUpdater(this, val);\n const prevValue = this.getPropertyValue(key);\n if(newValue !== prevValue) {\n this.setPropertyValue(key, newValue);\n if (!!options && options.onSet) {\n options.onSet(newValue, this, prevValue);\n }\n }\n },\n });\n } else {\n Object.defineProperty(target, key, {\n get: function () {\n return getLocStringValue(this, options, key);\n },\n set: function (val: any) {\n ensureLocString(this, options, key);\n const newValue = processComputedUpdater(this, val);\n this.setLocalizableStringText(key, newValue);\n if (!!options && options.onSet) {\n options.onSet(newValue, this);\n }\n },\n });\n Object.defineProperty(\n target,\n typeof options.localizable === \"object\" && !!options.localizable.name ?\n options.localizable.name : \"loc\" + key.charAt(0).toUpperCase() + key.slice(1),\n {\n get: function () {\n ensureLocString(this, options, key);\n return this.getLocalizableString(key);\n },\n }\n );\n }\n };\n}\n\nexport interface IArrayPropertyDecoratorOptions {\n onPush?: any;\n onRemove?: any;\n onSet?: (val: any, target: any) => void;\n}\n\nfunction ensureArray(\n target: any,\n options: IArrayPropertyDecoratorOptions,\n key: string\n) {\n target.ensureArray(\n key,\n (item: any, index: number) => {\n const handler = !!options ? options.onPush : null;\n handler && handler(item, index, target);\n },\n (item: any, index: number) => {\n const handler = !!options ? options.onRemove : null;\n handler && handler(item, index, target);\n },\n );\n}\n\nexport function propertyArray(options?: IArrayPropertyDecoratorOptions) {\n return function (target: any, key: string) {\n Object.defineProperty(target, key, {\n get: function () {\n ensureArray(this, options, key);\n return this.getPropertyValue(key);\n },\n set: function (val: any) {\n ensureArray(this, options, key);\n const arr = this.getPropertyValue(key);\n if (val === arr) {\n return;\n }\n if (arr) {\n arr.splice(0, arr.length, ...(val || []));\n } else {\n this.setPropertyValue(key, val);\n }\n if (!!options && options.onSet) {\n options.onSet(val, this);\n }\n },\n });\n };\n}\n\nexport interface IObject {\n [key: string]: any;\n}\n\nexport interface IJsonPropertyInfo {\n name: string;\n type?: string;\n className?: string;\n classNamePart?: string;\n baseClassName?: string;\n isRequired?: boolean;\n isUnique?: boolean;\n //uniquePropertyName\n uniqueProperty?: string;\n choices?: any;\n visible?: boolean;\n alternativeName?: string;\n oldName?: string;\n version?: string;\n dataList?: Array<string>;\n isLocalizable?: boolean;\n isSerializable?: boolean;\n isSerializableFunc?: (obj: any) => boolean;\n isLightSerializable?: boolean;\n readOnly?: boolean;\n availableInMatrixColumn?: boolean;\n serializationProperty?: string;\n dependsOn?: Array<string> | string;\n\n isBindable?: boolean;\n isArray?: boolean;\n layout?: string;\n default?: any;\n defaultFunc?: (obj: Base) => any;\n baseValue?: any;\n onSerializeValue?: (obj: any) => any;\n onGetValue?: (obj: any) => any;\n onSettingValue?: (obj: any, value: any) => any;\n onSetValue?: (obj: any, value: any, jsonConv: JsonObject) => any;\n visibleIf?: (obj: any) => boolean;\n enableIf?: (obj: any) => boolean;\n onExecuteExpression?: (obj: any, res: any) => any;\n onPropertyEditorUpdate?: (obj: any, propEditor: any) => any;\n\n displayName?: string;\n category?: string;\n categoryIndex?: number;\n visibleIndex?: number;\n nextToProperty?: string;\n overridingProperty?: string;\n showMode?: string;\n locationInTable?: string;\n maxLength?: number;\n maxValue?: any;\n minValue?: any;\n}\n/**\n * Contains information about a property of a survey element (page, panel, questions, and etc).\n * @see addProperty\n * @see removeProperty\n * @see [Add Properties](https://surveyjs.io/Documentation/Survey-Creator#addproperties)\n * @see [Remove Properties](https://surveyjs.io/Documentation/Survey-Creator#removeproperties)\n */\nexport class JsonObjectProperty implements IObject, IJsonPropertyInfo {\n public static getItemValuesDefaultValue: (val: any, type: string) => any;\n [key: string]: any;\n private static Index = 1;\n private static mergableValues = [\n \"typeValue\",\n \"choicesValue\",\n \"baseValue\",\n \"readOnlyValue\",\n \"visibleValue\",\n \"isSerializable\",\n \"isLightSerializable\",\n \"isCustom\",\n \"isBindable\",\n \"isUnique\",\n \"uniquePropertyName\",\n \"isDynamicChoices\",\n \"isLocalizableValue\",\n \"className\",\n \"alternativeName\",\n \"oldName\",\n \"layout\",\n \"version\",\n \"classNamePart\",\n \"baseClassName\",\n \"defaultValue\",\n \"defaultValueFunc\",\n \"serializationProperty\",\n \"onGetValue\",\n \"onSetValue\",\n \"onSettingValue\",\n \"displayName\",\n \"category\",\n \"categoryIndex\",\n \"visibleIndex\",\n \"nextToProperty\",\n \"overridingProperty\",\n \"locationInTable\",\n \"dependedProperties\",\n \"visibleIf\",\n \"enableIf\",\n \"onExecuteExpression\",\n \"onPropertyEditorUpdate\",\n \"maxLength\",\n \"maxValue\",\n \"minValue\",\n \"dataListValue\",\n ];\n private idValue: number;\n private classInfoValue: JsonMetadataClass;\n private typeValue: string;\n private choicesValue: Array<any>;\n public baseValue: any;\n private isRequiredValue: boolean = false;\n private isUniqueValue: boolean = false;\n private uniquePropertyValue: string\n private readOnlyValue: boolean | null;\n private visibleValue: boolean | null;\n private isLocalizableValue: boolean | null;\n private choicesfunc: (obj: any, choicesCallback: any) => Array<any>;\n private dependedProperties: Array<string>;\n public isSerializable: boolean = true;\n public isSerializableFunc: (obj: any) => boolean;\n public isLightSerializable: boolean = true;\n public isCustom: boolean = false;\n public isDynamicChoices: boolean = false; //TODO obsolete, use dependsOn attribute\n public isBindable: boolean = false;\n public className: string;\n public alternativeName: string;\n public oldName: string;\n public classNamePart: string;\n public baseClassName: string;\n public defaultValueValue: any;\n public defaultValueFunc: (obj: Base) => any;\n public serializationProperty: string;\n public displayName: string;\n public category: string = \"\";\n public categoryIndex: number = -1;\n public visibleIndex: number = -1;\n public nextToProperty: string;\n public overridingProperty: string;\n public availableInMatrixColumn: boolean;\n public maxLength: number = -1;\n public maxValue: any;\n public minValue: any;\n private dataListValue: Array<string>;\n private locationInTableValue: string;\n public layout: string;\n public version: string;\n public onSerializeValue: (obj: any) => any;\n public onGetValue: (obj: any) => any;\n public onSettingValue: (obj: any, value: any) => any;\n public onSetValue: (obj: any, value: any, jsonConv: JsonObject) => any;\n public visibleIf: (obj: any) => boolean;\n public enableIf: (obj: any) => boolean;\n public onExecuteExpression: (obj: any, res: any) => any;\n public onPropertyEditorUpdate: (obj: any, propEditor: any) => any;\n\n constructor(\n classInfo: JsonMetadataClass,\n public name: string,\n isRequired: boolean = false\n ) {\n this.classInfoValue = classInfo;\n this.isRequiredValue = isRequired;\n this.idValue = JsonObjectProperty.Index++;\n }\n uniqueProperty?: string;\n dependsOn?: string | Array<string>;\n default?: any;\n defaultFunc?: (obj: Base) => any;\n public get id(): number {\n return this.idValue;\n }\n public get classInfo(): JsonMetadataClass {\n return this.classInfoValue;\n }\n public get type(): string {\n return this.typeValue ? this.typeValue : \"string\";\n }\n public set type(value: string) {\n if (value === \"itemvalues\") value = \"itemvalue[]\";\n if (value === \"textitems\") value = \"textitem[]\";\n this.typeValue = value;\n if (this.typeValue.indexOf(\"[]\") === this.typeValue.length - 2) {\n this.isArray = true;\n this.className = this.typeValue.substring(0, this.typeValue.length - 2);\n }\n }\n public get locationInTable(): string {\n const res = this.locationInTableValue;\n return res || \"column\";\n }\n public set locationInTable(val: string) {\n this.locationInTableValue = val;\n }\n public get showMode(): string {\n const res = this.locationInTableValue;\n return res === \"detail\" ? \"form\" : (res === \"column\" ? \"list\" : \"\");\n }\n public set showMode(val: string) {\n this.locationInTable = val === \"form\" ? \"detail\" : (val === \"list\" ? \"column\" : undefined);\n }\n public isArray = false;\n public get isRequired(): boolean {\n return this.isRequiredValue;\n }\n public set isRequired(val: boolean) {\n if (val !== this.isRequired) {\n this.isRequiredValue = val;\n if (!!this.classInfo) {\n this.classInfo.resetAllProperties();\n }\n }\n }\n public get isUnique(): boolean {\n return this.isUniqueValue;\n }\n public set isUnique(val: boolean) {\n this.isUniqueValue = val;\n }\n public get uniquePropertyName(): string {\n return this.uniquePropertyValue;\n }\n public set uniquePropertyName(val: string) {\n this.uniquePropertyValue = val;\n }\n public isPropertySerializable(obj: any): boolean {\n if(this.isSerializableFunc) return this.isSerializableFunc(obj);\n return this.isSerializable;\n }\n public getDefaultValue(obj: Base): any {\n let result: any = !!this.defaultValueFunc ? this.defaultValueFunc(obj) : this.defaultValueValue;\n if (\n !!JsonObjectProperty.getItemValuesDefaultValue &&\n Serializer.isDescendantOf(this.className, \"itemvalue\")\n ) {\n result = JsonObjectProperty.getItemValuesDefaultValue(this.defaultValueValue || [], this.className);\n }\n return result;\n }\n public get defaultValue(): any {\n return this.g