{"version":3,"file":"input-format.min.js","sources":["../modules/helpers.js","../modules/close braces.js","../modules/template formatter.js","../modules/parse digit.js","../modules/parse.js","../modules/format.js","../modules/dom.js","../modules/input control.js","../modules/edit.js","../modules/template parser.js"],"sourcesContent":["// Counts all occurences of a symbol in a string\nexport function count_occurences(symbol, string) {\n var count = 0; // Using `.split('')` here instead of normal `for ... of`\n // because the importing application doesn't neccessarily include an ES6 polyfill.\n // The `.split('')` approach discards \"exotic\" UTF-8 characters\n // (the ones consisting of four bytes)\n // but template placeholder characters don't fall into that range\n // so skipping such miscellaneous \"exotic\" characters\n // won't matter here for just counting placeholder character occurrences.\n\n for (var _iterator = string.split(''), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var character = _ref;\n\n if (character === symbol) {\n count++;\n }\n }\n\n return count;\n}\n//# sourceMappingURL=helpers.js.map","import { count_occurences } from './helpers';\nexport default function close_braces(retained_template, template) {\n var placeholder = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'x';\n var empty_placeholder = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : ' ';\n var cut_before = retained_template.length;\n var opening_braces = count_occurences('(', retained_template);\n var closing_braces = count_occurences(')', retained_template);\n var dangling_braces = opening_braces - closing_braces;\n\n while (dangling_braces > 0 && cut_before < template.length) {\n retained_template += template[cut_before].replace(placeholder, empty_placeholder);\n\n if (template[cut_before] === ')') {\n dangling_braces--;\n }\n\n cut_before++;\n }\n\n return retained_template;\n}\n//# sourceMappingURL=close braces.js.map","import { count_occurences } from './helpers';\nimport close_braces from './close braces'; // Takes a `template` where character placeholders\n// are denoted by 'x'es (e.g. 'x (xxx) xxx-xx-xx').\n//\n// Returns a function which takes `value` characters\n// and returns the `template` filled with those characters.\n// If the `template` can only be partially filled\n// then it is cut off.\n//\n// If `should_close_braces` is `true`,\n// then it will also make sure all dangling braces are closed,\n// e.g. \"8 (8\" -> \"8 (8 )\" (iPhone style phone number input).\n//\n\nexport default function (template) {\n var placeholder = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'x';\n var should_close_braces = arguments.length > 2 ? arguments[2] : undefined;\n\n if (!template) {\n return function (value) {\n return {\n text: value\n };\n };\n }\n\n var characters_in_template = count_occurences(placeholder, template);\n return function (value) {\n if (!value) {\n return {\n text: '',\n template: template\n };\n }\n\n var value_character_index = 0;\n var filled_in_template = ''; // Using `.split('')` here instead of normal `for ... of`\n // because the importing application doesn't neccessarily include an ES6 polyfill.\n // The `.split('')` approach discards \"exotic\" UTF-8 characters\n // (the ones consisting of four bytes)\n // but template placeholder characters don't fall into that range\n // and appending UTF-8 characters to a string in parts still works.\n\n for (var _iterator = template.split(''), _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {\n var _ref;\n\n if (_isArray) {\n if (_i >= _iterator.length) break;\n _ref = _iterator[_i++];\n } else {\n _i = _iterator.next();\n if (_i.done) break;\n _ref = _i.value;\n }\n\n var character = _ref;\n\n if (character !== placeholder) {\n filled_in_template += character;\n continue;\n }\n\n filled_in_template += value[value_character_index];\n value_character_index++; // If the last available value character has been filled in,\n // then return the filled in template\n // (either trim the right part or retain it,\n // if no more character placeholders in there)\n\n if (value_character_index === value.length) {\n // If there are more character placeholders\n // in the right part of the template\n // then simply trim it.\n if (value.length < characters_in_template) {\n break;\n }\n }\n }\n\n if (should_close_braces) {\n filled_in_template = close_braces(filled_in_template, template);\n }\n\n return {\n text: filled_in_template,\n template: template\n };\n };\n}\n//# sourceMappingURL=template formatter.js.map","// Copied from `libphonenumber-js`:\n// https://gitlab.com/catamphetamine/libphonenumber-js/blob/master/source/parse.js\n//\n// These mappings map a character (key) to a specific digit that should\n// replace it for normalization purposes. Non-European digits that\n// may be used in phone numbers are mapped to a European equivalent.\n//\n// E.g. in Iraq they don't write `+442323234` but rather `+٤٤٢٣٢٣٢٣٤`.\n//\nexport var DIGITS = {\n '0': '0',\n '1': '1',\n '2': '2',\n '3': '3',\n '4': '4',\n '5': '5',\n '6': '6',\n '7': '7',\n '8': '8',\n '9': '9',\n \"\\uFF10\": '0',\n // Fullwidth digit 0\n \"\\uFF11\": '1',\n // Fullwidth digit 1\n \"\\uFF12\": '2',\n // Fullwidth digit 2\n \"\\uFF13\": '3',\n // Fullwidth digit 3\n \"\\uFF14\": '4',\n // Fullwidth digit 4\n \"\\uFF15\": '5',\n // Fullwidth digit 5\n \"\\uFF16\": '6',\n // Fullwidth digit 6\n \"\\uFF17\": '7',\n // Fullwidth digit 7\n \"\\uFF18\": '8',\n // Fullwidth digit 8\n \"\\uFF19\": '9',\n // Fullwidth digit 9\n \"\\u0660\": '0',\n // Arabic-indic digit 0\n \"\\u0661\": '1',\n // Arabic-indic digit 1\n \"\\u0662\": '2',\n // Arabic-indic digit 2\n \"\\u0663\": '3',\n // Arabic-indic digit 3\n \"\\u0664\": '4',\n // Arabic-indic digit 4\n \"\\u0665\": '5',\n // Arabic-indic digit 5\n \"\\u0666\": '6',\n // Arabic-indic digit 6\n \"\\u0667\": '7',\n // Arabic-indic digit 7\n \"\\u0668\": '8',\n // Arabic-indic digit 8\n \"\\u0669\": '9',\n // Arabic-indic digit 9\n \"\\u06F0\": '0',\n // Eastern-Arabic digit 0\n \"\\u06F1\": '1',\n // Eastern-Arabic digit 1\n \"\\u06F2\": '2',\n // Eastern-Arabic digit 2\n \"\\u06F3\": '3',\n // Eastern-Arabic digit 3\n \"\\u06F4\": '4',\n // Eastern-Arabic digit 4\n \"\\u06F5\": '5',\n // Eastern-Arabic digit 5\n \"\\u06F6\": '6',\n // Eastern-Arabic digit 6\n \"\\u06F7\": '7',\n // Eastern-Arabic digit 7\n \"\\u06F8\": '8',\n // Eastern-Arabic digit 8\n \"\\u06F9\": '9' // Eastern-Arabic digit 9\n\n};\nexport default function (character, value) {\n return DIGITS[character];\n}\n//# sourceMappingURL=parse digit.js.map","// Parses the `text`.\n//\n// Returns `{ value, caret }` where `caret` is\n// the caret position inside `value`\n// corresponding to the `caret_position` inside `text`.\n//\n// The `text` is parsed by feeding each character sequentially to\n// `parse_character(character, value)` function\n// and appending the result (if it's not `undefined`) to `value`.\n//\n// Example:\n//\n// `text` is `8 (800) 555-35-35`,\n// `caret_position` is `4` (before the first `0`).\n// `parse_character` is `(character, value) =>\n// if (character >= '0' && character <= '9') { return character }`.\n//\n// then `parse()` outputs `{ value: '88005553535', caret: 2 }`.\n//\nexport default function parse(text, caret_position, parse_character) {\n var value = '';\n var focused_input_character_index = 0;\n var index = 0;\n\n while (index < text.length) {\n var character = parse_character(text[index], value);\n\n if (character !== undefined) {\n value += character;\n\n if (caret_position !== undefined) {\n if (caret_position === index) {\n focused_input_character_index = value.length - 1;\n } else if (caret_position > index) {\n focused_input_character_index = value.length;\n }\n }\n }\n\n index++;\n } // If caret position wasn't specified\n\n\n if (caret_position === undefined) {\n // Then set caret position to \"after the last input character\"\n focused_input_character_index = value.length;\n }\n\n var result = {\n value: value,\n caret: focused_input_character_index\n };\n return result;\n}\n//# sourceMappingURL=parse.js.map","import template_formatter from './template formatter'; // Formats `value` value preserving `caret` at the same character.\n//\n// `{ value, caret }` attribute is the result of `parse()` function call.\n//\n// Returns `{ text, caret }` where the new `caret` is the caret position\n// inside `text` text corresponding to the original `caret` position inside `value`.\n//\n// `formatter(value)` is a function returning `{ text, template }`.\n//\n// `text` is the `value` value formatted using `template`.\n// It may either cut off the non-filled right part of the `template`\n// or it may fill the non-filled character placeholders\n// in the right part of the `template` with `spacer`\n// which is a space (' ') character by default.\n//\n// `template` is the template used to format the `value`.\n// It can be either a full-length template or a partial template.\n//\n// `formatter` can also be a string — a `template`\n// where character placeholders are denoted by 'x'es.\n// In this case `formatter` function is automatically created.\n//\n// Example:\n//\n// `value` is '880',\n// `caret` is `2` (before the first `0`)\n//\n// `formatter` is `'880' =>\n// { text: '8 (80 )', template: 'x (xxx) xxx-xx-xx' }`\n//\n// The result is `{ text: '8 (80 )', caret: 4 }`.\n//\n\nexport default function format(value, caret, formatter) {\n if (typeof formatter === 'string') {\n formatter = template_formatter(formatter);\n }\n\n var _ref = formatter(value) || {},\n text = _ref.text,\n template = _ref.template;\n\n if (text === undefined) {\n text = value;\n }\n\n if (template) {\n if (caret === undefined) {\n caret = text.length;\n } else {\n var index = 0;\n var found = false;\n var possibly_last_input_character_index = -1;\n\n while (index < text.length && index < template.length) {\n // Character placeholder found\n if (text[index] !== template[index]) {\n if (caret === 0) {\n found = true;\n caret = index;\n break;\n }\n\n possibly_last_input_character_index = index;\n caret--;\n }\n\n index++;\n } // If the caret was positioned after last input character,\n // then the text caret index is just after the last input character.\n\n\n if (!found) {\n caret = possibly_last_input_character_index + 1;\n }\n }\n }\n\n return {\n text: text,\n caret: caret\n };\n}\n//# sourceMappingURL=format.js.map","// Gets selection bounds\nexport function getSelection(element) {\n // If no selection, return nothing\n if (element.selectionStart === element.selectionEnd) {\n return;\n }\n\n return {\n start: element.selectionStart,\n end: element.selectionEnd\n };\n} // Key codes\n\nexport var Keys = {\n Backspace: 8,\n Delete: 46\n}; // Finds out the operation to be intercepted and performed\n// based on the key down event `keyCode`.\n\nexport function getOperation(event) {\n switch (event.keyCode) {\n case Keys.Backspace:\n return 'Backspace';\n\n case Keys.Delete:\n return 'Delete';\n }\n} // Gets caret position\n\nexport function getCaretPosition(element) {\n return element.selectionStart;\n} // Sets caret position\n\nexport function setCaretPosition(element, caret_position) {\n // Sanity check\n if (caret_position === undefined) {\n return;\n } // Set caret position.\n // There has been an issue with caret positioning on Android devices.\n // https://github.com/catamphetamine/input-format/issues/2\n // I was revisiting this issue and looked for similar issues in other libraries.\n // For example, there's [`text-mask`](https://github.com/text-mask/text-mask) library.\n // They've had exactly the same issue when the caret seemingly refused to be repositioned programmatically.\n // The symptoms were the same: whenever the caret passed through a non-digit character of a mask (a whitespace, a bracket, a dash, etc), it looked as if it placed itself one character before its correct position.\n // https://github.com/text-mask/text-mask/issues/300\n // They seem to have found a basic fix for it: calling `input.setSelectionRange()` in a timeout rather than instantly for Android devices.\n // https://github.com/text-mask/text-mask/pull/400/files\n // I've implemented the same workaround here.\n\n\n if (isAndroid()) {\n setTimeout(function () {\n return element.setSelectionRange(caret_position, caret_position);\n }, 0);\n } else {\n element.setSelectionRange(caret_position, caret_position);\n }\n}\n\nfunction isAndroid() {\n // `navigator` is not defined when running mocha tests.\n if (typeof navigator !== 'undefined') {\n return ANDROID_USER_AGENT_REG_EXP.test(navigator.userAgent);\n }\n}\n\nvar ANDROID_USER_AGENT_REG_EXP = /Android/i;\n//# sourceMappingURL=dom.js.map","import edit from './edit';\nimport parse from './parse';\nimport format from './format';\nimport { getOperation, getSelection, getCaretPosition, setCaretPosition } from './dom';\nexport function onCut(event, input, _parse, _format, on_change) {\n // The actual cut hasn't happened just yet hence the timeout.\n setTimeout(function () {\n return format_input_text(input, _parse, _format, undefined, on_change);\n }, 0);\n}\nexport function onPaste(event, input, _parse, _format, on_change) {\n var selection = getSelection(input); // If selection is made,\n // just erase the selected text\n // prior to pasting\n\n if (selection) {\n erase_selection(input, selection);\n }\n\n format_input_text(input, _parse, _format, undefined, on_change);\n}\nexport function onChange(event, input, _parse, _format, on_change) {\n format_input_text(input, _parse, _format, undefined, on_change);\n} // Intercepts \"Delete\" and \"Backspace\" keys.\n// (hitting \"Delete\" or \"Backspace\" at any caret\n// position should always result in rasing a digit)\n\nexport function onKeyDown(event, input, _parse, _format, on_change) {\n var operation = getOperation(event);\n\n switch (operation) {\n case 'Delete':\n case 'Backspace':\n // Intercept this operation and perform it manually.\n event.preventDefault();\n var selection = getSelection(input); // If selection is made,\n // just erase the selected text,\n // and don't apply any more operations to it.\n\n if (selection) {\n erase_selection(input, selection);\n return format_input_text(input, _parse, _format, undefined, on_change);\n } // Else, perform the (character erasing) operation manually\n\n\n return format_input_text(input, _parse, _format, operation, on_change);\n\n default: // Will be handled when `onChange` fires.\n\n }\n}\n/**\r\n * Erases the selected text inside an ``.\r\n * @param {DOMElement} input\r\n * @param {Selection} selection\r\n */\n\nfunction erase_selection(input, selection) {\n var text = input.value;\n text = text.slice(0, selection.start) + text.slice(selection.end);\n input.value = text;\n setCaretPosition(input, selection.start);\n}\n/**\r\n * Parses and re-formats `` textual value.\r\n * E.g. when a user enters something into the ``\r\n * that raw input must first be parsed and the re-formatted properly.\r\n * Is called either after some user input (e.g. entered a character, pasted something)\r\n * or after the user performed an `operation` (e.g. \"Backspace\", \"Delete\").\r\n * @param {DOMElement} input\r\n * @param {Function} parse\r\n * @param {Function} format\r\n * @param {string} [operation] - The operation that triggered `` textual value change. E.g. \"Backspace\", \"Delete\".\r\n * @param {Function} onChange\r\n */\n\n\nfunction format_input_text(input, _parse, _format, operation, on_change) {\n // Parse `` textual value.\n // Get `value` and `caret` position.\n var _parse2 = parse(input.value, getCaretPosition(input), _parse),\n value = _parse2.value,\n caret = _parse2.caret; // If a user performed an operation (e.g. \"Backspace\", \"Delete\")\n // then apply that operation and get new `value` and `caret` position.\n\n\n if (operation) {\n var operation_applied = edit(value, caret, operation);\n value = operation_applied.value;\n caret = operation_applied.caret;\n } // Format the `value`.\n // (and reposition the caret accordingly)\n\n\n var formatted = format(value, caret, _format);\n var text = formatted.text;\n caret = formatted.caret; // Set `` textual value manually\n // to prevent React from resetting the caret position\n // later inside subsequent `render()`.\n // Doesn't work for custom `inputComponent`s for some reason.\n\n input.value = text; // Position the caret properly.\n\n setCaretPosition(input, caret); // `` textual value may have changed,\n // so the parsed `value` may have changed too.\n // The `value` didn't neccessarily change\n // but it might have.\n\n on_change(value);\n}\n//# sourceMappingURL=input control.js.map","// Edits text `value` (if `operation` is passed) and repositions the `caret` if needed.\n//\n// Example:\n//\n// value - '88005553535'\n// caret - 2 // starting from 0; is positioned before the first zero\n// operation - 'Backspace'\n//\n// Returns\n// {\n// \tvalue: '8005553535'\n// \tcaret: 1\n// }\n//\n// Currently supports just 'Delete' and 'Backspace' operations\n//\nexport default function edit(value, caret, operation) {\n switch (operation) {\n case 'Backspace':\n // If there exists the previous character,\n // then erase it and reposition the caret.\n if (caret > 0) {\n // Remove the previous character\n value = value.slice(0, caret - 1) + value.slice(caret); // Position the caret where the previous (erased) character was\n\n caret--;\n }\n\n break;\n\n case 'Delete':\n // Remove current digit (if any)\n value = value.slice(0, caret) + value.slice(caret + 1);\n break;\n }\n\n return {\n value: value,\n caret: caret\n };\n}\n//# sourceMappingURL=edit.js.map","import { count_occurences } from './helpers';\nexport default function (template, placeholder, parse) {\n if (typeof placeholder === 'function') {\n parse = placeholder;\n placeholder = 'x';\n }\n\n var max_characters = count_occurences(placeholder, template);\n return function (character, value) {\n if (value.length < max_characters) {\n return parse(character, value);\n }\n };\n}\n//# sourceMappingURL=template parser.js.map"],"names":["count_occurences","symbol","string","count","_iterator","split","_isArray","Array","isArray","_i","Symbol","iterator","_ref","length","next","done","value","close_braces","retained_template","template","placeholder","arguments","undefined","empty_placeholder","cut_before","opening_braces","closing_braces","dangling_braces","replace","should_close_braces","text","characters_in_template","value_character_index","filled_in_template","character","DIGITS","0","1","2","3","4","5","6","7","8","9","0","1","2","3","4","5","6","7","8","9","٠","١","٢","٣","٤","٥","٦","٧","٨","٩","۰","۱","۲","۳","۴","۵","۶","۷","۸","۹","parse","caret_position","parse_character","focused_input_character_index","index","caret","format","formatter","template_formatter","found","possibly_last_input_character_index","getSelection","element","selectionStart","selectionEnd","start","end","Keys","setCaretPosition","navigator","ANDROID_USER_AGENT_REG_EXP","test","userAgent","isAndroid","setSelectionRange","setTimeout","erase_selection","input","selection","slice","format_input_text","_parse","_format","operation","on_change","_parse2","operation_applied","edit","formatted","event","keyCode","getOperation","preventDefault","max_characters"],"mappings":"yMACO,SAASA,EAAiBC,EAAQC,GACvC,IAAIC,EAAQ,EAQHC,EAAYF,EAAOG,MAAM,IAAKC,EAAWC,MAAMC,QAAQJ,GAAYK,EAAK,EAAjF,IAAoFL,EAAYE,EAAWF,EAAYA,EAAUM,OAAOC,cAAe,CACrJ,IAAIC,EAEJ,GAAIN,EAAU,CACZ,GAAIG,GAAML,EAAUS,OAAQ,MAC5BD,EAAOR,EAAUK,SACZ,CAEL,IADAA,EAAKL,EAAUU,QACRC,KAAM,MACbH,EAAOH,EAAGO,MAGIJ,IAEEX,GAChBE,IAIJ,OAAOA,EC5BM,SAASc,EAAaC,EAAmBC,GAQtD,IAPA,IAAIC,EAAcC,UAAUR,OAAS,QAAsBS,IAAjBD,UAAU,GAAmBA,UAAU,GAAK,IAClFE,EAAoBF,UAAUR,OAAS,QAAsBS,IAAjBD,UAAU,GAAmBA,UAAU,GAAK,IACxFG,EAAaN,EAAkBL,OAC/BY,EAAiBzB,EAAiB,IAAKkB,GACvCQ,EAAiB1B,EAAiB,IAAKkB,GACvCS,EAAkBF,EAAiBC,EAEhCC,EAAkB,GAAKH,EAAaL,EAASN,QAClDK,GAAqBC,EAASK,GAAYI,QAAQR,EAAaG,GAElC,MAAzBJ,EAASK,IACXG,IAGFH,IAGF,OAAON,ECLM,WAAUC,GACvB,IAAIC,EAAcC,UAAUR,OAAS,QAAsBS,IAAjBD,UAAU,GAAmBA,UAAU,GAAK,IAClFQ,EAAsBR,UAAUR,OAAS,EAAIQ,UAAU,QAAKC,EAEhE,IAAKH,EACH,OAAO,SAAUH,GACf,MAAO,CACLc,KAAMd,IAKZ,IAAIe,EAAyB/B,EAAiBoB,EAAaD,GAC3D,OAAO,SAAUH,GACf,IAAKA,EACH,MAAO,CACLc,KAAM,GACNX,SAAUA,GAId,IAAIa,EAAwB,EACxBC,EAAqB,GAOhB7B,EAAYe,EAASd,MAAM,IAAKC,EAAWC,MAAMC,QAAQJ,GAAYK,EAAK,EAAnF,IAAsFL,EAAYE,EAAWF,EAAYA,EAAUM,OAAOC,cAAe,CACvJ,IAAIC,EAEJ,GAAIN,EAAU,CACZ,GAAIG,GAAML,EAAUS,OAAQ,MAC5BD,EAAOR,EAAUK,SACZ,CAEL,IADAA,EAAKL,EAAUU,QACRC,KAAM,MACbH,EAAOH,EAAGO,MAGZ,IAAIkB,EAAYtB,EAEhB,GAAIsB,IAAcd,GAWlB,GANAa,GAAsBjB,EAAMgB,KAC5BA,IAK8BhB,EAAMH,QAI9BG,EAAMH,OAASkB,EACjB,WAfFE,GAAsBC,EAwB1B,OAJIL,IACFI,EAAqBhB,EAAagB,EAAoBd,IAGjD,CACLW,KAAMG,EACNd,SAAUA,IC3ET,IAAIgB,EAAS,CAClBC,EAAK,IACLC,EAAK,IACLC,EAAK,IACLC,EAAK,IACLC,EAAK,IACLC,EAAK,IACLC,EAAK,IACLC,EAAK,IACLC,EAAK,IACLC,EAAK,IACLC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,IAEVC,IAAU,KC3DG,SAASC,EAAM9C,EAAM+C,EAAgBC,GAKlD,IAJA,IAAI9D,EAAQ,GACR+D,EAAgC,EAChCC,EAAQ,EAELA,EAAQlD,EAAKjB,QAAQ,CAC1B,IAAIqB,EAAY4C,EAAgBhD,EAAKkD,GAAQhE,QAE3BM,IAAdY,IACFlB,GAASkB,OAEcZ,IAAnBuD,IACEA,IAAmBG,EACrBD,EAAgC/D,EAAMH,OAAS,EACtCgE,EAAiBG,IAC1BD,EAAgC/D,EAAMH,UAK5CmE,IAaF,YATuB1D,IAAnBuD,IAEFE,EAAgC/D,EAAMH,QAG3B,CACXG,MAAOA,EACPiE,MAAOF,GCjBI,SAASG,EAAOlE,EAAOiE,EAAOE,GAClB,iBAAdA,IACTA,EAAYC,EAAmBD,IAGjC,IAAIvE,EAAOuE,EAAUnE,IAAU,GAC3Bc,EAAOlB,EAAKkB,KACZX,EAAWP,EAAKO,SAMpB,QAJaG,IAATQ,IACFA,EAAOd,GAGLG,EACF,QAAcG,IAAV2D,EACFA,EAAQnD,EAAKjB,WACR,CAKL,IAJA,IAAImE,EAAQ,EACRK,GAAQ,EACRC,GAAuC,EAEpCN,EAAQlD,EAAKjB,QAAUmE,EAAQ7D,EAASN,QAAQ,CAErD,GAAIiB,EAAKkD,KAAW7D,EAAS6D,GAAQ,CACnC,GAAc,IAAVC,EAAa,CACfI,GAAQ,EACRJ,EAAQD,EACR,MAGFM,EAAsCN,EACtCC,IAGFD,IAKGK,IACHJ,EAAQK,EAAsC,GAKpD,MAAO,CACLxD,KAAMA,EACNmD,MAAOA,GC/EJ,SAASM,EAAaC,GAE3B,GAAIA,EAAQC,iBAAmBD,EAAQE,aAIvC,MAAO,CACLC,MAAOH,EAAQC,eACfG,IAAKJ,EAAQE,cAIV,IAAIG,EACE,EADFA,EAED,GAkBH,SAASC,EAAiBN,EAASX,QAEjBvD,IAAnBuD,KAwBN,WAEE,GAAyB,oBAAdkB,UACT,OAAOC,EAA2BC,KAAKF,UAAUG,WAZ/CC,GAKFX,EAAQY,kBAAkBvB,EAAgBA,GAJ1CwB,YAAW,WACT,OAAOb,EAAQY,kBAAkBvB,EAAgBA,KAChD,IAaP,IAAImB,EAA6B,WCTjC,SAASM,EAAgBC,EAAOC,GAC9B,IAAI1E,EAAOyE,EAAMvF,MACjBc,EAAOA,EAAK2E,MAAM,EAAGD,EAAUb,OAAS7D,EAAK2E,MAAMD,EAAUZ,KAC7DW,EAAMvF,MAAQc,EACdgE,EAAiBS,EAAOC,EAAUb,OAgBpC,SAASe,EAAkBH,EAAOI,EAAQC,EAASC,EAAWC,GAG5D,IAAIC,EAAUnC,EAAM2B,EAAMvF,MAAwBuF,EDlDnCd,eCkD2CkB,GACtD3F,EAAQ+F,EAAQ/F,MAChBiE,EAAQ8B,EAAQ9B,MAIpB,GAAI4B,EAAW,CACb,IAAIG,ECvEO,SAAchG,EAAOiE,EAAO4B,GACzC,OAAQA,GACN,IAAK,YAGC5B,EAAQ,IAEVjE,EAAQA,EAAMyF,MAAM,EAAGxB,EAAQ,GAAKjE,EAAMyF,MAAMxB,GAEhDA,KAGF,MAEF,IAAK,SAEHjE,EAAQA,EAAMyF,MAAM,EAAGxB,GAASjE,EAAMyF,MAAMxB,EAAQ,GAIxD,MAAO,CACLjE,MAAOA,EACPiE,MAAOA,GDiDiBgC,CAAKjG,EAAOiE,EAAO4B,GAC3C7F,EAAQgG,EAAkBhG,MAC1BiE,EAAQ+B,EAAkB/B,MAK5B,IAAIiC,EAAYhC,EAAOlE,EAAOiE,EAAO2B,GACjC9E,EAAOoF,EAAUpF,KACrBmD,EAAQiC,EAAUjC,MAKlBsB,EAAMvF,MAAQc,EAEdgE,EAAiBS,EAAOtB,GAKxB6B,EAAU9F,yBAvFL,SAAkBmG,EAAOZ,EAAOI,EAAQC,EAASE,GACtDJ,EAAkBH,EAAOI,EAAQC,OAAStF,EAAWwF,YAlBhD,SAAeK,EAAOZ,EAAOI,EAAQC,EAASE,GAEnDT,YAAW,WACT,OAAOK,EAAkBH,EAAOI,EAAQC,OAAStF,EAAWwF,KAC3D,gBAmBE,SAAmBK,EAAOZ,EAAOI,EAAQC,EAASE,GACvD,IAAID,EDTC,SAAsBM,GAC3B,OAAQA,EAAMC,SACZ,KAAKvB,EACH,MAAO,YAET,KAAKA,EACH,MAAO,UCGKwB,CAAaF,GAE7B,OAAQN,GACN,IAAK,SACL,IAAK,YAEHM,EAAMG,iBACN,IAAId,EAAYjB,EAAagB,GAI7B,OAAIC,GACFF,EAAgBC,EAAOC,GAChBE,EAAkBH,EAAOI,EAAQC,OAAStF,EAAWwF,IAIvDJ,EAAkBH,EAAOI,EAAQC,EAASC,EAAWC,eAnC3D,SAAiBK,EAAOZ,EAAOI,EAAQC,EAASE,GACrD,IAAIN,EAAYjB,EAAagB,GAIzBC,GACFF,EAAgBC,EAAOC,GAGzBE,EAAkBH,EAAOI,EAAQC,OAAStF,EAAWwF,2BJ8DxC,SAAU5E,EAAWlB,GAClC,OAAOmB,EAAOD,2CMjFD,SAAUf,EAAUC,EAAawD,GACnB,mBAAhBxD,IACTwD,EAAQxD,EACRA,EAAc,KAGhB,IAAImG,EAAiBvH,EAAiBoB,EAAaD,GACnD,OAAO,SAAUe,EAAWlB,GAC1B,GAAIA,EAAMH,OAAS0G,EACjB,OAAO3C,EAAM1C,EAAWlB"}