{"version":3,"sources":["webpack://aspnetValidation/webpack/universalModuleDefinition","webpack://aspnetValidation/webpack/bootstrap","webpack://aspnetValidation/./src/index.ts"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","nullLogger","log","_","getRelativeFormElement","elementName","selector","realSelector","substr","dotLocation","lastIndexOf","relativeElementName","relativeElement","document","getElementsByName","required","element","params","Boolean","stringLength","min","parseInt","length","max","compare","other","otherElement","range","val","parseFloat","isNaN","regex","pattern","RegExp","test","email","creditcard","cDigit","nCheck","nDigit","bEven","replace","charAt","url","lowerCaseValue","toLowerCase","indexOf","phone","remote","fieldSelectors","additionalfields","split","fields","fieldSelector","fieldName","fieldElement","encodedParams","encodedParam","encodeURIComponent","push","payload","join","Promise","ok","reject","request","XMLHttpRequest","type","postData","FormData","append","open","setRequestHeader","send","onload","e","status","data","JSON","parse","responseText","statusText","onerror","logger","providers","messageFor","elementUIDs","elementByUID","formInputs","validators","elementEvents","summary","debounce","allowHiddenFields","validateForm","form","callback","formUID","getElementUID","formValidationEvent","focusFirstInvalid","invalidFormInputUIDs","filter","uid","firstInvalid","focus","isValid","prevalidate","isFieldValid","field","closest","fieldUID","ValidationInputCssClassName","ValidationInputValidCssClassName","ValidationMessageCssClassName","ValidationMessageValidCssClassName","this","addProvider","addMvcProviders","mvc","MvcValidationProviders","scanMessages","validationMessageElements","Array","from","querySelectorAll","hasAttribute","getAttribute","parseDirectives","attributes","directives","validationAtributes","cut","a","parameters","keys","Q","directive","error","pcut","pvalue","pkey","guid4","Math","random","toString","node","x","getFormValidationTask","formInputUIDs","formValidators","inputUID","tasks","map","all","then","result","every","shouldValidate","trackFormInput","cb","validate","success","isProgrammaticValidate","CustomEvent","detail","valid","dispatchEvent","preventDefault","stopImmediatePropagation","validationEvent","catch","console","addEventListener","input","classList","remove","spans","innerHTML","renderSummary","addInput","createValidator","delay","clearTimeout","setTimeout","isDropdown","tagName","validateEvent","dataset","valEvent","scanInputs","inputs","createSummaryDOM","ul","createElement","li","appendChild","summaryElements","shadow","stringify","sort","renderedSummaryJSON","className","cloneNode","addError","message","add","removeError","isHidden","provider","resolution","offsetWidth","offsetHeight","getClientRects","bootstrap","options","readyState","scan","body","event","watch","observer","MutationObserver","mutations","forEach","mutation","observed","observe","childList","subtree","addedNodes","HTMLElement","target"],"mappings":"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","file":"aspnet-validation.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"aspnetValidation\"] = factory();\n\telse\n\t\troot[\"aspnetValidation\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 0);\n","/**\n * A simple IDictionary<string, string>\n */\nexport interface StringKeyValuePair {\n    [key: string]: string\n}\n\n/**\n * A duplex key-value pair for an element, by GUID or its DOM object reference.\n */\ninterface ElementUID {\n    node: Element,\n    uid: string;\n}\n\n/**\n * A simple logging interface that mirrors the Console object.\n */\nexport interface Logger {\n    log(message: string, ...args: any[]): void;\n}\n\nconst nullLogger = new (class implements Logger {\n    log(_: string, ...args: any[]): void {}\n})();\n\n/**\n * Parameters passed into validation providers from the element attributes.\n * error property is read from data-val-[Provider Name] attribute.\n * params property is populated from data-val-[Provider Name]-[Parameter Name] attributes.\n */\nexport interface ValidationDirectiveBindings {\n    error: string,\n    params: StringKeyValuePair\n}\n\n/**\n * A key-value pair describing what validations to enforce to an input element, with respective parameters.\n */\nexport type ValidationDirective = {\n    [key: string]: ValidationDirectiveBindings\n};\n\n/**\n * Validation plugin signature with multitype return.\n * Boolean return signifies the validation result, which uses the default validation error message read from the element attribute.\n * String return signifies failed validation, which then will be used as the validation error message.\n * Promise return signifies asynchronous plugin behavior, with same behavior as Boolean or String.\n */\nexport type ValidationProvider = (value: string, element: HTMLInputElement, params: StringKeyValuePair) => boolean | string | Promise<boolean | string>;\n\n/**\n * A callback method signature that kickstarts a new validation task for an input element, as a Boolean Promise.\n */\ntype Validator = () => Promise<boolean>;\n\n/**\n * Resolves and returns the element referred by original element using ASP.NET selector logic.\n * @param elementName\n */\nfunction getRelativeFormElement(elementName: string, selector: string) {\n    // example elementName: Form.PasswordConfirm, Form.Email\n    // example selector (dafuq): *.Password, *.__RequestVerificationToken\n    // example result element name: Form.Password, __RequestVerificationToken\n\n    let realSelector = selector.substr(2); // Password, __RequestVerificationToken\n    let objectName = '';\n\n    let dotLocation = elementName.lastIndexOf('.');\n    if (dotLocation > -1) {\n        // Form\n        objectName = elementName.substr(0, dotLocation);\n\n        // Form.Password\n        let relativeElementName = objectName + '.' + realSelector;\n        let relativeElement = document.getElementsByName(relativeElementName)[0];\n        if (relativeElement) {\n            return relativeElement;\n        }\n    }\n\n    // __RequestVerificationToken\n    return document.getElementsByName(realSelector)[0];\n}\n\n/**\n * Contains default implementations for ASP.NET Core MVC validation attributes.\n */\nexport class MvcValidationProviders {\n    /**\n     * Validates whether the input has a value.\n     */\n    required: ValidationProvider = (value, element, params) => {\n        return Boolean(value);\n    }\n\n    /**\n     * Validates whether the input value satisfies the length contstraint.\n     */\n    stringLength: ValidationProvider = (value, element, params) => {\n        if (!value) {\n            return true;\n        }\n\n        if (params.min) {\n            let min = parseInt(params.min);\n            if (value.length < min) {\n                return false;\n            }\n        }\n\n        if (params.max) {\n            let max = parseInt(params.max);\n            if (value.length > max) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validates whether the input value is equal to another input value.\n     */\n    compare: ValidationProvider = (value, element, params) => {\n        if (!params.other) {\n            return true;\n        }\n\n        let otherElement = getRelativeFormElement(element.name, params.other) as HTMLInputElement;\n        if (!otherElement) {\n            return true;\n        }\n\n        return (otherElement.value === value);\n    }\n\n    /**\n     * Validates whether the input value is a number within a given range.\n     */\n    range: ValidationProvider = (value, element, params) => {\n        if (!value) {\n            return true;\n        }\n\n        let val = parseFloat(value);\n        if (isNaN(val)) {\n            return false;\n        }\n\n        if (params.min) {\n            let min = parseFloat(params.min);\n            if (val < min) {\n                return false;\n            }\n        }\n\n        if (params.max) {\n            let max = parseFloat(params.max);\n            if (val > max) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Validates whether the input value satisfies a regular expression pattern.\n     */\n    regex: ValidationProvider = (value, element, params) => {\n        if (!value || !params.pattern) {\n            return true;\n        }\n\n        let r = new RegExp(params.pattern);\n        return r.test(value);\n    }\n\n    /**\n     * Validates whether the input value is an email in accordance to RFC822 specification, with a top level domain.\n     */\n    email: ValidationProvider = (value, element, params) => {\n        if (!value) {\n            return true;\n        }\n\n        // RFC822 email address with .TLD validation\n        // (c) Richard Willis, Chris Ferdinandi, MIT Licensed\n        // https://gist.github.com/badsyntax/719800\n        // https://gist.github.com/cferdinandi/d04aad4ce064b8da3edf21e26f8944c4\n\n        let r = /^([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x22([^\\x0d\\x22\\x5c\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x22))*\\x40([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x5d)(\\x2e([^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+|\\x5b([^\\x0d\\x5b-\\x5d\\x80-\\xff]|\\x5c[\\x00-\\x7f])*\\x5d))*(\\.\\w{2,})+$/;\n        return r.test(value);\n    }\n\n    /**\n     * Validates whether the input value is a credit card number, with Luhn's Algorithm.\n     */\n    creditcard: ValidationProvider = (value, element, params) => {\n        if (!value) {\n            return true;\n        }\n\n        // (c) jquery-validation, MIT Licensed\n        // https://github.com/jquery-validation/jquery-validation/blob/master/src/additional/creditcard.js\n        // based on https://en.wikipedia.org/wiki/Luhn_algorithm\n\n        // Accept only spaces, digits and dashes\n        if (/[^0-9 \\-]+/.test(value)) {\n            return false;\n        }\n\n        var nCheck = 0,\n            nDigit = 0,\n            bEven = false,\n            n, cDigit;\n\n        value = value.replace(/\\D/g, \"\");\n\n        // Basing min and max length on https://developer.ean.com/general_info/Valid_Credit_Card_Types\n        if (value.length < 13 || value.length > 19) {\n            return false;\n        }\n\n        for (n = value.length - 1; n >= 0; n--) {\n            cDigit = value.charAt(n);\n            nDigit = parseInt(cDigit, 10);\n            if (bEven) {\n                if ((nDigit *= 2) > 9) {\n                    nDigit -= 9;\n                }\n            }\n\n            nCheck += nDigit;\n            bEven = !bEven;\n        }\n\n        return (nCheck % 10) === 0;\n    }\n\n    /**\n     * Validates whether the input value is a URL.\n     */\n    url: ValidationProvider = (value, element, params) => {\n        if (!value) {\n            return true;\n        }\n\n        let lowerCaseValue = value.toLowerCase();\n\n        // Match the logic in `UrlAttribute`\n        return lowerCaseValue.indexOf('http://') > -1\n            || lowerCaseValue.indexOf('https://') > -1\n            || lowerCaseValue.indexOf('ftp://') > -1;\n    }\n\n    /**\n     * Validates whether the input value is a phone number.\n     */\n    phone: ValidationProvider = (value, element, params) => {\n        if (!value) {\n            return true;\n        }\n\n        // Allows whitespace or dash as number separator because some people like to do that...\n        let consecutiveSeparator = /[\\+\\-\\s][\\-\\s]/g;\n        if (consecutiveSeparator.test(value)) {\n            return false;\n        }\n\n        let r = /^\\+?[0-9\\-\\s]+$/;\n        return r.test(value);\n    }\n\n    /**\n     * Asynchronously validates the input value to a JSON GET API endpoint.\n     */\n    remote: ValidationProvider = (value, element, params) => {\n        if (!value) {\n            return true;\n        }\n\n        // params.additionalfields: *.Email,*.Username\n        let fieldSelectors: string[] = (params.additionalfields as string).split(',');\n        let fields: StringKeyValuePair = {};\n\n        for (let fieldSelector of fieldSelectors) {\n            let fieldName = fieldSelector.substr(2);\n            let fieldElement = getRelativeFormElement(element.name, fieldSelector) as HTMLInputElement;\n\n            let hasValue = Boolean(fieldElement && fieldElement.value);\n            if (!hasValue) {\n                continue;\n            }\n\n            fields[fieldName] = fieldElement.value;\n        }\n\n        let url: string = params['url'];\n        // console.log(fields);\n\n        let encodedParams: string[] = [];\n        for (let fieldName in fields) {\n            let encodedParam = encodeURIComponent(fieldName) + '=' + encodeURIComponent(fields[fieldName]);\n            encodedParams.push(encodedParam);\n        }\n        let payload = encodedParams.join('&');\n        // console.log(payload);\n\n        return new Promise((ok, reject) => {\n            let request = new XMLHttpRequest();\n\n            if (params.type === 'Post') {\n                let postData = new FormData();\n                for (let fieldName in fields) {\n                    postData.append(fieldName, fields[fieldName]);\n                }\n                request.open('post', url);\n                request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\n                request.send(payload);\n            } else {\n                request.open('get', url + '?' + payload);\n                request.send();\n            }\n\n            request.onload = e => {\n                if (request.status >= 200 && request.status < 300) {\n                    let data = JSON.parse(request.responseText);\n                    ok(data);\n                } else {\n                    reject({\n                        status: request.status,\n                        statusText: request.statusText,\n                        data: request.responseText\n                    });\n                }\n            };\n\n            request.onerror = e => {\n                reject({\n                    status: request.status,\n                    statusText: request.statusText,\n                    data: request.responseText\n                });\n            };\n        });\n    }\n}\n\n/**\n * Responsibles for managing the DOM elements and running the validation providers.\n */\nexport class ValidationService {\n    /**\n     * A key-value collection of loaded validation plugins.\n     */\n    private providers: { [name: string]: ValidationProvider } = {};\n\n    /**\n     * A key-value collection of <span> elements for displaying validation messages for an input (by DOM ID).\n     */\n    private messageFor: { [id: string]: Element[] } = {};\n\n    /**\n     * A list of managed elements, each having a randomly assigned unique identifier (UID).\n     */\n    private elementUIDs: ElementUID[] = [];\n\n    /**\n     * A key-value collection of UID to Element for quick lookup.\n     */\n    private elementByUID: { [uid: string]: Element } = {};\n\n    /**\n     * A key-value collection of input UIDs for a <form> UID.\n     */\n    private formInputs: { [formUID: string]: string[] } = {};\n\n    /**\n     * A key-value map for input UID to its validator factory.\n     */\n    private validators: { [inputUID: string]: Validator } = {};\n\n    /**\n     * A key-value map for element UID to its trigger element (submit event for <form>, input event for <textarea> and <input>).\n     */\n    private elementEvents: { [id: string]: (e: Event, callback?: Function) => any } = {};\n\n    /**\n     * A key-value map of input UID to its validation error message.\n     */\n    private summary: StringKeyValuePair = {};\n\n    /**\n     * A serialized representation of the validation error message summary rendered to the user.\n     */\n    private renderedSummaryJSON: string;\n\n    /**\n     * In milliseconds, the rate of fire of the input validation.\n     */\n    debounce = 300;\n\n    /**\n     * Allow hidden fields validation     \n     */\n    allowHiddenFields = false;\n\n    private logger: Logger;\n    observer?: MutationObserver;\n\n    constructor(logger?: Logger) {\n        this.logger = logger || nullLogger;\n    }\n\n    /**\n     * Registers a new validation plugin of the given name, if not registered yet.\n     * Registered plugin validates inputs with data-val-[name] attribute, used as error message.\n     * @param name\n     * @param callback\n     */\n    addProvider(name: string, callback: ValidationProvider) {\n        if (this.providers[name]) {\n            // First-Come-First-Serve validation plugin design.\n            // Allows developers to override the default MVC Providers by adding custom providers BEFORE bootstrap() is called!\n            return;\n        }\n        this.logger.log(`Registered provider: ${name}`);\n        this.providers[name] = callback;\n    }\n\n    /**\n     * Registers the default providers for enabling ASP.NET Core MVC client-side validation.\n     */\n    private addMvcProviders() {\n        let mvc = new MvcValidationProviders();\n\n        // [Required]\n        this.addProvider('required', mvc.required);\n        // [StringLength], [MinLength], [MaxLength]\n        this.addProvider('length', mvc.stringLength);\n        this.addProvider('maxlength', mvc.stringLength);\n        this.addProvider('minlength', mvc.stringLength);\n        // [Compare]\n        this.addProvider('equalto', mvc.compare);\n        // [Range]\n        this.addProvider('range', mvc.range);\n        // [RegularExpression]\n        this.addProvider('regex', mvc.regex);\n        // [CreditCard]\n        this.addProvider('creditcard', mvc.creditcard);\n        // [EmailAddress]\n        this.addProvider('email', mvc.email);\n        // [Url]\n        this.addProvider('url', mvc.url);\n        // [Phone]\n        this.addProvider('phone', mvc.phone);\n        // [Remote]\n        this.addProvider('remote', mvc.remote);\n    }\n\n    /**\n     * Scans document for all validation message <span> generated by ASP.NET Core MVC, then tracks them.\n     */\n    private scanMessages(root: HTMLElement) {\n        let validationMessageElements = Array.from(root.querySelectorAll<HTMLElement>('[data-valmsg-for]'));\n\n        // querySelectorAll does not include the root element itself.\n        // we could use 'matches', but that's newer than querySelectorAll so we'll keep it simple and compatible.\n        if (root.hasAttribute(\"data-valmsg-for\")) {\n            validationMessageElements.push(root);\n        }\n\n        for (let i = 0; i < validationMessageElements.length; i++) {\n            let e = validationMessageElements[i];\n            let name = e.getAttribute('data-valmsg-for');\n\n            if (!this.messageFor[name]) {\n                this.messageFor[name] = [];\n            }\n\n            this.messageFor[name].push(e);\n        }\n    }\n\n    /**\n     * Given attribute map for an HTML input, returns the validation directives to be executed.\n     * @param attributes\n     */\n    parseDirectives(attributes: NamedNodeMap) {\n        let directives: ValidationDirective = {};\n        let validationAtributes: StringKeyValuePair = {};\n\n        let cut = 'data-val-'.length;\n        for (let i = 0; i < attributes.length; i++) {\n            let a = attributes[i];\n            if (a.name.indexOf('data-val-') === 0) {\n                let key = a.name.substr(cut);\n                validationAtributes[key] = a.value;\n            }\n        }\n\n        for (let key in validationAtributes) {\n            if (key.indexOf('-') === -1) {\n                let parameters = Object.keys(validationAtributes).filter(Q => {\n                    return (Q !== key) && (Q.indexOf(key) === 0);\n                });\n\n                let directive: ValidationDirectiveBindings = {\n                    error: validationAtributes[key],\n                    params: {}\n                };\n\n                let pcut = (key + '-').length;\n                for (let i = 0; i < parameters.length; i++) {\n                    let pvalue = validationAtributes[parameters[i]];\n                    let pkey = parameters[i].substr(pcut);\n\n                    directive.params[pkey] = pvalue;\n                }\n\n                directives[key] = directive;\n            }\n        }\n\n        // console.log(directives);\n        return directives;\n    }\n\n    /**\n     *  Returns an RFC4122 version 4 compliant GUID.\n     */\n    private guid4() {\n        // (c) broofa, MIT Licensed\n        // https://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript/2117523#2117523\n\n        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n            var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);\n            return v.toString(16);\n        });\n    }\n\n    /**\n     * Gets a UID for an DOM element.\n     * @param node\n     */\n    private getElementUID(node: Element) {\n        let x = this.elementUIDs.filter(e => {\n            return e.node === node;\n        })[0];\n\n        if (x) {\n            return x.uid;\n        }\n\n        let uid = this.guid4();\n        this.elementUIDs.push({\n            node: node,\n            uid: uid\n        });\n        this.elementByUID[uid] = node;\n        return uid;\n    }\n\n    /**\n     * Returns a Promise that returns validation result for each and every inputs within the form.\n     * @param formUID\n     */\n    private getFormValidationTask(formUID: string) {\n        let formInputUIDs = this.formInputs[formUID];\n        if (!formInputUIDs || formInputUIDs.length === 0) {\n            return null;\n        }\n\n        let formValidators: Validator[] = [];\n\n        for (let i = 0; i < formInputUIDs.length; i++) {\n            let inputUID = formInputUIDs[i];\n            formValidators.push(this.validators[inputUID]);\n        }\n\n        let tasks = formValidators.map(factory => factory());\n        return Promise.all(tasks).then(result => result.every(e => e));\n    }\n\n    /**\n     * Fires off validation for elements within the provided form and then calls the callback\n     * @param form\n     * @param callback\n     */\n    validateForm = (form: HTMLFormElement, callback: Function) => {\n        let formUID = this.getElementUID(form);\n        let formValidationEvent = this.elementEvents[formUID];\n        if (formValidationEvent) {\n            formValidationEvent(null, callback);\n        }\n    }\n\n\n    /**\n     * Focuses the first invalid element within the provided form\n     * @param form\n     */\n    focusFirstInvalid = (form: HTMLFormElement) => {\n        let formUID = this.getElementUID(form);\n        let formInputUIDs = this.formInputs[formUID];\n        let invalidFormInputUIDs = formInputUIDs.filter(uid => this.summary[uid]);\n\n        if (invalidFormInputUIDs.length > 0) {\n            var firstInvalid = this.elementByUID[invalidFormInputUIDs[0]] as HTMLElement;\n            if (firstInvalid) {\n                firstInvalid.focus();\n            }\n        }\n    }\n\n    /**\n     * Returns true if the provided form is valid, and then calls the callback. The form will be validated before checking, unless prevalidate is set to false\n     * @param form\n     * @param prevalidate\n     * @param callback\n     * @returns\n     */\n    isValid = (form: HTMLFormElement, prevalidate: boolean = true, callback: Function) => {\n        if (prevalidate) {\n            this.validateForm(form, callback);\n        }\n        let formUID = this.getElementUID(form);\n        let formInputUIDs = this.formInputs[formUID];\n        let invalidFormInputUIDs = formInputUIDs.filter(uid => this.summary[uid]);\n        return invalidFormInputUIDs.length == 0;\n    }\n\n    /**\n     * Returns true if the provided field is valid, and then calls the callback. The form will be validated before checking, unless prevalidate is set to false\n     * @param form\n     * @param prevalidate\n     * @param callback\n     * @returns\n     */\n    isFieldValid = (field: HTMLElement, prevalidate: boolean = true, callback: Function) => {\n\n        if (prevalidate) {\n            let form = field.closest(\"form\");\n            if (form != null) {\n                this.validateForm(form, callback);\n            }\n        }\n\n        let fieldUID = this.getElementUID(field);\n        return this.summary[fieldUID] != null;\n    }\n\n    /**\n     * Returns true if the event triggering the form submission indicates we should validate the form.\n     * @param e\n     */\n    private shouldValidate(e: Event) {\n        // Skip client-side validation if the form has been submitted via a button that has the \"formnovalidate\" attribute.\n        return !(e !== null && e['submitter'] && e['submitter']['formNoValidate']);\n    }\n\n    /**\n     * Tracks a <form> element as parent of an input UID. When the form is submitted, attempts to validate the said input asynchronously.\n     * @param form\n     * @param inputUID\n     */\n    private trackFormInput(form: HTMLFormElement, inputUID: string) {\n        let formUID = this.getElementUID(form);\n        if (!this.formInputs[formUID]) {\n            this.formInputs[formUID] = [];\n        }\n        let add = (this.formInputs[formUID].indexOf(inputUID) === -1);\n        if (add) {\n            this.formInputs[formUID].push(inputUID);\n        }\n\n        if (this.elementEvents[formUID]) {\n            return;\n        }\n\n        let cb = (e: Event, callback?: Function) => {\n            if (!this.shouldValidate(e)) {\n                return;\n            }\n\n            let validate = this.getFormValidationTask(formUID);\n            if (!validate) {\n                return;\n            }\n\n            validate.then(success => {\n                let isProgrammaticValidate = !e;\n                if (success) {\n                    if (isProgrammaticValidate) {\n                        callback(true);\n                        return;\n                    }\n                    const validationEvent = new CustomEvent('validation',\n                    {\n                        detail: { valid: true }\n                    });\n                    form.dispatchEvent(validationEvent);\n                    return;\n                }\n\n                if (e) {\n                    e.preventDefault();\n                    e.stopImmediatePropagation();\n                }\n\n                const validationEvent = new CustomEvent('validation',\n                {\n                    detail: { valid: false }\n                });\n                form.dispatchEvent(validationEvent);\n\n\n                if (isProgrammaticValidate) {\n                    callback(false);\n                }\n                else {\n                    this.focusFirstInvalid(form);\n                }\n            }).catch(error => {\n                console.log(error);\n            });\n        };\n\n        form.addEventListener('submit', cb);\n        form.addEventListener('reset', e => {\n            let uids = this.formInputs[formUID];\n\n            for (let uid of uids) {\n                let input = this.elementByUID[uid] as HTMLInputElement;\n                input.classList.remove(this.ValidationInputCssClassName);\n                input.classList.remove(this.ValidationInputValidCssClassName);\n\n                let spans = this.messageFor[input.name];\n                if (spans) {\n                    for (let i = 0; i < spans.length; i++) {\n                        spans[i].innerHTML = '';\n                    }\n                }\n\n                delete this.summary[uid];\n            }\n            this.renderSummary();\n        });\n        this.elementEvents[formUID] = cb;\n    }\n\n    /**\n     * Adds an input element to be managed and validated by the service.\n     * Triggers a debounced live validation when input value changes.\n     * @param input\n     */\n    addInput(input: HTMLInputElement) {\n        let uid = this.getElementUID(input);\n\n        let directives = this.parseDirectives(input.attributes);\n        let validate = this.createValidator(input, directives);\n\n        this.validators[uid] = validate;\n        if (input.form) {\n            this.trackFormInput(input.form, uid);\n        }\n\n        if (this.elementEvents[uid]) {\n            return;\n        }\n\n        let delay;\n        let cb = e => {\n            let validate = this.validators[uid];\n            clearTimeout(delay);\n            delay = setTimeout(validate, this.debounce);\n        };\n\n        let isDropdown = input.tagName.toLowerCase() === 'select';\n        let validateEvent = input.dataset.valEvent;\n        if (isDropdown) {\n            input.addEventListener('change', cb);\n        } else if (validateEvent) {\n            input.addEventListener(validateEvent, cb);\n        }\n        else {\n            input.addEventListener('input', cb);\n        }\n\n        this.elementEvents[uid] = cb;\n    }\n\n    /**\n     * Scans the entire document for input elements to be validated.\n     */\n    private scanInputs(root: HTMLElement) {\n        let inputs = Array.from(root.querySelectorAll<HTMLElement>('[data-val=\"true\"]'));\n\n        // querySelectorAll does not include the root element itself.\n        // we could use 'matches', but that's newer than querySelectorAll so we'll keep it simple and compatible.\n        if (root.getAttribute(\"data-val\") === \"true\") {\n            inputs.push(root);\n        }\n\n        for (let i = 0; i < inputs.length; i++) {\n            let input = inputs[i] as HTMLInputElement;\n            this.addInput(input);\n        }\n    }\n\n    /**\n     * Returns a <ul> element as a validation errors summary.\n     */\n    createSummaryDOM() {\n        if (!Object.keys(this.summary).length) {\n            return null;\n        }\n\n        let ul = document.createElement('ul');\n        for (let key in this.summary) {\n            let li = document.createElement('li');\n            li.innerHTML = this.summary[key];\n            ul.appendChild(li);\n        }\n        return ul;\n    }\n\n    /**\n     * Displays validation summary to ASP.NET Core MVC designated elements, when it actually gets updated.\n     */\n    private renderSummary() {\n        let summaryElements = document.querySelectorAll('[data-valmsg-summary=\"true\"]');\n        if (!summaryElements.length) {\n            return;\n        }\n\n        // Using JSON.stringify for quick and painless deep compare of simple KVP. You need to sort the keys first, tho...\n        let shadow = JSON.stringify(this.summary, Object.keys(this.summary).sort());\n        if (shadow === this.renderedSummaryJSON) {\n            return;\n        }\n\n        // Prevents wasteful re-rendering of summary list element with identical items!\n        // console.log('RENDERING VALIDATION SUMMARY');\n        this.renderedSummaryJSON = shadow;\n        let ul = this.createSummaryDOM();\n\n        for (let i = 0; i < summaryElements.length; i++) {\n            let e = summaryElements[i];\n            e.innerHTML = '';\n            if (ul) {\n                e.className = 'validation-summary-errors';\n                e.appendChild(ul.cloneNode(true));\n            } else {\n                e.className = 'validation-summary-valid';\n            }\n        }\n    }\n\n    /**\n     * Adds an error message to an input element, which also updates the validation message elements and validation summary elements.\n     * @param input\n     * @param message\n     */\n    addError(input: HTMLInputElement, message: string) {\n        let spans = this.messageFor[input.name];\n        if (spans) {\n            for (let i = 0; i < spans.length; i++) {\n                spans[i].innerHTML = message;\n                spans[i].className = this.ValidationMessageCssClassName;\n            }\n        }\n\n        input.classList.remove(this.ValidationInputValidCssClassName);\n        input.classList.add(this.ValidationInputCssClassName);\n\n        let uid = this.getElementUID(input);\n        this.summary[uid] = message;\n        this.renderSummary();\n    }\n\n    /**\n     * Removes an error message from an input element, which also updates the validation message elements and validation summary elements.\n     * @param input\n     */\n    removeError(input: HTMLInputElement) {\n        let spans = this.messageFor[input.name];\n        if (spans) {\n            for (let i = 0; i < spans.length; i++) {\n                spans[i].innerHTML = '';\n                spans[i].className = this.ValidationMessageValidCssClassName;\n            }\n        }\n\n        input.classList.remove(this.ValidationInputCssClassName);\n        input.classList.add(this.ValidationInputValidCssClassName);\n\n        let uid = this.getElementUID(input);\n        delete this.summary[uid];\n        this.renderSummary();\n    }\n\n    /**\n     * Returns a validation Promise factory for an input element, using given validation directives.\n     * @param input\n     * @param directives\n     */\n    createValidator(input: HTMLInputElement, directives: ValidationDirective) {\n        return async () => {\n\n            // only validate visible fields\n            if (!this.isHidden(input))\n            {\n                for (let key in directives) {\n                    let directive = directives[key];\n                    let provider = this.providers[key];\n\n                    if (!provider) {\n                        console.log('aspnet-validation provider not implemented: ' + key);\n                        continue;\n                    }\n                    this.logger.log(`Running ${key} validator on element`, input);\n\n                    let result = provider(input.value, input, directive.params);\n                    let valid = false;\n                    let error = directive.error;\n\n                    if (typeof result === 'boolean') {\n                        valid = result;\n                    } else if (typeof result === 'string') {\n                        valid = false;\n                        error = result;\n                    } else {\n                        let resolution = await result;\n                        if (typeof resolution === 'boolean') {\n                            valid = resolution;\n                        } else {\n                            valid = false;\n                            error = resolution;\n                        }\n                    }\n\n                    if (!valid) {\n                        this.addError(input, error);\n                        return false;\n                    }\n                }\n            }\n\n            this.removeError(input);\n            return true;\n\n        };\n    }\n\n    /**\n     * Checks if the provided input is hidden from the browser\n     * @param input\n     * @returns\n     */\n    private isHidden(input: HTMLElement) {\n        return !(this.allowHiddenFields || input.offsetWidth || input.offsetHeight || input.getClientRects().length );\n    }\n\n    /**\n     * Load default validation providers and scans the entire document when ready.\n     * @param options.watch If set to true, a MutationObserver will be used to continuously watch for new elements that provide validation directives.\n     */\n    bootstrap(options?: { watch?: boolean, root?: HTMLElement }) {\n        options = options || {};\n\n        this.addMvcProviders();\n        let document = window.document;\n        // If the document is done loading, scan it now.\n        if(document.readyState === 'complete' || document.readyState === 'interactive') {\n            this.scan(options.root || window.document.body);\n        }\n        else {\n            // Otherwise wait until the document is done loading.\n            window.document.addEventListener('DOMContentLoaded', event => {\n                this.scan(options.root || window.document.body);\n            });\n        }\n\n        // Watch for further mutations\n        if (options.watch) {\n            this.watch(options.root);\n        }\n    }\n\n    /**\n     * Scans the provided root element for any validation directives and attaches behavior to them.\n     */\n    scan(root: HTMLElement) {\n        this.scanMessages(root);\n        this.scanInputs(root);\n    }\n\n    /**\n     * Watches the provided root element for mutations, and scans for new validation directives to attach behavior.\n     * @param root The root element to use, defaults to the document.documentElement.\n     */\n    watch(root: HTMLElement) {\n        this.observer = new MutationObserver(mutations => {\n            mutations.forEach(mutation => {\n                this.observed(mutation);\n            });\n        });\n        this.observer.observe(root, {\n            attributes: true,\n            childList: true,\n            subtree: true\n        });\n        this.logger.log(\"Watching for mutations\");\n    }\n\n    private observed(mutation: MutationRecord) {\n        if(mutation.type === 'childList') {\n            for(let i = 0; i < mutation.addedNodes.length; i++) {\n                let node = mutation.addedNodes[i];\n                if (node instanceof HTMLElement) {\n                    this.scan(node);\n                }\n            }\n        } else if(mutation.type === 'attributes') {\n            if (mutation.target instanceof HTMLElement) {\n                this.scan(mutation.target);\n            }\n        }\n    }\n\n    /**\n     * Override CSS class name for input validation. Default: 'input-validation-error'\n     */\n     ValidationInputCssClassName = \"input-validation-error\";\n\n     /**\n      * Override CSS class name for valid input validation. Default: 'input-validation-valid'\n      */\n     ValidationInputValidCssClassName = \"input-validation-valid\";\n\n     /**\n      * Override CSS class name for field validation error. Default: 'field-validation-error'\n      */\n     ValidationMessageCssClassName = \"field-validation-error\";  \n\n     /**\n      * Override CSS class name for valid field validation. Default: 'field-validation-valid'\n      */\n     ValidationMessageValidCssClassName = \"field-validation-valid\";\n}\n"],"sourceRoot":""}