├── .babelrc ├── .eslintignore ├── .eslintrc ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── dist ├── bundle.js └── bundle.js.map ├── docs ├── pin-secret.png └── pin.png ├── example └── index.js ├── index.html ├── package-lock.json ├── package.json ├── src ├── PinInput.jsx ├── PinItem.jsx └── index.js ├── test └── PinInput.spec.jsx ├── typings └── react-pin-input.d.ts └── webpack.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | "es2015", 4 | "react" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | test 2 | example -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "airbnb", 3 | "rules": { 4 | "jsx-quotes": [2, "prefer-single"], 5 | // "react/jsx-curly-spacing": [2, "always"], 6 | "react/prefer-stateless-function": [0] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.swp 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "node" 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Arun Ghosh 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # react-pin-input 2 | 3 | _There is [another package](https://github.com/40818419/react-code-input) for managing PIN input. Check and see which suits you better._ 4 | 5 | **React-PIN-Input is a React component o capture PIN/MPIN like input** 6 | 7 | ![alt tag](https://github.com/arunghosh/react-pin-input/raw/master/docs/pin.png) 8 | 9 | ## Demo 10 | https://codesandbox.io/s/8jnlxw359 11 | 12 | ## Installation 13 | ``` 14 | npm install react-pin-input --save 15 | ``` 16 | 17 | 18 | ## Usage 19 | 20 | The component takes in the length of the PIN and two callback to notifiy change and completion. The ```index``` is the input which is currently in focus. 21 | 22 | ```javascript 23 | import PinInput from 'react-pin-input'; 24 | 25 | {}} 31 | type="numeric" 32 | inputMode="numeric" 33 | style={{padding: '10px'}} 34 | inputStyle={{borderColor: 'red'}} 35 | inputFocusStyle={{borderColor: 'blue'}} 36 | onComplete={(value, index) => {}} 37 | autoSelect={true} 38 | regexCriteria={/^[ A-Za-z0-9_@./#&+-]*$/} 39 | /> 40 | ``` 41 | |Attribute|Type|Description| 42 | |:--|:--|:--| 43 | |length|number|Number of inputs| 44 | |initialValue|number\|string|Initial value of inputs| 45 | |type|string|Type of input allowed 46 | ||| if ```numeric```, the input will take only numbers| 47 | ||| if ```custom```, the input will take other than numbers| 48 | |secret|boolean|If you set the ```secret``` attibute, the input will be hidden as shown below. 49 | |secretDelay|number|If you set the ```secret``` attibute, then you can optionally add secretDelay ms to hide the inputs as you type. 50 | |disabled|boolean|If you set the ```disable``` attibute, the input will be disabled. 51 | |focus|boolean| Setting the ```focus``` attibute will set the default focus on the first input element. 52 | |onChange|function|Callback function invoked on input change. The first parameter is the value and the second is the index of the input that is currently in focus| 53 | |onComplete|function|Callback function invoked when all inputs have valid values. The first parameter is the value and the second is the index of the input that is currently in focus| 54 | |style|object|Style for the container `div` 55 | |inputStyle|object|Style for the input element 56 | |inputFocusStyle|object|Style for the input element when on focus 57 | |autoSelect|boolean|Setting ```autoSelect``` to ```false``` will stop automatically highlighting input values on focus. This eliminates popup focus flashing on iOS.| 58 | |regexCriteria|any|Add validation for ```alphanumeric``` type. *NOTE:* default value is /^[ A-Za-z0-9_@./#&+-]*$/ 59 | 60 | Display when secret is set 61 | ![alt tag](https://github.com/arunghosh/react-pin-input/raw/master/docs/pin-secret.png) 62 | 63 | 64 | ## Additional APIs 65 | 66 | ```javascript 67 | ele=n} /> 68 | ``` 69 | - ```ele.focus()``` to set focus on the first input element. 70 | - ```ele.clear``` to clear the values 71 | 72 | ## Custom Style 73 | 74 | You can update the style via following props 75 | - `style` 76 | - `inputStyle` 77 | - `inputFocusStyle` 78 | 79 | Or another option is to override the default style(shown below is scss. For css [refer](https://github.com/arunghosh/react-pin-input/issues/4) ). 80 | 81 | ```scss 82 | .pincode-input-container 83 | { 84 | .pincode-input-text 85 | { 86 | padding:0 !important; 87 | margin:0 2px; 88 | text-align:center; 89 | border: 1px solid; 90 | background: transparent; 91 | width: 50px; 92 | height: 50px; 93 | } 94 | .pincode-input-text:focus 95 | { 96 | outline:none; 97 | box-shadow:none; 98 | } 99 | } 100 | ``` 101 | 102 | 103 | ## For developers 104 | 105 | **New build** 106 | ``` 107 | npm run build 108 | ``` 109 | 110 | **Run dev server** 111 | ``` 112 | npm run dev 113 | ``` 114 | 115 | **Run test** 116 | ``` 117 | npm run test 118 | ``` 119 | 120 | Buy Me A Coffee 121 | -------------------------------------------------------------------------------- /dist/bundle.js: -------------------------------------------------------------------------------- 1 | !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports["react-pin-input"]=t():e["react-pin-input"]=t()}(this,(function(){return function(e){var t={};function n(r){if(t[r])return t[r].exports;var o=t[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(r,o,function(t){return e[t]}.bind(null,o));return r},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="/dist/",n(n.s=3)}([function(e,t,n){e.exports=n(5)()},function(e,t,n){"use strict";function r(e){return function(){return e}}var o=function(){};o.thatReturns=r,o.thatReturnsFalse=r(!1),o.thatReturnsTrue=r(!0),o.thatReturnsNull=r(null),o.thatReturnsThis=function(){return this},o.thatReturnsArgument=function(e){return e},e.exports=o},function(e,t,n){"use strict";e.exports=n(8)},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r,o=n(4),u=(r=o)&&r.__esModule?r:{default:r};t.default=u.default},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n0&&this.elements[e-1].focus()}},{key:"onPaste",value:function(e){var t=this.props.length;e.length===t&&this.elements.forEach((function(t,n){return t.update(e[n],!0)}))}},{key:"render",value:function(){var e=this;return i.default.createElement("div",{style:this.props.style,className:"pincode-input-container"},this.values.map((function(t,n){return i.default.createElement(a.default,{initialValue:t,ref:function(t){return e.elements[n]=t},key:n,disabled:e.props.disabled,onBackspace:function(){return e.onBackspace(n)},secret:e.props.secret||!1,onChange:function(t,r){return e.onItemChange(t,r,n)},type:e.props.type,inputMode:e.props.inputMode,validate:e.props.validate,inputStyle:e.props.inputStyle,inputFocusStyle:e.props.inputFocusStyle,autoSelect:e.props.autoSelect,onPaste:0===n?e.onPaste:null,regexCriteria:e.props.regexCriteria,ariaLabel:e.props.ariaLabel,placeholder:e.props.placeholder,secretDelay:e.props.secretDelay})})))}}]),t}(u.Component);s.propTypes={initialValue:o.default.oneOfType([o.default.string,o.default.number]),length:o.default.number.isRequired,type:o.default.string,onComplete:o.default.func,validate:o.default.func,secret:o.default.bool,disabled:o.default.bool,focus:o.default.bool,onChange:o.default.func,inputMode:o.default.string,style:o.default.object,inputStyle:o.default.object,inputFocusStyle:o.default.object,autoSelect:o.default.bool,regexCriteria:o.default.any,ariaLabel:o.default.string,placeholder:o.default.string},s.defaultProps={initialValue:"",type:"numeric",secret:!1,validate:null,focus:!1,disabled:!1,onChange:function(){},onComplete:function(){},inputMode:void 0,style:{},inputStyle:{},inputFocusStyle:{},autoSelect:!0,regexCriteria:/^[a-zA-Z0-9]+$/,ariaLabel:"",placeholder:""},t.default=s},function(e,t,n){"use strict";var r=n(1),o=n(6),u=n(7);e.exports=function(){function e(e,t,n,r,i,a){a!==u&&o(!1,"Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types")}function t(){return e}e.isRequired=e;var n={array:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t};return n.checkPropTypes=r,n.PropTypes=n,n}},function(e,t,n){"use strict";e.exports=function(e,t,n,r,o,u,i,a){if(!e){var l;if(void 0===t)l=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var s=[n,r,o,u,i,a],c=0;(l=new Error(t.replace(/%s/g,(function(){return s[c++]})))).name="Invariant Violation"}throw l.framesToPop=1,l}}},function(e,t,n){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},function(e,t,n){"use strict"; 2 | /** @license React v16.2.0 3 | * react.production.min.js 4 | * 5 | * Copyright (c) 2013-present, Facebook, Inc. 6 | * 7 | * This source code is licensed under the MIT license found in the 8 | * LICENSE file in the root directory of this source tree. 9 | */var r=n(9),o=n(10),u=n(1),i="function"==typeof Symbol&&Symbol.for,a=i?Symbol.for("react.element"):60103,l=i?Symbol.for("react.call"):60104,s=i?Symbol.for("react.return"):60105,c=i?Symbol.for("react.portal"):60106,f=i?Symbol.for("react.fragment"):60107,p="function"==typeof Symbol&&Symbol.iterator;function d(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,r=0;rx.length&&x.push(e)}function R(e,t,n,r){var o=typeof e;"undefined"!==o&&"boolean"!==o||(e=null);var u=!1;if(null===e)u=!0;else switch(o){case"string":case"number":u=!0;break;case"object":switch(e.$$typeof){case a:case l:case s:case c:u=!0}}if(u)return n(r,e,""===t?"."+E(e,0):t),1;if(u=0,t=""===t?".":t+":",Array.isArray(e))for(var i=0;i1&&void 0!==arguments[1]&&arguments[1],r=this.validate(e);(this.state.value!==r||n)&&r.length<2&&(this.setState({value:r}),this.inputTimeout=setTimeout((function(){t.props.onChange(r,n)}),0))}},{key:"onChange",value:function(e){this.update(e.target.value)}},{key:"focus",value:function(){this.input.focus()}},{key:"onFocus",value:function(e){this.props.autoSelect&&e.target.select(),this.setState({focus:!0})}},{key:"onBlur",value:function(){this.setState({focus:!1})}},{key:"onPaste",value:function(e){if(this.props.onPaste){var t=e.clipboardData.getData("text");this.props.onPaste(t)}}},{key:"validate",value:function(e){if(this.props.secretDelay&&this.setSecretDelayed(e),this.props.validate)return this.props.validate(e);if("numeric"===this.props.type){var t=e.charCodeAt(0);return t>="0".charCodeAt(0)&&t<="9".charCodeAt(0)?e:""}return this.props.regexCriteria.test(e)?e.toUpperCase():""}},{key:"render",value:function(){var e=this,t=this.state,n=t.focus,r=t.value,o=this.props,u=o.type,a=o.inputMode,c=o.inputStyle,f=o.inputFocusStyle,p="numeric"===u?"tel":u||"text";return i.default.createElement("input",{disabled:this.props.disabled?"disabled":void 0,className:"pincode-input-text",onChange:this.onChange,onKeyDown:this.onKeyDown,placeholder:this.props.placeholder?this.props.placeholder:r,"aria-label":this.props.ariaLabel?this.props.ariaLabel:r,maxLength:"1",autoComplete:"off",type:this.state.showSecret?"password":p,inputMode:a||"text",pattern:"numeric"===this.props.type?"[0-9]*":"^[a-zA-Z0-9]+$",ref:function(t){return e.input=t},onFocus:this.onFocus,onBlur:this.onBlur,onPaste:this.onPaste,style:Object.assign({},l,c,n?Object.assign({},s,f):{}),value:r})}}]),t}(u.Component);c.propTypes={initialValue:o.default.string,onChange:o.default.func.isRequired,onBackspace:o.default.func.isRequired,onPaste:o.default.func,secret:o.default.bool,secretDelay:o.default.number,disabled:o.default.bool,type:o.default.string,inputMode:o.default.string,validate:o.default.func,inputStyle:o.default.object.isRequired,inputFocusStyle:o.default.object.isRequired,autoSelect:o.default.bool,regexCriteria:o.default.any,ariaLabel:o.default.string,placeholder:o.default.string},c.defaultProps={secret:!1,type:"numeric",inputMode:void 0,disabled:!1,validate:void 0,autoSelect:!1,onPaste:void 0,regexCriteria:/^[a-zA-Z0-9]+$/,ariaLabel:"",placeholder:""},t.default=c}])})); 15 | //# sourceMappingURL=bundle.js.map -------------------------------------------------------------------------------- /dist/bundle.js.map: -------------------------------------------------------------------------------- 1 | {"version":3,"sources":["webpack://react-pin-input/webpack/universalModuleDefinition","webpack://react-pin-input/webpack/bootstrap","webpack://react-pin-input/./node_modules/prop-types/index.js","webpack://react-pin-input/./node_modules/fbjs/lib/emptyFunction.js","webpack://react-pin-input/./node_modules/react/index.js","webpack://react-pin-input/./src/index.js","webpack://react-pin-input/./src/PinInput.jsx","webpack://react-pin-input/./node_modules/prop-types/factoryWithThrowingShims.js","webpack://react-pin-input/./node_modules/fbjs/lib/invariant.js","webpack://react-pin-input/./node_modules/prop-types/lib/ReactPropTypesSecret.js","webpack://react-pin-input/./node_modules/react/cjs/react.production.min.js","webpack://react-pin-input/./node_modules/object-assign/index.js","webpack://react-pin-input/./node_modules/fbjs/lib/emptyObject.js","webpack://react-pin-input/./src/PinItem.jsx"],"names":["root","factory","exports","module","define","amd","this","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","makeEmptyFunction","arg","emptyFunction","thatReturns","thatReturnsFalse","thatReturnsTrue","thatReturnsNull","thatReturnsThis","thatReturnsArgument","PinInput","props","values","Array","length","fill","map","x","initialValue","toString","elements","currentIndex","onPaste","focus","forEach","e","clear","isPasting","index","onComplete","onChange","pin","join","el","update","style","className","ref","disabled","onBackspace","secret","v","onItemChange","type","inputMode","validate","inputStyle","inputFocusStyle","autoSelect","regexCriteria","ariaLabel","placeholder","secretDelay","Component","propTypes","PropTypes","oneOfType","string","number","isRequired","func","bool","any","defaultProps","undefined","invariant","ReactPropTypesSecret","shim","propName","componentName","location","propFullName","getShim","ReactPropTypes","array","symbol","arrayOf","element","instanceOf","node","objectOf","oneOf","shape","exact","checkPropTypes","condition","format","a","b","f","error","Error","args","argIndex","replace","framesToPop","q","u","w","iterator","y","arguments","encodeURIComponent","z","isMounted","enqueueForceUpdate","enqueueReplaceState","enqueueSetState","A","context","refs","updater","B","C","isReactComponent","setState","forceUpdate","D","E","constructor","isPureReactComponent","F","unstable_isAsyncReactComponent","render","children","G","current","H","I","__self","__source","J","g","k","h","$$typeof","_owner","K","L","M","N","pop","result","keyPrefix","count","O","push","P","Q","isArray","next","done","keys","escape","R","S","T","U","Children","toArray","only","PureComponent","unstable_AsyncComponent","Fragment","createElement","cloneElement","createFactory","isValidElement","version","__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED","ReactCurrentOwner","assign","V","freeze","default","W","getOwnPropertySymbols","propIsEnumerable","propertyIsEnumerable","toObject","val","TypeError","test1","String","getOwnPropertyNames","test2","fromCharCode","test3","split","letter","err","shouldUseNative","target","source","from","symbols","to","styles","padding","margin","textAlign","border","background","width","height","outline","boxShadow","PinItem","state","showSecret","onKeyDown","onFocus","onBlur","secretTimeout","inputTimeout","clearTimeout","keyCode","setTimeout","updatedValue","input","select","clipboardData","getData","setSecretDelayed","numCode","charCodeAt","test","toUpperCase","inputType","aria-label","maxLength","autoComplete","pattern"],"mappings":"CAAA,SAA2CA,EAAMC,GAC1B,iBAAZC,SAA0C,iBAAXC,OACxCA,OAAOD,QAAUD,IACQ,mBAAXG,QAAyBA,OAAOC,IAC9CD,OAAO,GAAIH,GACe,iBAAZC,QACdA,QAAQ,mBAAqBD,IAE7BD,EAAK,mBAAqBC,IAR5B,CASGK,MAAM,WACT,O,YCTE,IAAIC,EAAmB,GAGvB,SAASC,EAAoBC,GAG5B,GAAGF,EAAiBE,GACnB,OAAOF,EAAiBE,GAAUP,QAGnC,IAAIC,EAASI,EAAiBE,GAAY,CACzCC,EAAGD,EACHE,GAAG,EACHT,QAAS,IAUV,OANAU,EAAQH,GAAUI,KAAKV,EAAOD,QAASC,EAAQA,EAAOD,QAASM,GAG/DL,EAAOQ,GAAI,EAGJR,EAAOD,QA0Df,OArDAM,EAAoBM,EAAIF,EAGxBJ,EAAoBO,EAAIR,EAGxBC,EAAoBQ,EAAI,SAASd,EAASe,EAAMC,GAC3CV,EAAoBW,EAAEjB,EAASe,IAClCG,OAAOC,eAAenB,EAASe,EAAM,CAAEK,YAAY,EAAMC,IAAKL,KAKhEV,EAAoBgB,EAAI,SAAStB,GACX,oBAAXuB,QAA0BA,OAAOC,aAC1CN,OAAOC,eAAenB,EAASuB,OAAOC,YAAa,CAAEC,MAAO,WAE7DP,OAAOC,eAAenB,EAAS,aAAc,CAAEyB,OAAO,KAQvDnB,EAAoBoB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQnB,EAAoBmB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,iBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKX,OAAOY,OAAO,MAGvB,GAFAxB,EAAoBgB,EAAEO,GACtBX,OAAOC,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOnB,EAAoBQ,EAAEe,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,IAAQC,KAAK,KAAMD,IAC9I,OAAOF,GAIRvB,EAAoB2B,EAAI,SAAShC,GAChC,IAAIe,EAASf,GAAUA,EAAO2B,WAC7B,WAAwB,OAAO3B,EAAgB,SAC/C,WAA8B,OAAOA,GAEtC,OADAK,EAAoBQ,EAAEE,EAAQ,IAAKA,GAC5BA,GAIRV,EAAoBW,EAAI,SAASiB,EAAQC,GAAY,OAAOjB,OAAOkB,UAAUC,eAAe1B,KAAKuB,EAAQC,IAGzG7B,EAAoBgC,EAAI,SAIjBhC,EAAoBA,EAAoBiC,EAAI,G,kBCxDnDtC,EAAOD,QAAU,EAAQ,EAAR,I,6BCfnB,SAASwC,EAAkBC,GACzB,OAAO,WACL,OAAOA,GASX,IAAIC,EAAgB,aAEpBA,EAAcC,YAAcH,EAC5BE,EAAcE,iBAAmBJ,GAAkB,GACnDE,EAAcG,gBAAkBL,GAAkB,GAClDE,EAAcI,gBAAkBN,EAAkB,MAClDE,EAAcK,gBAAkB,WAC9B,OAAO3C,MAETsC,EAAcM,oBAAsB,SAAUP,GAC5C,OAAOA,GAGTxC,EAAOD,QAAU0C,G,6BChCfzC,EAAOD,QAAU,EAAQ,I,8ECH3B,I,EAAA,O,8CAEeiD,W,2UCFf,MACA,O,WACA,O,uDAIMA,E,YACJ,WAAYC,I,4FAAO,e,iKAAA,wDACXA,IADW,OAGjB,EAAKC,OAASC,MAAMF,EAAMG,QACvBC,KAAK,IACLC,KAAI,SAACC,EAAGhD,GAAJ,OAAU0C,EAAMO,aAAaC,WAAWlD,IAAM,MACrD,EAAKmD,SAAW,GAChB,EAAKC,aAAe,EAEpB,EAAKC,QAAU,EAAKA,QAAQ7B,KAAb,GATE,E,qXAcb5B,KAAK8C,MAAMY,OAAS1D,KAAK8C,MAAMG,QAAQjD,KAAKuD,SAAS,GAAGG,U,8BAI5D1D,KAAKuD,SAASI,SAAQ,SAAAC,GAAA,OAAKA,EAAEC,WAC7B7D,KAAK+C,OAAS/C,KAAK+C,OAAOI,KAAI,eAC9BnD,KAAKuD,SAAS,GAAGG,U,8BAIb1D,KAAK8C,MAAMG,QAAQjD,KAAKuD,SAAS,GAAGG,U,mCAK7BrC,EAAOyC,EAAWC,GAAO,MACK/D,KAAK8C,MAAtCG,EAD4B,EAC5BA,OAAQe,EADoB,EACpBA,WAAYC,EADQ,EACRA,SACxBT,EAAeO,EAEnB/D,KAAK+C,OAAOgB,GAAS1C,EAGA,IAAjBA,EAAM4B,QAAgBc,EAAQd,EAAS,IACzCO,GAAgB,EAChBxD,KAAKuD,SAASC,GAAcE,SAI9B,IAAMQ,EAAMlE,KAAK+C,OAAOoB,KAAK,IAM7B,GAJKL,GACHG,EAASC,EAAKV,GAGZU,EAAIjB,SAAWA,EAAQ,CAEzB,GAAIa,GAAaC,EAAQd,EAAS,EAChC,OAGFe,EAAWE,EAAKV,M,kCAIRO,GACNA,EAAQ,GACV/D,KAAKuD,SAASQ,EAAQ,GAAGL,U,8BAIrBrC,GAAO,IACL4B,EAAWjD,KAAK8C,MAAhBG,OACJ5B,EAAM4B,SAAWA,GAIrBjD,KAAKuD,SAASI,SAAQ,SAACS,EAAIL,GAAL,OAAeK,EAAGC,OAAOhD,EAAM0C,IAAQ,Q,+BAGtD,WACP,OACE,+BAAKO,MAAOtE,KAAK8C,MAAMwB,MAAOC,UAAU,2BACrCvE,KAAK+C,OAAOI,KAAI,SAACS,EAAGxD,GAAJ,OACf,wBAAC,UAAD,CACEiD,aAAcO,EACdY,IAAK,SAAA3C,GAAA,OAAM,EAAK0B,SAASnD,GAAKyB,GAC9BF,IAAKvB,EACLqE,SAAU,EAAK3B,MAAM2B,SACrBC,YAAa,kBAAM,EAAKA,YAAYtE,IACpCuE,OAAQ,EAAK7B,MAAM6B,SAAU,EAC7BV,SAAU,SAACW,EAAGd,GAAJ,OAAkB,EAAKe,aAAaD,EAAGd,EAAW1D,IAC5D0E,KAAM,EAAKhC,MAAMgC,KACjBC,UAAW,EAAKjC,MAAMiC,UACtBC,SAAU,EAAKlC,MAAMkC,SACrBC,WAAY,EAAKnC,MAAMmC,WACvBC,gBAAiB,EAAKpC,MAAMoC,gBAC5BC,WAAY,EAAKrC,MAAMqC,WACvB1B,QAAe,IAANrD,EAAU,EAAKqD,QAAU,KAClC2B,cAAe,EAAKtC,MAAMsC,cAC1BC,UAAW,EAAKvC,MAAMuC,UACtBC,YAAa,EAAKxC,MAAMwC,YACxBC,YAAa,EAAKzC,MAAMyC,sB,GAhGbC,aAwGvB3C,EAAS4C,UAAY,CACnBpC,aAAcqC,UAAUC,UAAU,CAACD,UAAUE,OAAQF,UAAUG,SAC/D5C,OAAQyC,UAAUG,OAAOC,WACzBhB,KAAMY,UAAUE,OAChB5B,WAAY0B,UAAUK,KACtBf,SAAUU,UAAUK,KACpBpB,OAAQe,UAAUM,KAClBvB,SAAUiB,UAAUM,KACpBtC,MAAOgC,UAAUM,KACjB/B,SAAUyB,UAAUK,KACpBhB,UAAWW,UAAUE,OACrBtB,MAAOoB,UAAU5D,OACjBmD,WAAYS,UAAU5D,OACtBoD,gBAAiBQ,UAAU5D,OAC3BqD,WAAYO,UAAUM,KACtBZ,cAAeM,UAAUO,IACzBZ,UAAWK,UAAUE,OACrBN,YAAaI,UAAUE,QAGzB/C,EAASqD,aAAe,CACtB7C,aAAc,GACdyB,KAAM,UACNH,QAAQ,EACRK,SAAU,KACVtB,OAAO,EACPe,UAAU,EACVR,SAAU,aACVD,WAAY,aACZe,eAAWoB,EACX7B,MAAO,GACPW,WAAY,GACZC,gBAAiB,GACjBC,YAAY,EACZC,cAAe,iBACfC,UAAW,GACXC,YAAa,I,UAGAzC,G,6BC5If,IAAIP,EAAgB,EAAQ,GACxB8D,EAAY,EAAQ,GACpBC,EAAuB,EAAQ,GAEnCxG,EAAOD,QAAU,WACf,SAAS0G,EAAKxD,EAAOyD,EAAUC,EAAeC,EAAUC,EAAc/B,GAChEA,IAAW0B,GAIfD,GACE,EACA,mLAMJ,SAASO,IACP,OAAOL,EAFTA,EAAKR,WAAaQ,EAMlB,IAAIM,EAAiB,CACnBC,MAAOP,EACPN,KAAMM,EACNP,KAAMO,EACNT,OAAQS,EACRxE,OAAQwE,EACRV,OAAQU,EACRQ,OAAQR,EAERL,IAAKK,EACLS,QAASJ,EACTK,QAASV,EACTW,WAAYN,EACZO,KAAMZ,EACNa,SAAUR,EACVS,MAAOT,EACPhB,UAAWgB,EACXU,MAAOV,EACPW,MAAOX,GAMT,OAHAC,EAAeW,eAAiBjF,EAChCsE,EAAelB,UAAYkB,EAEpBA,I,6BCJT/G,EAAOD,QArBP,SAAmB4H,EAAWC,EAAQC,EAAGC,EAAGlH,EAAGC,EAAGkD,EAAGgE,GAGnD,IAAKJ,EAAW,CACd,IAAIK,EACJ,QAAe1B,IAAXsB,EACFI,EAAQ,IAAIC,MAAM,qIACb,CACL,IAAIC,EAAO,CAACL,EAAGC,EAAGlH,EAAGC,EAAGkD,EAAGgE,GACvBI,EAAW,GACfH,EAAQ,IAAIC,MAAML,EAAOQ,QAAQ,OAAO,WACtC,OAAOF,EAAKC,UAERrH,KAAO,sBAIf,MADAkH,EAAMK,YAAc,EACdL,K,6BCrCVhI,EAAOD,QAFoB,gD;;;;;;;;GCAd,IAAIY,EAAE,EAAQ,GAAiBqB,EAAE,EAAQ,IAAwBK,EAAE,EAAQ,GAA0BiG,EAAE,mBAAoBhH,QAAQA,OAAY,IAAED,EAAEiH,EAAEhH,OAAY,IAAE,iBAAiB,MAAMG,EAAE6G,EAAEhH,OAAY,IAAE,cAAc,MAAMiH,EAAED,EAAEhH,OAAY,IAAE,gBAAgB,MAAMyD,EAAEuD,EAAEhH,OAAY,IAAE,gBAAgB,MAAMkH,EAAEF,EAAEhH,OAAY,IAAE,kBAAkB,MAAMiC,EAAE,mBAAoBjC,QAAQA,OAAOmH,SAC5Y,SAASC,EAAEb,GAAG,IAAI,IAAIC,EAAEa,UAAUvF,OAAO,EAAEW,EAAE,yBAAyB8D,EAAE,6EAAgFA,EAAEjH,EAAE,EAAEA,EAAEkH,EAAElH,IAAImD,GAAG,WAAiB6E,mBAAmBD,UAAU/H,EAAE,IAA6K,MAAzKkH,EAAEG,MAAMlE,EAAE,mHAAoHjD,KAAK,sBAAsBgH,EAAEO,YAAY,EAAQP,EAC5Y,IAAIe,EAAE,CAACC,UAAU,WAAW,OAAM,GAAIC,mBAAmB,aAAaC,oBAAoB,aAAaC,gBAAgB,cAAc,SAASC,EAAErB,EAAEC,EAAE/D,GAAG5D,KAAK8C,MAAM4E,EAAE1H,KAAKgJ,QAAQrB,EAAE3H,KAAKiJ,KAAKpH,EAAE7B,KAAKkJ,QAAQtF,GAAG8E,EAC/M,SAASS,EAAEzB,EAAEC,EAAE/D,GAAG5D,KAAK8C,MAAM4E,EAAE1H,KAAKgJ,QAAQrB,EAAE3H,KAAKiJ,KAAKpH,EAAE7B,KAAKkJ,QAAQtF,GAAG8E,EAAE,SAASU,KAD4HL,EAAE/G,UAAUqH,iBAAiB,GAAGN,EAAE/G,UAAUsH,SAAS,SAAS5B,EAAEC,GAAG,iBAAkBD,GAAG,mBAAoBA,GAAG,MAAMA,GAAEa,EAAE,MAAavI,KAAKkJ,QAAQJ,gBAAgB9I,KAAK0H,EAAEC,EAAE,aAAaoB,EAAE/G,UAAUuH,YAAY,SAAS7B,GAAG1H,KAAKkJ,QAAQN,mBAAmB5I,KAAK0H,EAAE,gBAC3X0B,EAAEpH,UAAU+G,EAAE/G,UAAU,IAAIwH,EAAEL,EAAEnH,UAAU,IAAIoH,EAA6D,SAASK,EAAE/B,EAAEC,EAAE/D,GAAG5D,KAAK8C,MAAM4E,EAAE1H,KAAKgJ,QAAQrB,EAAE3H,KAAKiJ,KAAKpH,EAAE7B,KAAKkJ,QAAQtF,GAAG8E,EAArIc,EAAEE,YAAYP,EAAE3I,EAAEgJ,EAAET,EAAE/G,WAAWwH,EAAEG,sBAAqB,EAA+E,IAAIC,EAAEH,EAAEzH,UAAU,IAAIoH,EAAEQ,EAAEF,YAAYD,EAAEjJ,EAAEoJ,EAAEb,EAAE/G,WAAW4H,EAAEC,gCAA+B,EAAGD,EAAEE,OAAO,WAAW,OAAO9J,KAAK8C,MAAMiH,UAAU,IAAIC,EAAE,CAACC,QAAQ,MAAMC,EAAEpJ,OAAOkB,UAAUC,eAAekI,EAAE,CAACxI,KAAI,EAAG6C,KAAI,EAAG4F,QAAO,EAAGC,UAAS,GACzf,SAASC,EAAE5C,EAAEC,EAAE/D,GAAG,IAAInD,EAAEC,EAAE,GAAG6J,EAAE,KAAKC,EAAE,KAAK,GAAG,MAAM7C,EAAE,IAAIlH,UAAK,IAASkH,EAAEnD,MAAMgG,EAAE7C,EAAEnD,UAAK,IAASmD,EAAEhG,MAAM4I,EAAE,GAAG5C,EAAEhG,KAAKgG,EAAEuC,EAAE3J,KAAKoH,EAAElH,KAAK0J,EAAElI,eAAexB,KAAKC,EAAED,GAAGkH,EAAElH,IAAI,IAAImH,EAAEY,UAAUvF,OAAO,EAAE,GAAG,IAAI2E,EAAElH,EAAEqJ,SAASnG,OAAO,GAAG,EAAEgE,EAAE,CAAC,IAAI,IAAI6C,EAAEzH,MAAM4E,GAAGvH,EAAE,EAAEA,EAAEuH,EAAEvH,IAAIoK,EAAEpK,GAAGmI,UAAUnI,EAAE,GAAGK,EAAEqJ,SAASU,EAAE,GAAG/C,GAAGA,EAAExB,aAAa,IAAIzF,KAAKmH,EAAEF,EAAExB,kBAAe,IAASxF,EAAED,KAAKC,EAAED,GAAGmH,EAAEnH,IAAI,MAAM,CAACiK,SAASxJ,EAAE4D,KAAK4C,EAAE/F,IAAI4I,EAAE/F,IAAIgG,EAAE1H,MAAMpC,EAAEiK,OAAOX,EAAEC,SAAS,SAASW,EAAElD,GAAG,MAAM,iBAAkBA,GAAG,OAAOA,GAAGA,EAAEgD,WAAWxJ,EAC7X,IAAI2J,EAAE,OAAOC,EAAE,GAAG,SAASC,EAAErD,EAAEC,EAAE/D,EAAEnD,GAAG,GAAGqK,EAAE7H,OAAO,CAAC,IAAIvC,EAAEoK,EAAEE,MAA8D,OAAxDtK,EAAEuK,OAAOvD,EAAEhH,EAAEwK,UAAUvD,EAAEjH,EAAEqF,KAAKnC,EAAElD,EAAEsI,QAAQvI,EAAEC,EAAEyK,MAAM,EAASzK,EAAE,MAAM,CAACuK,OAAOvD,EAAEwD,UAAUvD,EAAE5B,KAAKnC,EAAEoF,QAAQvI,EAAE0K,MAAM,GAAG,SAASC,EAAE1D,GAAGA,EAAEuD,OAAO,KAAKvD,EAAEwD,UAAU,KAAKxD,EAAE3B,KAAK,KAAK2B,EAAEsB,QAAQ,KAAKtB,EAAEyD,MAAM,EAAE,GAAGL,EAAE7H,QAAQ6H,EAAEO,KAAK3D,GAC/Y,SAAS4D,EAAE5D,EAAEC,EAAE/D,EAAEnD,GAAG,IAAIC,SAASgH,EAAK,cAAchH,GAAG,YAAYA,IAAEgH,EAAE,MAAK,IAAI6C,GAAE,EAAG,GAAG,OAAO7C,EAAE6C,GAAE,OAAQ,OAAO7J,GAAG,IAAK,SAAS,IAAK,SAAS6J,GAAE,EAAG,MAAM,IAAK,SAAS,OAAO7C,EAAEgD,UAAU,KAAKxJ,EAAE,KAAKI,EAAE,KAAK8G,EAAE,KAAKxD,EAAE2F,GAAE,GAAI,GAAGA,EAAE,OAAO3G,EAAEnD,EAAEiH,EAAE,KAAKC,EAAE,IAAI4D,EAAE7D,EAAE,GAAGC,GAAG,EAAyB,GAAvB4C,EAAE,EAAE5C,EAAE,KAAKA,EAAE,IAAIA,EAAE,IAAO3E,MAAMwI,QAAQ9D,GAAG,IAAI,IAAI8C,EAAE,EAAEA,EAAE9C,EAAEzE,OAAOuH,IAAI,CAAQ,IAAI5C,EAAED,EAAE4D,EAAf7K,EAAEgH,EAAE8C,GAAeA,GAAGD,GAAGe,EAAE5K,EAAEkH,EAAEhE,EAAEnD,QAAQ,GAAG,MAAOiH,EAA0BE,EAAE,KAAiCA,EAAE,mBAA7BA,EAAExE,GAAGsE,EAAEtE,IAAIsE,EAAE,eAAsCE,EAAE,KAAM,mBAAoBA,EAAE,IAAIF,EACzfE,EAAErH,KAAKmH,GAAG8C,EAAE,IAAI9J,EAAEgH,EAAE+D,QAAQC,MAA6BnB,GAAGe,EAA1B5K,EAAEA,EAAEW,MAAMuG,EAAED,EAAE4D,EAAE7K,EAAE8J,KAAc5G,EAAEnD,OAAO,WAAWC,GAAW6H,EAAE,KAAK,qBAAd3E,EAAE,GAAG8D,GAA+B,qBAAqB5G,OAAO6K,KAAKjE,GAAGvD,KAAK,MAAM,IAAIP,EAAE,IAAK,OAAO2G,EAAE,SAASgB,EAAE7D,EAAEC,GAAG,MAAM,iBAAkBD,GAAG,OAAOA,GAAG,MAAMA,EAAE/F,IAF9P,SAAgB+F,GAAG,IAAIC,EAAE,CAAC,IAAO,KAAQ,IAAI,MAAS,MAAM,KAAK,GAAGD,GAAGO,QAAQ,SAAQ,SAASP,GAAG,OAAOC,EAAED,MAEsJkE,CAAOlE,EAAE/F,KAAKgG,EAAErE,SAAS,IAAI,SAASuI,EAAEnE,EAAEC,GAAGD,EAAE3B,KAAKxF,KAAKmH,EAAEsB,QAAQrB,EAAED,EAAEyD,SACzU,SAASW,EAAEpE,EAAEC,EAAE/D,GAAG,IAAInD,EAAEiH,EAAEuD,OAAOvK,EAAEgH,EAAEwD,UAAUxD,EAAEA,EAAE3B,KAAKxF,KAAKmH,EAAEsB,QAAQrB,EAAED,EAAEyD,SAASnI,MAAMwI,QAAQ9D,GAAGqE,EAAErE,EAAEjH,EAAEmD,EAAE1B,EAAEU,qBAAqB,MAAM8E,IAAIkD,EAAElD,KAAKC,EAAEjH,IAAIgH,EAAE/F,KAAKgG,GAAGA,EAAEhG,MAAM+F,EAAE/F,IAAI,IAAI,GAAG+F,EAAE/F,KAAKsG,QAAQ4C,EAAE,OAAU,KAAKjH,EAAE8D,EAAE,CAACgD,SAASxJ,EAAE4D,KAAK4C,EAAE5C,KAAKnD,IAAIgG,EAAEnD,IAAIkD,EAAElD,IAAI1B,MAAM4E,EAAE5E,MAAM6H,OAAOjD,EAAEiD,SAASlK,EAAE4K,KAAK3D,IAAI,SAASqE,EAAErE,EAAEC,EAAE/D,EAAEnD,EAAEC,GAAG,IAAI6J,EAAE,GAAG,MAAM3G,IAAI2G,GAAG,GAAG3G,GAAGqE,QAAQ4C,EAAE,OAAU,KAAKlD,EAAEoD,EAAEpD,EAAE4C,EAAE9J,EAAEC,GAAG,MAAMgH,GAAG4D,EAAE5D,EAAE,GAAGoE,EAAEnE,GAAGyD,EAAEzD,GACha,IAAIqE,EAAE,CAACC,SAAS,CAAC9I,IAAI,SAASuE,EAAEC,EAAE/D,GAAG,GAAG,MAAM8D,EAAE,OAAOA,EAAE,IAAIjH,EAAE,GAAmB,OAAhBsL,EAAErE,EAAEjH,EAAE,KAAKkH,EAAE/D,GAAUnD,GAAGkD,QAAQ,SAAS+D,EAAEC,EAAE/D,GAAG,GAAG,MAAM8D,EAAE,OAAOA,EAAEC,EAAEoD,EAAE,KAAK,KAAKpD,EAAE/D,GAAG,MAAM8D,GAAG4D,EAAE5D,EAAE,GAAGmE,EAAElE,GAAGyD,EAAEzD,IAAIwD,MAAM,SAASzD,GAAG,OAAO,MAAMA,EAAE,EAAE4D,EAAE5D,EAAE,GAAGxF,EAAEQ,gBAAgB,OAAOwJ,QAAQ,SAASxE,GAAG,IAAIC,EAAE,GAAqC,OAAlCoE,EAAErE,EAAEC,EAAE,KAAKzF,EAAEU,qBAA4B+E,GAAGwE,KAAK,SAASzE,GAAwB,OAArBkD,EAAElD,IAAUa,EAAE,OAAcb,IAAIlC,UAAUuD,EAAEqD,cAAcjD,EAAEkD,wBAAwB5C,EAAE6C,SAASjE,EAAEkE,cAAcjC,EAAEkC,aAAa,SAAS9E,EAAEC,EAAE/D,GAAG,IAAInD,EAAED,EAAE,GAAGkH,EAAE5E,OAC9epC,EAAEgH,EAAE/F,IAAI4I,EAAE7C,EAAElD,IAAIgG,EAAE9C,EAAEiD,OAAO,GAAG,MAAMhD,EAAE,CAAoE,QAAnE,IAASA,EAAEnD,MAAM+F,EAAE5C,EAAEnD,IAAIgG,EAAER,EAAEC,cAAS,IAAStC,EAAEhG,MAAMjB,EAAE,GAAGiH,EAAEhG,KAAQ+F,EAAE5C,MAAM4C,EAAE5C,KAAKoB,aAAa,IAAI0B,EAAEF,EAAE5C,KAAKoB,aAAa,IAAIuE,KAAK9C,EAAEuC,EAAE3J,KAAKoH,EAAE8C,KAAKN,EAAElI,eAAewI,KAAKhK,EAAEgK,QAAG,IAAS9C,EAAE8C,SAAI,IAAS7C,EAAEA,EAAE6C,GAAG9C,EAAE8C,IAAI,IAAIA,EAAEjC,UAAUvF,OAAO,EAAE,GAAG,IAAIwH,EAAEhK,EAAEsJ,SAASnG,OAAO,GAAG,EAAE6G,EAAE,CAAC7C,EAAE5E,MAAMyH,GAAG,IAAI,IAAIpK,EAAE,EAAEA,EAAEoK,EAAEpK,IAAIuH,EAAEvH,GAAGmI,UAAUnI,EAAE,GAAGI,EAAEsJ,SAASnC,EAAE,MAAM,CAAC8C,SAASxJ,EAAE4D,KAAK4C,EAAE5C,KAAKnD,IAAIjB,EAAE8D,IAAI+F,EAAEzH,MAAMrC,EAAEkK,OAAOH,IAAIiC,cAAc,SAAS/E,GAAG,IAAIC,EAAE2C,EAAE1I,KAAK,KAAK8F,GAAY,OAATC,EAAE7C,KAAK4C,EAASC,GACpf+E,eAAe9B,EAAE+B,QAAQ,SAASC,mDAAmD,CAACC,kBAAkB7C,EAAE8C,OAAOtM,IAAIuM,EAAEjM,OAAOkM,OAAO,CAACC,QAAQjB,IAAIkB,EAAEH,GAAGf,GAAGe,EAAElN,EAAOD,QAAQsN,EAAW,QAAEA,EAAW,QAAEA,G;;;;;ECZrM,IAAIC,EAAwBrM,OAAOqM,sBAC/BlL,EAAiBnB,OAAOkB,UAAUC,eAClCmL,EAAmBtM,OAAOkB,UAAUqL,qBAExC,SAASC,EAASC,GACjB,GAAIA,QACH,MAAM,IAAIC,UAAU,yDAGrB,OAAO1M,OAAOyM,GA+Cf1N,EAAOD,QA5CP,WACC,IACC,IAAKkB,OAAOgM,OACX,OAAO,EAMR,IAAIW,EAAQ,IAAIC,OAAO,OAEvB,GADAD,EAAM,GAAK,KACkC,MAAzC3M,OAAO6M,oBAAoBF,GAAO,GACrC,OAAO,EAKR,IADA,IAAIG,EAAQ,GACHxN,EAAI,EAAGA,EAAI,GAAIA,IACvBwN,EAAM,IAAMF,OAAOG,aAAazN,IAAMA,EAKvC,GAAwB,eAHXU,OAAO6M,oBAAoBC,GAAOzK,KAAI,SAAUtB,GAC5D,OAAO+L,EAAM/L,MAEHsC,KAAK,IACf,OAAO,EAIR,IAAI2J,EAAQ,GAIZ,MAHA,uBAAuBC,MAAM,IAAIpK,SAAQ,SAAUqK,GAClDF,EAAME,GAAUA,KAGf,yBADElN,OAAO6K,KAAK7K,OAAOgM,OAAO,GAAIgB,IAAQ3J,KAAK,IAM9C,MAAO8J,GAER,OAAO,GAIQC,GAAoBpN,OAAOgM,OAAS,SAAUqB,EAAQC,GAKtE,IAJA,IAAIC,EAEAC,EADAC,EAAKjB,EAASa,GAGThM,EAAI,EAAGA,EAAIqG,UAAUvF,OAAQd,IAAK,CAG1C,IAAK,IAAIR,KAFT0M,EAAOvN,OAAO0H,UAAUrG,IAGnBF,EAAe1B,KAAK8N,EAAM1M,KAC7B4M,EAAG5M,GAAO0M,EAAK1M,IAIjB,GAAIwL,EAAuB,CAC1BmB,EAAUnB,EAAsBkB,GAChC,IAAK,IAAIjO,EAAI,EAAGA,EAAIkO,EAAQrL,OAAQ7C,IAC/BgN,EAAiB7M,KAAK8N,EAAMC,EAAQlO,MACvCmO,EAAGD,EAAQlO,IAAMiO,EAAKC,EAAQlO,MAMlC,OAAOmO,I,6BCxER1O,EAAOD,QANW,I,2UCVlB,MACA,O,0DAEA,IAAM4O,EACG,CACLC,QAAS,EACTC,OAAQ,QACRC,UAAW,SACXC,OAAQ,YACRC,WAAY,cACZC,MAAO,OACPC,OAAQ,QARNP,EAUQ,CACVQ,QAAS,OACTC,UAAW,QAMTC,E,YACJ,WAAYpM,I,4FAAO,e,iKAAA,wDACXA,IADW,OAEjB,EAAKqM,MAAQ,CACX9N,MAAO,EAAK2D,SAASlC,EAAMO,cAC3B+L,WAAY,EAAKtM,MAAM6B,OACvBjB,OAAO,GAET,EAAKO,SAAW,EAAKA,SAASrC,KAAd,GAChB,EAAKyN,UAAY,EAAKA,UAAUzN,KAAf,GACjB,EAAK0N,QAAU,EAAKA,QAAQ1N,KAAb,GACf,EAAK2N,OAAS,EAAKA,OAAO3N,KAAZ,GACd,EAAK6B,QAAU,EAAKA,QAAQ7B,KAAb,GACf,EAAK4N,cAAgB,KACrB,EAAKC,aAAe,KAbH,E,wXAiBjBC,aAAa1P,KAAKwP,eAClBE,aAAa1P,KAAKyP,gB,gCAGV7L,GACU,IAAdA,EAAE+L,SAAmB3P,KAAKmP,MAAM9N,OAAUrB,KAAKmP,MAAM9N,MAAM4B,QAC7DjD,KAAK8C,MAAM4B,gB,8BAKb1E,KAAKsJ,SAAS,CACZjI,MAAO,O,uCAIMA,GAAM,WACrBrB,KAAKsJ,SAAS,CAAE8F,YAAY,IAC5BpP,KAAKwP,cAAiBI,YAAW,WAC7B,EAAKtG,SAAS,CACZ8F,aAAY/N,MAEbrB,KAAK8C,MAAMyC,e,6BAGXsK,GAAiC,WAAnB/L,EAAmB,wDAChCzC,EAAQrB,KAAKgF,SAAS6K,IACxB7P,KAAKmP,MAAM9N,QAAUA,GAAUyC,IAE/BzC,EAAM4B,OAAS,IACjBjD,KAAKsJ,SAAS,CACZjI,UAGHrB,KAAKyP,aAAeG,YAAW,WAC5B,EAAK9M,MAAMmB,SAAS5C,EAAOyC,KAC1B,M,+BAIEF,GACP5D,KAAKqE,OAAOT,EAAEuK,OAAO9M,S,8BAIrBrB,KAAK8P,MAAMpM,U,8BAGLE,GACF5D,KAAK8C,MAAMqC,YACbvB,EAAEuK,OAAO4B,SAEX/P,KAAKsJ,SAAS,CAAE5F,OAAO,M,+BAIvB1D,KAAKsJ,SAAS,CAAE5F,OAAO,M,8BAGjBE,GACN,GAAK5D,KAAK8C,MAAMW,QAAhB,CAIA,IAAMpC,EAAQuC,EAAEoM,cAAcC,QAAQ,QACtCjQ,KAAK8C,MAAMW,QAAQpC,M,+BAGZA,GAGP,GAFGrB,KAAK8C,MAAMyC,aAAavF,KAAKkQ,iBAAiB7O,GAE7CrB,KAAK8C,MAAMkC,SACb,OAAOhF,KAAK8C,MAAMkC,SAAS3D,GAG7B,GAAwB,YAApBrB,KAAK8C,MAAMgC,KAAoB,CACjC,IAAMqL,EAAU9O,EAAM+O,WAAW,GAGjC,OADED,GAAW,IAAIC,WAAW,IAAMD,GAAW,IAAIC,WAAW,GACzC/O,EAAQ,GAE7B,OAAIrB,KAAK8C,MAAMsC,cAAciL,KAAKhP,GACzBA,EAAMiP,cAGR,K,+BAGA,aACkBtQ,KAAKmP,MAAtBzL,EADD,EACCA,MAAOrC,EADR,EACQA,MADR,EAEkDrB,KAAK8C,MAAtDgC,EAFD,EAECA,KAAMC,EAFP,EAEOA,UAAWE,EAFlB,EAEkBA,WAAYC,EAF9B,EAE8BA,gBAC/BqL,EAAqB,YAATzL,EAAqB,MAAQA,GAAQ,OACvD,OACE,iCACEL,SAAUzE,KAAK8C,MAAM2B,SAAW,gBAAa0B,EAC7C5B,UAAU,qBACVN,SAAUjE,KAAKiE,SACfoL,UAAWrP,KAAKqP,UAChB/J,YAAatF,KAAK8C,MAAMwC,YAActF,KAAK8C,MAAMwC,YAAcjE,EAC/DmP,aAAYxQ,KAAK8C,MAAMuC,UAAYrF,KAAK8C,MAAMuC,UAAYhE,EAC1DoP,UAAU,IACVC,aAAa,MACb5L,KAAM9E,KAAKmP,MAAMC,WAAa,WAAamB,EAC3CxL,UAAWA,GAAa,OACxB4L,QAA6B,YAApB3Q,KAAK8C,MAAMgC,KAAqB,SAAW,iBACpDN,IAAK,SAAA3C,GAAA,OAAM,EAAKiO,MAAQjO,GACxByN,QAAStP,KAAKsP,QACdC,OAAQvP,KAAKuP,OACb9L,QAASzD,KAAKyD,QACda,MAAOxD,OAAOgM,OACZ,GACA0B,EACAvJ,EACAvB,EAAQ5C,OAAOgM,OAAO,GAAI0B,EAAmBtJ,GAAmB,IAElE7D,MAAOA,Q,GArIOmE,aA2ItB0J,EAAQzJ,UAAY,CAClBpC,aAAcqC,UAAUE,OACxB3B,SAAUyB,UAAUK,KAAKD,WACzBpB,YAAagB,UAAUK,KAAKD,WAC5BrC,QAASiC,UAAUK,KACnBpB,OAAQe,UAAUM,KAClBT,YAAaG,UAAUG,OACvBpB,SAAUiB,UAAUM,KACpBlB,KAAMY,UAAUE,OAChBb,UAAWW,UAAUE,OACrBZ,SAAUU,UAAUK,KACpBd,WAAYS,UAAU5D,OAAOgE,WAC7BZ,gBAAiBQ,UAAU5D,OAAOgE,WAClCX,WAAYO,UAAUM,KACtBZ,cAAeM,UAAUO,IACzBZ,UAAWK,UAAUE,OACrBN,YAAaI,UAAUE,QAGzBsJ,EAAQhJ,aAAe,CACrBvB,QAAQ,EACRG,KAAM,UACNC,eAAWoB,EACX1B,UAAU,EACVO,cAAUmB,EACVhB,YAAY,EACZ1B,aAAS0C,EACTf,cAAe,iBACfC,UAAW,GACXC,YAAa,I,UAGA4J","file":"bundle.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[\"react-pin-input\"] = factory();\n\telse\n\t\troot[\"react-pin-input\"] = factory();\n})(this, 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 = \"/dist/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 3);\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\nif (process.env.NODE_ENV !== 'production') {\n var REACT_ELEMENT_TYPE = (typeof Symbol === 'function' &&\n Symbol.for &&\n Symbol.for('react.element')) ||\n 0xeac7;\n\n var isValidElement = function(object) {\n return typeof object === 'object' &&\n object !== null &&\n object.$$typeof === REACT_ELEMENT_TYPE;\n };\n\n // By explicitly using `prop-types` you are opting into new development behavior.\n // http://fb.me/prop-types-in-prod\n var throwOnDirectAccess = true;\n module.exports = require('./factoryWithTypeCheckers')(isValidElement, throwOnDirectAccess);\n} else {\n // By explicitly using `prop-types` you are opting into new production behavior.\n // http://fb.me/prop-types-in-prod\n module.exports = require('./factoryWithThrowingShims')();\n}\n","\"use strict\";\n\n/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n * \n */\n\nfunction makeEmptyFunction(arg) {\n return function () {\n return arg;\n };\n}\n\n/**\n * This function accepts and discards inputs; it has no side effects. This is\n * primarily useful idiomatically for overridable function endpoints which\n * always need to be callable, since JS lacks a null-call idiom ala Cocoa.\n */\nvar emptyFunction = function emptyFunction() {};\n\nemptyFunction.thatReturns = makeEmptyFunction;\nemptyFunction.thatReturnsFalse = makeEmptyFunction(false);\nemptyFunction.thatReturnsTrue = makeEmptyFunction(true);\nemptyFunction.thatReturnsNull = makeEmptyFunction(null);\nemptyFunction.thatReturnsThis = function () {\n return this;\n};\nemptyFunction.thatReturnsArgument = function (arg) {\n return arg;\n};\n\nmodule.exports = emptyFunction;","'use strict';\n\nif (process.env.NODE_ENV === 'production') {\n module.exports = require('./cjs/react.production.min.js');\n} else {\n module.exports = require('./cjs/react.development.js');\n}\n","import PinInput from './PinInput';\n\nexport default PinInput;\n","import PropTypes from 'prop-types';\nimport React, { Component } from 'react';\nimport PinItem from './PinItem';\n\n/**\n */\nclass PinInput extends Component {\n constructor(props) {\n super(props);\n \n this.values = Array(props.length)\n .fill('')\n .map((x, i) => props.initialValue.toString()[i] || '');\n this.elements = [];\n this.currentIndex = 0;\n\n this.onPaste = this.onPaste.bind(this);\n }\n\n componentDidMount() {\n // Setting focus on the first element\n if (this.props.focus && this.props.length) this.elements[0].focus();\n }\n\n clear() {\n this.elements.forEach(e => e.clear());\n this.values = this.values.map(() => undefined);\n this.elements[0].focus();\n }\n\n focus() {\n if (this.props.length) this.elements[0].focus();\n }\n\n /**\n */\n onItemChange(value, isPasting, index) {\n const { length, onComplete, onChange } = this.props;\n let currentIndex = index;\n\n this.values[index] = value;\n\n // Set focus on next\n if (value.length === 1 && index < length - 1) {\n currentIndex += 1;\n this.elements[currentIndex].focus();\n }\n\n // Notify the parent\n const pin = this.values.join('');\n\n if (!isPasting) {\n onChange(pin, currentIndex);\n }\n\n if (pin.length === length) {\n // for pasting, trigger onComplete only when the last input triggers onChange\n if (isPasting && index < length - 1) {\n return;\n }\n\n onComplete(pin, currentIndex);\n }\n }\n\n onBackspace(index) {\n if (index > 0) {\n this.elements[index - 1].focus();\n }\n }\n\n onPaste(value) {\n const { length } = this.props;\n if (value.length !== length) {\n return;\n }\n\n this.elements.forEach((el, index) => el.update(value[index], true));\n }\n\n render() {\n return (\n
\n {this.values.map((e, i) => (\n (this.elements[i] = n)}\n key={i}\n disabled={this.props.disabled}\n onBackspace={() => this.onBackspace(i)}\n secret={this.props.secret || false}\n onChange={(v, isPasting) => this.onItemChange(v, isPasting, i)}\n type={this.props.type}\n inputMode={this.props.inputMode}\n validate={this.props.validate}\n inputStyle={this.props.inputStyle}\n inputFocusStyle={this.props.inputFocusStyle}\n autoSelect={this.props.autoSelect}\n onPaste={i === 0 ? this.onPaste : null}\n regexCriteria={this.props.regexCriteria}\n ariaLabel={this.props.ariaLabel}\n placeholder={this.props.placeholder}\n secretDelay={this.props.secretDelay}\n />\n ))}\n
\n );\n }\n}\n\nPinInput.propTypes = {\n initialValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),\n length: PropTypes.number.isRequired,\n type: PropTypes.string,\n onComplete: PropTypes.func,\n validate: PropTypes.func,\n secret: PropTypes.bool,\n disabled: PropTypes.bool,\n focus: PropTypes.bool,\n onChange: PropTypes.func,\n inputMode: PropTypes.string,\n style: PropTypes.object, // eslint-disable-line react/forbid-prop-types\n inputStyle: PropTypes.object, // eslint-disable-line react/forbid-prop-types\n inputFocusStyle: PropTypes.object, // eslint-disable-line react/forbid-prop-types\n autoSelect: PropTypes.bool,\n regexCriteria: PropTypes.any,\n ariaLabel: PropTypes.string,\n placeholder: PropTypes.string,\n};\n\nPinInput.defaultProps = {\n initialValue: '',\n type: 'numeric',\n secret: false,\n validate: null,\n focus: false,\n disabled: false,\n onChange: () => {},\n onComplete: () => {},\n inputMode: undefined,\n style: {},\n inputStyle: {},\n inputFocusStyle: {},\n autoSelect: true,\n regexCriteria: /^[a-zA-Z0-9]+$/,\n ariaLabel: '',\n placeholder: ''\n};\n\nexport default PinInput;\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar emptyFunction = require('fbjs/lib/emptyFunction');\nvar invariant = require('fbjs/lib/invariant');\nvar ReactPropTypesSecret = require('./lib/ReactPropTypesSecret');\n\nmodule.exports = function() {\n function shim(props, propName, componentName, location, propFullName, secret) {\n if (secret === ReactPropTypesSecret) {\n // It is still safe when called from React.\n return;\n }\n invariant(\n false,\n 'Calling PropTypes validators directly is not supported by the `prop-types` package. ' +\n 'Use PropTypes.checkPropTypes() to call them. ' +\n 'Read more at http://fb.me/use-check-prop-types'\n );\n };\n shim.isRequired = shim;\n function getShim() {\n return shim;\n };\n // Important!\n // Keep this list in sync with production version in `./factoryWithTypeCheckers.js`.\n var ReactPropTypes = {\n array: shim,\n bool: shim,\n func: shim,\n number: shim,\n object: shim,\n string: shim,\n symbol: shim,\n\n any: shim,\n arrayOf: getShim,\n element: shim,\n instanceOf: getShim,\n node: shim,\n objectOf: getShim,\n oneOf: getShim,\n oneOfType: getShim,\n shape: getShim,\n exact: getShim\n };\n\n ReactPropTypes.checkPropTypes = emptyFunction;\n ReactPropTypes.PropTypes = ReactPropTypes;\n\n return ReactPropTypes;\n};\n","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n *\n */\n\n'use strict';\n\n/**\n * Use invariant() to assert state which your program assumes to be true.\n *\n * Provide sprintf-style format (only %s is supported) and arguments\n * to provide information about what broke and what you were\n * expecting.\n *\n * The invariant message will be stripped in production, but the invariant\n * will remain to ensure logic does not differ in production.\n */\n\nvar validateFormat = function validateFormat(format) {};\n\nif (process.env.NODE_ENV !== 'production') {\n validateFormat = function validateFormat(format) {\n if (format === undefined) {\n throw new Error('invariant requires an error message argument');\n }\n };\n}\n\nfunction invariant(condition, format, a, b, c, d, e, f) {\n validateFormat(format);\n\n if (!condition) {\n var error;\n if (format === undefined) {\n error = new Error('Minified exception occurred; use the non-minified dev environment ' + 'for the full error message and additional helpful warnings.');\n } else {\n var args = [a, b, c, d, e, f];\n var argIndex = 0;\n error = new Error(format.replace(/%s/g, function () {\n return args[argIndex++];\n }));\n error.name = 'Invariant Violation';\n }\n\n error.framesToPop = 1; // we don't care about invariant's own frame\n throw error;\n }\n}\n\nmodule.exports = invariant;","/**\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';\n\nvar ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED';\n\nmodule.exports = ReactPropTypesSecret;\n","/** @license React v16.2.0\n * react.production.min.js\n *\n * Copyright (c) 2013-present, Facebook, Inc.\n *\n * This source code is licensed under the MIT license found in the\n * LICENSE file in the root directory of this source tree.\n */\n\n'use strict';var m=require(\"object-assign\"),n=require(\"fbjs/lib/emptyObject\"),p=require(\"fbjs/lib/emptyFunction\"),q=\"function\"===typeof Symbol&&Symbol[\"for\"],r=q?Symbol[\"for\"](\"react.element\"):60103,t=q?Symbol[\"for\"](\"react.call\"):60104,u=q?Symbol[\"for\"](\"react.return\"):60105,v=q?Symbol[\"for\"](\"react.portal\"):60106,w=q?Symbol[\"for\"](\"react.fragment\"):60107,x=\"function\"===typeof Symbol&&Symbol.iterator;\nfunction y(a){for(var b=arguments.length-1,e=\"Minified React error #\"+a+\"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant\\x3d\"+a,c=0;cM.length&&M.push(a)}\nfunction P(a,b,e,c){var d=typeof a;if(\"undefined\"===d||\"boolean\"===d)a=null;var g=!1;if(null===a)g=!0;else switch(d){case \"string\":case \"number\":g=!0;break;case \"object\":switch(a.$$typeof){case r:case t:case u:case v:g=!0}}if(g)return e(c,a,\"\"===b?\".\"+Q(a,0):b),1;g=0;b=\"\"===b?\".\":b+\":\";if(Array.isArray(a))for(var k=0;k{\n this.setState({\n showSecret: value ? true : false,\n });\n } ,this.props.secretDelay);\n }\n\n update(updatedValue, isPasting = false) {\n const value = this.validate(updatedValue);\n if (this.state.value === value && !isPasting) return;\n\n if (value.length < 2) {\n this.setState({\n value,\n });\n\n this.inputTimeout = setTimeout(() => {\n this.props.onChange(value, isPasting);\n }, 0);\n } \n }\n\n onChange(e) {\n this.update(e.target.value);\n }\n\n focus() {\n this.input.focus();\n }\n\n onFocus(e) {\n if (this.props.autoSelect) {\n e.target.select();\n }\n this.setState({ focus: true });\n }\n\n onBlur() {\n this.setState({ focus: false });\n }\n\n onPaste(e) {\n if (!this.props.onPaste) {\n return;\n }\n\n const value = e.clipboardData.getData('text');\n this.props.onPaste(value);\n }\n\n validate(value) {\n if(this.props.secretDelay) this.setSecretDelayed(value)\n\n if (this.props.validate) {\n return this.props.validate(value);\n }\n\n if (this.props.type === 'numeric') {\n const numCode = value.charCodeAt(0);\n const isInteger =\n numCode >= '0'.charCodeAt(0) && numCode <= '9'.charCodeAt(0);\n return isInteger ? value : '';\n }\n if (this.props.regexCriteria.test(value)) {\n return value.toUpperCase();\n }\n\n return '';\n }\n\n render() {\n const { focus, value } = this.state;\n const { type, inputMode, inputStyle, inputFocusStyle } = this.props;\n const inputType = type === 'numeric' ? 'tel' : type || 'text';\n return (\n (this.input = n)}\n onFocus={this.onFocus}\n onBlur={this.onBlur}\n onPaste={this.onPaste}\n style={Object.assign(\n {},\n styles.input,\n inputStyle,\n focus ? Object.assign({}, styles.inputFocus, inputFocusStyle) : {},\n )}\n value={value}\n />\n );\n }\n}\n\nPinItem.propTypes = {\n initialValue: PropTypes.string,\n onChange: PropTypes.func.isRequired,\n onBackspace: PropTypes.func.isRequired,\n onPaste: PropTypes.func,\n secret: PropTypes.bool,\n secretDelay: PropTypes.number,\n disabled: PropTypes.bool,\n type: PropTypes.string,\n inputMode: PropTypes.string,\n validate: PropTypes.func,\n inputStyle: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types\n inputFocusStyle: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types\n autoSelect: PropTypes.bool,\n regexCriteria: PropTypes.any,\n ariaLabel: PropTypes.string,\n placeholder: PropTypes.string,\n};\n\nPinItem.defaultProps = {\n secret: false,\n type: 'numeric',\n inputMode: undefined,\n disabled: false,\n validate: undefined,\n autoSelect: false,\n onPaste: undefined,\n regexCriteria: /^[a-zA-Z0-9]+$/,\n ariaLabel: '',\n placeholder: ''\n};\n\nexport default PinItem;\n"],"sourceRoot":""} -------------------------------------------------------------------------------- /docs/pin-secret.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arunghosh/react-pin-input/24d41f78708e8b59322eb60d39bb1b3379dd0e35/docs/pin-secret.png -------------------------------------------------------------------------------- /docs/pin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arunghosh/react-pin-input/24d41f78708e8b59322eb60d39bb1b3379dd0e35/docs/pin.png -------------------------------------------------------------------------------- /example/index.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import ReactDOM from "react-dom"; 3 | import PinInput from "../src"; 4 | 5 | let pin; 6 | 7 | ReactDOM.render( 8 |
9 | (pin = p)} 16 | type="alphanumeric" 17 | onChange={v => console.log(v)} 18 | // onComplete={v => pin.clear(v)} 19 | /> 20 | 21 |
, 22 | document.getElementById("app") 23 | ); 24 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | Webpack React Library Starter 4 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-pin-input", 3 | "version": "1.3.1", 4 | "description": "React component for PIN like input", 5 | "main": "dist/bundle.js", 6 | "scripts": { 7 | "test": "jest", 8 | "dev": "NODE_ENV=dev webpack-dev-server", 9 | "build": "rimraf dist && eslint src && NODE_ENV=prod webpack" 10 | }, 11 | "author": "Arun Ghosh", 12 | "repository": { 13 | "type": "git", 14 | "url": "https://github.com/arunghosh/react-pin-input" 15 | }, 16 | "keywords": [ 17 | "pin", 18 | "input", 19 | "react", 20 | "component" 21 | ], 22 | "license": "MIT", 23 | "devDependencies": { 24 | "babel-core": "^6.26.3", 25 | "babel-jest": "^23.6.0", 26 | "babel-loader": "^7.1.5", 27 | "babel-preset-es2015": "^6.24.0", 28 | "babel-preset-react": "^6.23.0", 29 | "enzyme": "^3.7.0", 30 | "enzyme-adapter-react-16": "^1.7.0", 31 | "eslint": "^3.17.1", 32 | "eslint-config-airbnb": "^14.1.0", 33 | "eslint-plugin-import": "^2.2.0", 34 | "eslint-plugin-jsx-a11y": "^4.0.0", 35 | "eslint-plugin-react": "^6.10.0", 36 | "jest": "^23.6.0", 37 | "react": "^16.2.0", 38 | "react-addons-test-utils": "^15.4.2", 39 | "react-dom": "^16.2.0", 40 | "react-test-renderer": "^16.2.0", 41 | "rimraf": "^2.6.1", 42 | "webpack": "^4.42.1", 43 | "webpack-cli": "^3.3.12", 44 | "webpack-dev-server": "^3.10.3" 45 | }, 46 | "peerDependencies": { 47 | "prop-types": "^15.6.0", 48 | "react": "^0.14.0 || ^15.4.2 || ^16.2.0 || ^17.0.0 || ^18.0.0", 49 | "react-dom": "^0.14.0 || ^15.4.2 || ^16.2.0 || ^17.0.0 || ^18.0.0" 50 | }, 51 | "types": "./typings/react-pin-input.d.ts" 52 | } 53 | -------------------------------------------------------------------------------- /src/PinInput.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React, { Component } from 'react'; 3 | import PinItem from './PinItem'; 4 | 5 | /** 6 | */ 7 | class PinInput extends Component { 8 | constructor(props) { 9 | super(props); 10 | 11 | this.values = Array(props.length) 12 | .fill('') 13 | .map((x, i) => props.initialValue.toString()[i] || ''); 14 | this.elements = []; 15 | this.currentIndex = 0; 16 | 17 | this.onPaste = this.onPaste.bind(this); 18 | } 19 | 20 | componentDidMount() { 21 | // Setting focus on the first element 22 | if (this.props.focus && this.props.length) this.elements[0].focus(); 23 | } 24 | 25 | clear() { 26 | this.elements.forEach(e => e.clear()); 27 | this.values = this.values.map(() => undefined); 28 | this.elements[0].focus(); 29 | } 30 | 31 | focus() { 32 | if (this.props.length) this.elements[0].focus(); 33 | } 34 | 35 | /** 36 | */ 37 | onItemChange(value, isPasting, index) { 38 | const { length, onComplete, onChange } = this.props; 39 | let currentIndex = index; 40 | 41 | this.values[index] = value; 42 | 43 | // Set focus on next 44 | if (value.length === 1 && index < length - 1) { 45 | currentIndex += 1; 46 | this.elements[currentIndex].focus(); 47 | } 48 | 49 | // Notify the parent 50 | const pin = this.values.join(''); 51 | 52 | if (!isPasting) { 53 | onChange(pin, currentIndex); 54 | } 55 | 56 | if (pin.length === length) { 57 | // for pasting, trigger onComplete only when the last input triggers onChange 58 | if (isPasting && index < length - 1) { 59 | return; 60 | } 61 | 62 | onComplete(pin, currentIndex); 63 | } 64 | } 65 | 66 | onBackspace(index) { 67 | if (index > 0) { 68 | this.elements[index - 1].focus(); 69 | } 70 | } 71 | 72 | onPaste(value) { 73 | const { length } = this.props; 74 | if (value.length !== length) { 75 | return; 76 | } 77 | 78 | this.elements.forEach((el, index) => el.update(value[index], true)); 79 | } 80 | 81 | render() { 82 | return ( 83 |
84 | {this.values.map((e, i) => ( 85 | (this.elements[i] = n)} 88 | key={i} 89 | disabled={this.props.disabled} 90 | onBackspace={() => this.onBackspace(i)} 91 | secret={this.props.secret || false} 92 | onChange={(v, isPasting) => this.onItemChange(v, isPasting, i)} 93 | type={this.props.type} 94 | inputMode={this.props.inputMode} 95 | validate={this.props.validate} 96 | inputStyle={this.props.inputStyle} 97 | inputFocusStyle={this.props.inputFocusStyle} 98 | autoSelect={this.props.autoSelect} 99 | onPaste={i === 0 ? this.onPaste : null} 100 | regexCriteria={this.props.regexCriteria} 101 | ariaLabel={this.props.ariaLabel} 102 | placeholder={this.props.placeholder} 103 | secretDelay={this.props.secretDelay} 104 | /> 105 | ))} 106 |
107 | ); 108 | } 109 | } 110 | 111 | PinInput.propTypes = { 112 | initialValue: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), 113 | length: PropTypes.number.isRequired, 114 | type: PropTypes.string, 115 | onComplete: PropTypes.func, 116 | validate: PropTypes.func, 117 | secret: PropTypes.bool, 118 | disabled: PropTypes.bool, 119 | focus: PropTypes.bool, 120 | onChange: PropTypes.func, 121 | inputMode: PropTypes.string, 122 | style: PropTypes.object, // eslint-disable-line react/forbid-prop-types 123 | inputStyle: PropTypes.object, // eslint-disable-line react/forbid-prop-types 124 | inputFocusStyle: PropTypes.object, // eslint-disable-line react/forbid-prop-types 125 | autoSelect: PropTypes.bool, 126 | regexCriteria: PropTypes.any, 127 | ariaLabel: PropTypes.string, 128 | placeholder: PropTypes.string, 129 | }; 130 | 131 | PinInput.defaultProps = { 132 | initialValue: '', 133 | type: 'numeric', 134 | secret: false, 135 | validate: null, 136 | focus: false, 137 | disabled: false, 138 | onChange: () => {}, 139 | onComplete: () => {}, 140 | inputMode: undefined, 141 | style: {}, 142 | inputStyle: {}, 143 | inputFocusStyle: {}, 144 | autoSelect: true, 145 | regexCriteria: /^[a-zA-Z0-9]+$/, 146 | ariaLabel: '', 147 | placeholder: '' 148 | }; 149 | 150 | export default PinInput; 151 | -------------------------------------------------------------------------------- /src/PinItem.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React, { Component } from 'react'; 3 | 4 | const styles = { 5 | input: { 6 | padding: 0, 7 | margin: '0 2px', 8 | textAlign: 'center', 9 | border: '1px solid', 10 | background: 'transparent', 11 | width: '50px', 12 | height: '50px', 13 | }, 14 | inputFocus: { 15 | outline: 'none', 16 | boxShadow: 'none', 17 | }, 18 | }; 19 | 20 | /** 21 | */ 22 | class PinItem extends Component { 23 | constructor(props) { 24 | super(props); 25 | this.state = { 26 | value: this.validate(props.initialValue), 27 | showSecret: this.props.secret, 28 | focus: false, 29 | }; 30 | this.onChange = this.onChange.bind(this); 31 | this.onKeyDown = this.onKeyDown.bind(this); 32 | this.onFocus = this.onFocus.bind(this); 33 | this.onBlur = this.onBlur.bind(this); 34 | this.onPaste = this.onPaste.bind(this); 35 | this.secretTimeout = null; 36 | this.inputTimeout = null; 37 | } 38 | 39 | componentWillUnmount() { 40 | clearTimeout(this.secretTimeout); 41 | clearTimeout(this.inputTimeout) 42 | } 43 | 44 | onKeyDown(e) { 45 | if (e.keyCode === 8 && (!this.state.value || !this.state.value.length)) { 46 | this.props.onBackspace(); 47 | } 48 | } 49 | 50 | clear() { 51 | this.setState({ 52 | value: '', 53 | }); 54 | } 55 | 56 | setSecretDelayed(value){ 57 | this.setState({ showSecret: false }); 58 | this.secretTimeout = setTimeout(()=>{ 59 | this.setState({ 60 | showSecret: value ? true : false, 61 | }); 62 | } ,this.props.secretDelay); 63 | } 64 | 65 | update(updatedValue, isPasting = false) { 66 | const value = this.validate(updatedValue); 67 | if (this.state.value === value && !isPasting) return; 68 | 69 | if (value.length < 2) { 70 | this.setState({ 71 | value, 72 | }); 73 | 74 | this.inputTimeout = setTimeout(() => { 75 | this.props.onChange(value, isPasting); 76 | }, 0); 77 | } 78 | } 79 | 80 | onChange(e) { 81 | this.update(e.target.value); 82 | } 83 | 84 | focus() { 85 | this.input.focus(); 86 | } 87 | 88 | onFocus(e) { 89 | if (this.props.autoSelect) { 90 | e.target.select(); 91 | } 92 | this.setState({ focus: true }); 93 | } 94 | 95 | onBlur() { 96 | this.setState({ focus: false }); 97 | } 98 | 99 | onPaste(e) { 100 | if (!this.props.onPaste) { 101 | return; 102 | } 103 | 104 | const value = e.clipboardData.getData('text'); 105 | this.props.onPaste(value); 106 | } 107 | 108 | validate(value) { 109 | if(this.props.secretDelay) this.setSecretDelayed(value) 110 | 111 | if (this.props.validate) { 112 | return this.props.validate(value); 113 | } 114 | 115 | if (this.props.type === 'numeric') { 116 | const numCode = value.charCodeAt(0); 117 | const isInteger = 118 | numCode >= '0'.charCodeAt(0) && numCode <= '9'.charCodeAt(0); 119 | return isInteger ? value : ''; 120 | } 121 | if (this.props.regexCriteria.test(value)) { 122 | return value.toUpperCase(); 123 | } 124 | 125 | return ''; 126 | } 127 | 128 | render() { 129 | const { focus, value } = this.state; 130 | const { type, inputMode, inputStyle, inputFocusStyle } = this.props; 131 | const inputType = type === 'numeric' ? 'tel' : type || 'text'; 132 | return ( 133 | (this.input = n)} 146 | onFocus={this.onFocus} 147 | onBlur={this.onBlur} 148 | onPaste={this.onPaste} 149 | style={Object.assign( 150 | {}, 151 | styles.input, 152 | inputStyle, 153 | focus ? Object.assign({}, styles.inputFocus, inputFocusStyle) : {}, 154 | )} 155 | value={value} 156 | /> 157 | ); 158 | } 159 | } 160 | 161 | PinItem.propTypes = { 162 | initialValue: PropTypes.string, 163 | onChange: PropTypes.func.isRequired, 164 | onBackspace: PropTypes.func.isRequired, 165 | onPaste: PropTypes.func, 166 | secret: PropTypes.bool, 167 | secretDelay: PropTypes.number, 168 | disabled: PropTypes.bool, 169 | type: PropTypes.string, 170 | inputMode: PropTypes.string, 171 | validate: PropTypes.func, 172 | inputStyle: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types 173 | inputFocusStyle: PropTypes.object.isRequired, // eslint-disable-line react/forbid-prop-types 174 | autoSelect: PropTypes.bool, 175 | regexCriteria: PropTypes.any, 176 | ariaLabel: PropTypes.string, 177 | placeholder: PropTypes.string, 178 | }; 179 | 180 | PinItem.defaultProps = { 181 | secret: false, 182 | type: 'numeric', 183 | inputMode: undefined, 184 | disabled: false, 185 | validate: undefined, 186 | autoSelect: false, 187 | onPaste: undefined, 188 | regexCriteria: /^[a-zA-Z0-9]+$/, 189 | ariaLabel: '', 190 | placeholder: '' 191 | }; 192 | 193 | export default PinItem; 194 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import PinInput from './PinInput'; 2 | 3 | export default PinInput; 4 | -------------------------------------------------------------------------------- /test/PinInput.spec.jsx: -------------------------------------------------------------------------------- 1 | import { configure, mount, shallow } from 'enzyme'; 2 | import Adapter from 'enzyme-adapter-react-16'; 3 | import React from 'react'; 4 | import PinInput from '../src/PinInput'; 5 | import PinItem from '../src/PinItem'; 6 | 7 | configure({ adapter: new Adapter() }); 8 | 9 | 10 | test('The inputs should be equal to the length specified', () => { 11 | const pinInput = shallow(); 12 | expect(pinInput.find(PinItem)).toHaveLength(5); 13 | }); 14 | 15 | test('The inputs should be styled via inputStyle prop', () => { 16 | const pinInput = mount(); 17 | expect(pinInput.find('input').first().props().style.color).toEqual('red'); 18 | }); 19 | 20 | test('The inputs should be render with initial value', () => { 21 | const initialValue = '76239'; 22 | const pinInput = mount(); 23 | expect(pinInput.find('input').map(el => el.instance().value).join('')).toEqual(initialValue); 24 | }); 25 | 26 | test('The inputs should not allow special characters', () => { 27 | const initialValue = '^%#$@'; 28 | const pinInput = mount(); 29 | expect(pinInput.find('input').map(el => el.instance().value).join('')).toEqual(''); 30 | }) 31 | 32 | test('The inputs should allow special characters', () => { 33 | const initialValue = '%#$@'; 34 | const pinInput = mount(); 36 | expect(pinInput.find('input').map(el => el.instance().value).join('')).toEqual(initialValue); 37 | }) -------------------------------------------------------------------------------- /typings/react-pin-input.d.ts: -------------------------------------------------------------------------------- 1 | declare module "react-pin-input" { 2 | import * as React from "react"; 3 | 4 | type InputType = "numeric" | "custom"; 5 | 6 | interface PinInputProps { 7 | length: number; 8 | initialValue?: number | string; 9 | type?: InputType; 10 | inputMode?: string; 11 | secret?: boolean; 12 | secretDelay?: number; 13 | disabled?: boolean; 14 | focus?: boolean; 15 | onChange?: (value: string, index: number) => void; 16 | onComplete?: (value: string, index: number) => void; 17 | style?: React.CSSProperties; 18 | inputStyle?: React.CSSProperties; 19 | inputFocusStyle?: React.CSSProperties; 20 | validate?: (value: string) => string; 21 | autoSelect?: boolean; 22 | regexCriteria?: any; 23 | ariaLabel?: string 24 | placeholder?: string 25 | } 26 | 27 | class PinInput extends React.Component { 28 | clear: () => void; 29 | focus: () => void; 30 | } 31 | 32 | export default PinInput; 33 | } 34 | -------------------------------------------------------------------------------- /webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | let entry = './src/index.js'; 4 | let output = { 5 | path: path.join(__dirname, 'dist'), 6 | publicPath: '/dist/', 7 | }; 8 | 9 | if (process.env.NODE_ENV === 'dev') { 10 | entry = './example/index.js'; 11 | output = { 12 | path: path.join(__dirname, 'example'), 13 | publicPath: '/example/', 14 | }; 15 | } 16 | 17 | module.exports = { 18 | entry, 19 | output: Object.assign(output, { 20 | filename: 'bundle.js', 21 | globalObject: "this", 22 | library: 'react-pin-input', 23 | libraryTarget: 'umd', // universal module definition 24 | }), 25 | devtool: 'source-map', 26 | resolve: { 27 | extensions: ['.js', '.jsx'], 28 | }, 29 | module: { 30 | rules: [ 31 | { 32 | test: /\.jsx?$/, 33 | exclude: /node_modules/, 34 | loaders: ['babel-loader'], 35 | }, 36 | ], 37 | }, 38 | }; 39 | --------------------------------------------------------------------------------