{"version":3,"file":"member_js.js","mappings":"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","sources":["webpack://AJN/webpack/bootstrap","webpack://AJN/webpack/runtime/define property getters","webpack://AJN/webpack/runtime/hasOwnProperty shorthand","webpack://AJN/webpack/runtime/make namespace object","webpack://AJN/external var \"jQuery\"","webpack://AJN/./src/js/member/countdowntimer.ts","webpack://AJN/./src/js/member/lesson.ts","webpack://AJN/./src/js/member/coursesummary.ts","webpack://AJN/./src/js/member/quiz.ts","webpack://AJN/./src/js/member/exam.ts","webpack://AJN/./src/js/member/membersq.ts","webpack://AJN/./src/js/member/formhelper.ts"],"sourcesContent":["// The require scope\nvar __webpack_require__ = {};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","const __WEBPACK_NAMESPACE_OBJECT__ = jQuery;","const tickRate = 500; // ticket every 500 ms\r\n\r\nexport interface TickEvent {\r\n secondsLeft: number;\r\n}\r\n\r\n// see https://codereview.stackexchange.com/questions/215161/a-countdown-clock-in-typescript\r\ninterface CountdownEvents {\r\n tick(values: TickEvent): void;\r\n expired(): void;\r\n}\r\n\r\ntype EventMap = { [K in keyof T]: Function[] };\r\n\r\ninterface IOnTick { (evt: TickEvent): void }\r\ninterface IOnComplete { (evt: TickEvent): void }\r\n\r\n// Wrote my own timer because I was tired of non-typescript compatible timers.\r\nexport class CountdownTimer {\r\n private listeners: EventMap = {\r\n tick: [],\r\n expired: []\r\n };\r\n private timer: number; // pointer to internal\r\n private seconds: number // # of seconds\r\n private startTimeMS: number;\r\n private endTimeMS: number;\r\n isRunning: boolean;\r\n\r\n constructor() {\r\n this.isRunning = false;\r\n }\r\n\r\n startTimer(seconds: number) {\r\n const self = this;\r\n this.seconds = seconds; // keep this around... no reason\r\n if (this.isRunning) {\r\n this.endTimer();\r\n }\r\n\r\n const d = new Date();\r\n this.startTimeMS = d.getTime();\r\n this.endTimeMS = this.startTimeMS + (seconds * 1000);\r\n\r\n this.timer = window.setInterval(() => self.tick(), tickRate);\r\n }\r\n\r\n // Force the timer to end\r\n endTimer() {\r\n if (this.timer) {\r\n window.clearInterval(this.timer);\r\n }\r\n this.isRunning = false;\r\n }\r\n\r\n tick() {\r\n var secondsLeft = this.getSecondsLeft();\r\n this.listeners.tick.forEach(listener => listener({ secondsLeft: secondsLeft }));\r\n if (secondsLeft <= 0) {\r\n this.endTimer();\r\n this.listeners.expired.forEach(listener => listener());\r\n }\r\n }\r\n\r\n // Watch an event\r\n on(eventName: K, listener: CountdownEvents[K]): void {\r\n this.listeners[eventName].push(listener);\r\n }\r\n\r\n // Watch an event\r\n off(eventName: K, listener: CountdownEvents[K]): void {\r\n const listeners = this.listeners[eventName];\r\n const index = listeners.indexOf(listener);\r\n if (index !== -1) {\r\n listeners.splice(index, 1);\r\n }\r\n }\r\n\r\n getFormattedTimeLeft(): string {\r\n return CountdownTimer.getFormattedTime(this.getSecondsLeft());\r\n }\r\n\r\n // get # of ms left\r\n getMSLeft(): number {\r\n const d = new Date();\r\n const timeLeft = this.endTimeMS - d.getTime();\r\n return timeLeft > 0 ? timeLeft : 0;\r\n }\r\n\r\n // get # of seconds left\r\n getSecondsLeft() {\r\n return Math.round(this.getMSLeft() / 1000);\r\n }\r\n\r\n getMSElapsed(): number{\r\n const d = new Date();\r\n const timeElapsed = d.getTime() - this.startTimeMS;\r\n const maxMS = this.seconds * 1000;\r\n return timeElapsed > maxMS ? maxMS : timeElapsed;\r\n }\r\n\r\n getSecondsElapsed(): number {\r\n return Math.round(this.getMSElapsed() / 1000);\r\n }\r\n\r\n static padtime(num: number): string {\r\n return num < 10 ? \"0\" + num : num.toString();\r\n }\r\n\r\n // Returns a nicely formatted time\r\n static getFormattedTime(sec_num: number): string {\r\n const hours = Math.floor(sec_num / 3600);\r\n const minutes = Math.floor((sec_num - (hours * 3600)) / 60);\r\n const seconds = sec_num - (hours * 3600) - (minutes * 60);\r\n\r\n const sSeconds = CountdownTimer.padtime(seconds);\r\n\r\n if (hours === 0) {\r\n // just min:sec\r\n return minutes + \":\" + sSeconds;\r\n }\r\n\r\n const sMinutes = CountdownTimer.padtime(minutes);\r\n\r\n return hours + ':' + sMinutes + ':' + sSeconds;\r\n }\r\n}","import * as $ from 'jquery';\r\nimport { CountdownTimer, TickEvent } from \"./countdowntimer\";\r\n\r\nexport class Lesson {\r\n isTimerDone: boolean;\r\n totalLessonSeconds: number;\r\n offsetLessonSeconds: number; // if we're mid-lesson... just continue\r\n timer: CountdownTimer;\r\n pislid: number; // PurchaseItemSchoolLessonID\r\n piid: number;\r\n elapsedTimeSaved: boolean;\r\n $counttimer: JQuery;\r\n $pageseconds: JQuery;\r\n audioplayer: HTMLAudioElement;\r\n\r\n constructor(pislid: number, piid: number) {\r\n this.isTimerDone = true;\r\n this.pislid = pislid;\r\n this.piid = piid;\r\n this.$counttimer = $('#counttimer');\r\n this.$pageseconds = $('#PageSecondsElapsed');\r\n const self = this;\r\n\r\n this.audioplayer = document.getElementById(\"readalongplayer\") as HTMLAudioElement;\r\n\r\n window.addEventListener(\"contextmenu\", e => e.preventDefault());\r\n\r\n if (this.audioplayer) {\r\n const oldvolume = window.localStorage.getItem(\"audiovolume\");\r\n if (oldvolume) {\r\n this.audioplayer.volume = parseFloat(oldvolume);\r\n }\r\n this.audioplayer.addEventListener(\"volumechange\", () => self.audiovolumechange());\r\n }\r\n }\r\n\r\n // Monitor a change in audio volume and keep it for future use\r\n audiovolumechange() {\r\n window.localStorage.setItem(\"audiovolume\", this.audioplayer.volume.toString());\r\n }\r\n\r\n startTimer(lessonseconds: number, offsetLessonSeconds: number) {\r\n const self = this;\r\n this.isTimerDone = true;\r\n this.elapsedTimeSaved = false;\r\n this.totalLessonSeconds = lessonseconds;\r\n if (offsetLessonSeconds) {\r\n this.offsetLessonSeconds = offsetLessonSeconds;\r\n }\r\n else {\r\n this.offsetLessonSeconds = 0;\r\n }\r\n // start the timer!\r\n if (this.totalLessonSeconds > 0) {\r\n this.timer = new CountdownTimer();\r\n this.timer.on(\"tick\", tevent => self.tick(tevent));\r\n this.timer.on(\"expired\", () => self.timerDone());\r\n this.isTimerDone = false;\r\n this.timer.startTimer(this.totalLessonSeconds - this.offsetLessonSeconds);\r\n }\r\n else {\r\n self.timerDone();\r\n }\r\n $('#finishlesson').on(\"click\", function () {\r\n if (self.isTimerDone) {\r\n return true;\r\n }\r\n else {\r\n if (confirm(\"You still need to spend some time on this page. Are you sure you want to stop?\")) {\r\n // stuff the elapsed time in a variable so that we can record this information\r\n self.saveElapsedTime();\r\n window.location.href = \"/Member/Summary/\" + self.piid;\r\n return false;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n });\r\n // get all the links and add the timer warning\r\n $('a').on(\"click\", function () {\r\n // special case links we don't ask anything\r\n if ($(this).hasClass(\"readalonglink\")) {\r\n self.saveElapsedTime();\r\n return true;\r\n }\r\n if (self.isTimerDone) {\r\n if (confirm(\"If you exit this page without clicking the FINISH PAGE, you will have to repeat the lesson from the beginning. Are you sure you want to exit this page?\")) {\r\n self.saveElapsedTime();\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n else {\r\n if (confirm(\"If you exit this page without letting the timer elapse, you will have to repeat the lesson from the beginning. Are you sure you want to exit this page?\")) {\r\n self.saveElapsedTime();\r\n // stuff the elapsed time in a variable so that we can record this information\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n }\r\n });\r\n }\r\n\r\n saveElapsedTime() {\r\n if (this.isTimerDone || this.elapsedTimeSaved) {\r\n return;\r\n }\r\n\r\n this.elapsedTimeSaved = true; // so we don't hit this again\r\n\r\n let data = new FormData();\r\n\r\n data.append('purchaseItemID', this.piid.toString());\r\n data.append('seconds', (this.timer.getSecondsElapsed() + this.offsetLessonSeconds).toString());\r\n data.append('purchaseItemSchoolLessonID', this.pislid.toString());\r\n\r\n if (navigator.sendBeacon) {\r\n navigator.sendBeacon(\"/Lesson/UpdateLessonTime\", data)\r\n }\r\n }\r\n\r\n timerDone() {\r\n this.$counttimer.hide();\r\n $('#countdone').show();\r\n this.$pageseconds.val(-1);// full time elapse\r\n this.isTimerDone = true;\r\n }\r\n\r\n private tick(evt: TickEvent) {\r\n const formattedSeconds = CountdownTimer.getFormattedTime(evt.secondsLeft);\r\n this.$counttimer.text(formattedSeconds);\r\n this.$pageseconds.val(this.timer.getSecondsElapsed());\r\n }\r\n\r\n // Calculate greatest common demoninator for aspect ratio\r\n static gcd_rec(a: number, b: number): number {\r\n if (b) {\r\n return Lesson.gcd_rec(b, a % b);\r\n } else {\r\n return Math.abs(a);\r\n }\r\n }\r\n\r\n static getaspectratio(width: number, height: number): string {\r\n const gcd = Lesson.gcd_rec(width, height);\r\n return `${(width / gcd)} : ${(height / gcd)}`;\r\n }\r\n\r\n showMedia(medialist) {\r\n return;\r\n // we used to add some javascript for each type of media item. Now no longer necessary\r\n }\r\n}\r\n","import * as $ from 'jquery';\r\n\r\nexport class CourseSummary {\r\n constructor() {\r\n $(\".coursesummary .title .expand\").on(\"click\", function () {\r\n const $this = $(this);\r\n const $chapter = $this.closest(\".chapter\");\r\n const $lessons = $(\".lessons\", $chapter);\r\n if ($lessons.is(':visible')) {\r\n $this.text('Show Lesson');\r\n $lessons.slideUp();\r\n }\r\n else {\r\n $this.text('Hide Lesson');\r\n $lessons.slideDown();\r\n }\r\n });\r\n }\r\n}","import * as $ from 'jquery';\r\n\r\nexport class Quiz {\r\n constructor() {\r\n $('A').on(\"click\", function () {\r\n if (confirm(\"To continue the course, you must score you quiz by clicking SCORE QUIZ. Are you sure you want to exit this page?\")) {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n });\r\n // hide validation class\r\n $('.answers input').on(\"click\", function () {\r\n $(this).closest('.input-validation-error').removeClass('input-validation-error');\r\n });\r\n }\r\n}","import * as $ from 'jquery';\r\n\r\nexport class Exam {\r\n constructor() {\r\n $('A').on(\"click\", function () {\r\n if (confirm(\"To complete this course, you must take the final exam and click SCORE EXAM when you are done. Are you sure you want to exit this page?\")) {\r\n return true;\r\n }\r\n else {\r\n return false;\r\n }\r\n });\r\n // hide validation class\r\n $('.answers input').on(\"click\", function () {\r\n $(this).closest('.input-validation-error').removeClass('input-validation-error');\r\n });\r\n }\r\n}\r\n\r\n\r\n","import * as $ from 'jquery';\r\nimport { CountdownTimer, TickEvent } from \"./countdowntimer\";\r\n\r\nexport class MemberSQTimer {\r\n isTimerDone: boolean;\r\n totalSeconds: number;\r\n securityQuestionID: number;\r\n $timerDisplay: JQuery;\r\n timer: CountdownTimer;\r\n\r\n constructor() {\r\n this.isTimerDone = true;\r\n this.totalSeconds = 0;\r\n this.securityQuestionID = 0;\r\n this.$timerDisplay = $('#counttimer');\r\n }\r\n\r\n startTimer(seconds: number, sqID: number) {\r\n this.isTimerDone = true;\r\n this.totalSeconds = seconds;\r\n this.securityQuestionID = sqID;\r\n const self = this;\r\n //alert(this.securityQuestionID)\r\n // start the timer!\r\n if (this.totalSeconds > 0) {\r\n this.timer = new CountdownTimer();\r\n this.timer.on(\"tick\", (tevent) => self.tick(tevent));\r\n this.timer.on(\"expired\", () => self.timerDone());\r\n this.isTimerDone = false;\r\n this.timer.startTimer(self.totalSeconds);\r\n }\r\n }\r\n\r\n timerDone() {\r\n //alert(self.securityQuestionID)\r\n var postFailUrl = \"/SecurityQuestion/FailTimeout/\" + this.securityQuestionID;\r\n $.post(postFailUrl, function (data) {\r\n window.location.href = \"/SecurityQuestion/Fail\";\r\n });\r\n }\r\n\r\n private tick(evt: TickEvent) {\r\n const formattedSeconds = CountdownTimer.getFormattedTime(evt.secondsLeft);\r\n this.$timerDisplay.text(formattedSeconds);\r\n }\r\n}","\r\nexport interface IFormHelper {\r\n // you can pass in a selector or the actual elements\r\n form: string | HTMLFormElement;\r\n submitButton?: string | HTMLInputElement | HTMLButtonElement;\r\n}\r\n\r\n// valid elements\r\ntype FieldElement = HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement;\r\n\r\ninterface IValidationElement {\r\n field: FieldElement;\r\n messageField?: Element;\r\n requiredMessage?: string;\r\n phoneMessage?: string;\r\n emailMessage?: string;\r\n creditcardMessage?: string; // this currently doesn't do anything!\r\n regexMessage?: string;\r\n maxlengthMessage?: string;\r\n minlengthMessage?: string;\r\n}\r\n\r\ntype doFixup = (validElement: IValidationElement, attrval: string) => void;\r\n\r\nconst fixups: { [attrkey: string]: doFixup } = {\r\n \"data-val-required\": (validElement, attrval) => {\r\n validElement.requiredMessage = attrval;\r\n validElement.field.setAttribute('required', '');\r\n },\r\n \"data-val-email\": (validElement, attrval) => {\r\n validElement.emailMessage = attrval;\r\n },\r\n \"data-val-phone\": (validElement, attrval) => {\r\n validElement.phoneMessage = attrval;\r\n },\r\n \"data-val-creditcard\": (validElement, attrval) => {\r\n validElement.creditcardMessage = attrval;\r\n },\r\n \"data-val-maxlength\": (validElement, attrval) => {\r\n validElement.maxlengthMessage = attrval;\r\n },\r\n \"data-val-maxlength-max\": (validElement, attrval) => {\r\n validElement.field.setAttribute('maxlength', attrval);\r\n },\r\n \"data-val-minlength\": (validElement, attrval) => {\r\n validElement.minlengthMessage = attrval;\r\n },\r\n \"data-val-minlength-min\": (validElement, attrval) => {\r\n validElement.field.setAttribute('minlength', attrval);\r\n },\r\n \"data-val-regex\": (validElement, attrval) => {\r\n validElement.regexMessage = attrval;\r\n },\r\n \"data-val-regex-pattern\": (validElement, attrval) => {\r\n validElement.field.setAttribute('pattern', attrval);\r\n }\r\n}\r\n\r\nconst DEFAULTINVALIDMESSAGE = \"Field is not valid\";\r\n\r\n// Includes various functions to make forms more user friendly\r\n// 100% javascript... no jquery\r\n// related topics: \r\n// https://www.falldowngoboone.com/blog/native-form-validation-with-javascript/\r\n// https://developer.mozilla.org/en-US/docs/Web/API/Constraint_validation\r\nexport class FormHelper {\r\n submitMessage: string;\r\n form: HTMLFormElement;\r\n submitButton: HTMLInputElement | HTMLButtonElement;\r\n isSubmitted: boolean;\r\n checkDoubleSubmit: boolean;\r\n checkValid: boolean;\r\n validationElements: Map;\r\n\r\n constructor(setup: IFormHelper) {\r\n const self = this;\r\n if (typeof setup.form === 'string') {\r\n this.form = document.querySelector(setup.form);\r\n }\r\n else {\r\n this.form = setup.form;\r\n }\r\n if (setup.submitButton) {\r\n if (typeof setup.submitButton === 'string') {\r\n this.submitButton = this.form.querySelector(setup.submitButton);\r\n }\r\n else {\r\n this.submitButton = setup.submitButton;\r\n }\r\n }\r\n else {\r\n this.submitButton = this.form.querySelector('input[type=\"submit\"],button')\r\n }\r\n\r\n this.submitMessage = \"(processing)\";\r\n this.checkDoubleSubmit = false;\r\n this.isSubmitted = false;\r\n this.checkValid = false;\r\n this.validationElements = new Map;\r\n\r\n this.form.addEventListener('submit', (e) => {\r\n self.submit(e);\r\n });\r\n }\r\n\r\n // Prevent double-submission\r\n public preventDoubleSubmit() {\r\n this.checkDoubleSubmit = true;\r\n }\r\n\r\n // Add the HTML required attribute to fields which have unobtrusive required validation\r\n // setup\r\n public addRequiredAttributes() {\r\n const allfields = this.form.elements;\r\n for (var idxEl = 0; idxEl < allfields.length; ++idxEl) {\r\n const field = allfields[idxEl];\r\n const valrequired = field.getAttribute(\"data-val-required\");\r\n if (valrequired) {\r\n field.setAttribute('required', '');\r\n }\r\n }\r\n }\r\n\r\n // Check all elements for unobtrusive elements\r\n // and try to add our equivalents\r\n public addUnobtrusiveAttributes() {\r\n this.form.noValidate = true;\r\n this.checkValid = true;\r\n const allfields = this.form.elements;\r\n\r\n for (var idxEl = 0; idxEl < allfields.length; ++idxEl) {\r\n const field = allfields[idxEl];\r\n this.addUnobtrusiveField(field);\r\n }\r\n }\r\n\r\n // Called when the form is submitted. \r\n private submit(e: SubmitEvent) {\r\n // we're handling validity checks\r\n if (this.checkValid) {\r\n const isValid = this.form.reportValidity();\r\n if (!isValid) {\r\n e.preventDefault();\r\n return;\r\n }\r\n }\r\n\r\n if (this.checkDoubleSubmit) {\r\n if (this.isSubmitted) {\r\n // Previously submitted - don't submit again\r\n e.preventDefault();\r\n } else {\r\n // Mark it so that the next submit can be ignored\r\n this.isSubmitted = true;\r\n this.showSubmitted();\r\n }\r\n }\r\n }\r\n\r\n private showSubmitted() {\r\n this.submitButton.setAttribute('disabled', '');\r\n if (this.submitMessage) {\r\n if (this.submitButton.nodeName.toLowerCase() === 'button') {\r\n this.submitButton.innerHTML = this.submitMessage;\r\n }\r\n else {\r\n this.submitButton.value = this.submitMessage;\r\n }\r\n }\r\n }\r\n\r\n private addUnobtrusiveField(field: FieldElement) {\r\n if (!FormHelper.isFieldElement(field)) {\r\n return;\r\n }\r\n const self = this;\r\n\r\n const validElement: IValidationElement = {\r\n field: field,\r\n };\r\n\r\n field.addEventListener(\"invalid\", function handleInvalidField(event) {\r\n self.handleInvalid(field, event);\r\n });\r\n\r\n field.addEventListener(\"blur\", function handleFieldBlur() {\r\n const validElement = self.validationElements.get(field);\r\n self.clearErrorMessage(validElement);\r\n field.checkValidity();\r\n });\r\n\r\n // is there a related field that gets any messages that we have?\r\n if (field.name) {\r\n validElement.messageField = this.form.querySelector('[data-valmsg-for=\"' + field.name + '\"]');\r\n }\r\n\r\n var attributes = field.getAttributeNames();\r\n for (const attrkey of attributes) {\r\n const fixfunc = fixups[attrkey];\r\n if (fixfunc) {\r\n fixfunc(validElement, field.getAttribute(attrkey));\r\n }\r\n }\r\n\r\n this.validationElements.set(field, validElement);\r\n }\r\n\r\n private handleInvalid(field: FieldElement, event: Event) {\r\n // find the validElement\r\n event.preventDefault(); // suppress browser error\r\n const validElement = this.validationElements.get(field);\r\n const validity = field.validity;\r\n if (!validity) {\r\n this.setErrorMessage(validElement, null);\r\n return;\r\n }\r\n\r\n // check for missing\r\n if (validity.valueMissing && validElement.requiredMessage) {\r\n this.setErrorMessage(validElement, validElement.requiredMessage);\r\n return;\r\n }\r\n if (validity.typeMismatch) {\r\n if (validElement.emailMessage) {\r\n this.setErrorMessage(validElement, validElement.emailMessage);\r\n return;\r\n }\r\n if (validElement.creditcardMessage) {\r\n this.setErrorMessage(validElement, validElement.creditcardMessage);\r\n return;\r\n }\r\n if (validElement.phoneMessage) {\r\n this.setErrorMessage(validElement, validElement.phoneMessage);\r\n return;\r\n }\r\n }\r\n if (validity.tooLong) {\r\n this.setErrorMessage(validElement, validElement.maxlengthMessage);\r\n return;\r\n }\r\n if (validity.tooShort) {\r\n this.setErrorMessage(validElement, validElement.minlengthMessage);\r\n return;\r\n }\r\n if (validity.patternMismatch && validElement.regexMessage) {\r\n this.setErrorMessage(validElement, validElement.regexMessage);\r\n return;\r\n }\r\n\r\n // default...fall throught\r\n this.setErrorMessage(validElement, null);\r\n }\r\n\r\n private setErrorMessage(validElement: IValidationElement, message: string) {\r\n validElement.field.setAttribute(\"aria-invalid\", \"true\");\r\n validElement.field.classList.add(\"input-validation-error\");\r\n if (validElement.messageField) {\r\n validElement.messageField.innerHTML = message ? message : DEFAULTINVALIDMESSAGE;\r\n validElement.messageField.classList.remove(\"field-validation-valid\");\r\n validElement.messageField.classList.add(\"field-validation-error\");\r\n }\r\n }\r\n\r\n private clearErrorMessage(validElement: IValidationElement) {\r\n validElement.field.removeAttribute(\"aria-invalid\");\r\n validElement.field.classList.remove(\"input-validation-error\");\r\n\r\n if (validElement.messageField) {\r\n validElement.messageField.innerHTML = '';\r\n validElement.messageField.classList.add(\"field-validation-valid\");\r\n validElement.messageField.classList.remove(\"field-validation-error\");\r\n }\r\n }\r\n\r\n // Get the validity attribute. This probably isn't necessary, but just to \r\n // be safe\r\n private static isFieldElement(field: Element): boolean {\r\n if (field instanceof HTMLInputElement ||\r\n field instanceof HTMLSelectElement ||\r\n field instanceof HTMLTextAreaElement) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n}"],"names":["__webpack_require__","exports","definition","key","o","Object","defineProperty","enumerable","get","obj","prop","prototype","hasOwnProperty","call","Symbol","toStringTag","value","jQuery","CountdownTimer","constructor","listeners","tick","expired","this","isRunning","startTimer","seconds","self","endTimer","d","Date","startTimeMS","getTime","endTimeMS","timer","window","setInterval","clearInterval","secondsLeft","getSecondsLeft","forEach","listener","on","eventName","push","off","index","indexOf","splice","getFormattedTimeLeft","getFormattedTime","getMSLeft","timeLeft","Math","round","getMSElapsed","timeElapsed","maxMS","getSecondsElapsed","padtime","num","toString","sec_num","hours","floor","minutes","sSeconds","Lesson","pislid","piid","isTimerDone","$counttimer","$pageseconds","audioplayer","document","getElementById","addEventListener","e","preventDefault","oldvolume","localStorage","getItem","volume","parseFloat","audiovolumechange","setItem","lessonseconds","offsetLessonSeconds","elapsedTimeSaved","totalLessonSeconds","tevent","timerDone","confirm","saveElapsedTime","location","href","hasClass","data","FormData","append","navigator","sendBeacon","hide","show","val","evt","formattedSeconds","text","gcd_rec","a","b","abs","getaspectratio","width","height","gcd","showMedia","medialist","CourseSummary","$this","$chapter","closest","$lessons","is","slideUp","slideDown","Quiz","removeClass","Exam","MemberSQTimer","totalSeconds","securityQuestionID","$timerDisplay","sqID","postFailUrl","fixups","validElement","attrval","requiredMessage","field","setAttribute","emailMessage","phoneMessage","creditcardMessage","maxlengthMessage","minlengthMessage","regexMessage","FormHelper","setup","form","querySelector","submitButton","submitMessage","checkDoubleSubmit","isSubmitted","checkValid","validationElements","Map","submit","preventDoubleSubmit","addRequiredAttributes","allfields","elements","idxEl","length","getAttribute","addUnobtrusiveAttributes","noValidate","addUnobtrusiveField","reportValidity","showSubmitted","nodeName","toLowerCase","innerHTML","isFieldElement","event","handleInvalid","clearErrorMessage","checkValidity","name","messageField","attributes","getAttributeNames","attrkey","fixfunc","set","validity","valueMissing","setErrorMessage","typeMismatch","tooLong","tooShort","patternMismatch","message","classList","add","remove","removeAttribute","HTMLInputElement","HTMLSelectElement","HTMLTextAreaElement"],"sourceRoot":""}