valdatr 13.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (222) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +273 -0
  3. package/es/index.js +211 -0
  4. package/es/lib/alpha.js +137 -0
  5. package/es/lib/blacklist.js +5 -0
  6. package/es/lib/contains.js +15 -0
  7. package/es/lib/equals.js +5 -0
  8. package/es/lib/escape.js +5 -0
  9. package/es/lib/isAbaRouting.js +15 -0
  10. package/es/lib/isAfter.js +9 -0
  11. package/es/lib/isAlpha.js +23 -0
  12. package/es/lib/isAlphanumeric.js +23 -0
  13. package/es/lib/isAscii.js +10 -0
  14. package/es/lib/isBIC.js +16 -0
  15. package/es/lib/isBase32.js +19 -0
  16. package/es/lib/isBase58.js +11 -0
  17. package/es/lib/isBase64.js +20 -0
  18. package/es/lib/isBefore.js +9 -0
  19. package/es/lib/isBoolean.js +14 -0
  20. package/es/lib/isBtcAddress.js +7 -0
  21. package/es/lib/isByteLength.js +19 -0
  22. package/es/lib/isCreditCard.js +43 -0
  23. package/es/lib/isCurrency.js +74 -0
  24. package/es/lib/isDataURI.js +31 -0
  25. package/es/lib/isDate.js +92 -0
  26. package/es/lib/isDecimal.js +22 -0
  27. package/es/lib/isDivisibleBy.js +6 -0
  28. package/es/lib/isEAN.js +70 -0
  29. package/es/lib/isEmail.js +164 -0
  30. package/es/lib/isEmpty.js +10 -0
  31. package/es/lib/isEthereumAddress.js +6 -0
  32. package/es/lib/isFQDN.js +67 -0
  33. package/es/lib/isFloat.js +13 -0
  34. package/es/lib/isFullWidth.js +6 -0
  35. package/es/lib/isHSL.js +13 -0
  36. package/es/lib/isHalfWidth.js +6 -0
  37. package/es/lib/isHash.js +21 -0
  38. package/es/lib/isHexColor.js +6 -0
  39. package/es/lib/isHexadecimal.js +6 -0
  40. package/es/lib/isIBAN.js +173 -0
  41. package/es/lib/isIMEI.js +40 -0
  42. package/es/lib/isIP.js +50 -0
  43. package/es/lib/isIPRange.js +41 -0
  44. package/es/lib/isISBN.js +47 -0
  45. package/es/lib/isISIN.js +55 -0
  46. package/es/lib/isISO31661Alpha2.js +9 -0
  47. package/es/lib/isISO31661Alpha3.js +8 -0
  48. package/es/lib/isISO4217.js +9 -0
  49. package/es/lib/isISO6346.js +27 -0
  50. package/es/lib/isISO6391.js +6 -0
  51. package/es/lib/isISO8601.js +42 -0
  52. package/es/lib/isISRC.js +8 -0
  53. package/es/lib/isISSN.js +19 -0
  54. package/es/lib/isIdentityCard.js +406 -0
  55. package/es/lib/isIn.js +23 -0
  56. package/es/lib/isInt.js +18 -0
  57. package/es/lib/isJSON.js +19 -0
  58. package/es/lib/isJWT.js +15 -0
  59. package/es/lib/isLatLong.js +20 -0
  60. package/es/lib/isLength.js +21 -0
  61. package/es/lib/isLicensePlate.js +55 -0
  62. package/es/lib/isLocale.js +107 -0
  63. package/es/lib/isLowercase.js +5 -0
  64. package/es/lib/isLuhnNumber.js +25 -0
  65. package/es/lib/isMACAddress.js +36 -0
  66. package/es/lib/isMD5.js +6 -0
  67. package/es/lib/isMagnetURI.js +9 -0
  68. package/es/lib/isMailtoURI.js +75 -0
  69. package/es/lib/isMimeType.js +40 -0
  70. package/es/lib/isMobilePhone.js +208 -0
  71. package/es/lib/isMongoId.js +6 -0
  72. package/es/lib/isMultibyte.js +10 -0
  73. package/es/lib/isNumeric.js +10 -0
  74. package/es/lib/isOctal.js +6 -0
  75. package/es/lib/isPassportNumber.js +144 -0
  76. package/es/lib/isPort.js +8 -0
  77. package/es/lib/isPostalCode.js +95 -0
  78. package/es/lib/isRFC3339.js +21 -0
  79. package/es/lib/isRgbColor.js +13 -0
  80. package/es/lib/isSemVer.js +14 -0
  81. package/es/lib/isSlug.js +6 -0
  82. package/es/lib/isStrongPassword.js +90 -0
  83. package/es/lib/isSurrogatePair.js +6 -0
  84. package/es/lib/isTaxID.js +1388 -0
  85. package/es/lib/isTime.js +20 -0
  86. package/es/lib/isURL.js +155 -0
  87. package/es/lib/isUUID.js +15 -0
  88. package/es/lib/isUppercase.js +5 -0
  89. package/es/lib/isVAT.js +264 -0
  90. package/es/lib/isVariableWidth.js +7 -0
  91. package/es/lib/isWhitelisted.js +10 -0
  92. package/es/lib/ltrim.js +7 -0
  93. package/es/lib/matches.js +8 -0
  94. package/es/lib/normalizeEmail.js +129 -0
  95. package/es/lib/rtrim.js +15 -0
  96. package/es/lib/stripLow.js +7 -0
  97. package/es/lib/toBoolean.js +8 -0
  98. package/es/lib/toDate.js +6 -0
  99. package/es/lib/toFloat.js +5 -0
  100. package/es/lib/toInt.js +5 -0
  101. package/es/lib/trim.js +5 -0
  102. package/es/lib/unescape.js +8 -0
  103. package/es/lib/util/algorithms.js +79 -0
  104. package/es/lib/util/assertString.js +9 -0
  105. package/es/lib/util/includes.js +6 -0
  106. package/es/lib/util/merge.js +10 -0
  107. package/es/lib/util/multilineRegex.js +12 -0
  108. package/es/lib/util/toString.js +13 -0
  109. package/es/lib/util/typeOf.js +10 -0
  110. package/es/lib/whitelist.js +5 -0
  111. package/index.js +223 -0
  112. package/lib/alpha.js +143 -0
  113. package/lib/blacklist.js +14 -0
  114. package/lib/contains.js +24 -0
  115. package/lib/equals.js +14 -0
  116. package/lib/escape.js +14 -0
  117. package/lib/isAbaRouting.js +23 -0
  118. package/lib/isAfter.js +18 -0
  119. package/lib/isAlpha.js +31 -0
  120. package/lib/isAlphanumeric.js +31 -0
  121. package/lib/isAscii.js +18 -0
  122. package/lib/isBIC.js +24 -0
  123. package/lib/isBase32.js +28 -0
  124. package/lib/isBase58.js +19 -0
  125. package/lib/isBase64.js +29 -0
  126. package/lib/isBefore.js +18 -0
  127. package/lib/isBoolean.js +23 -0
  128. package/lib/isBtcAddress.js +16 -0
  129. package/lib/isByteLength.js +27 -0
  130. package/lib/isCreditCard.js +52 -0
  131. package/lib/isCurrency.js +83 -0
  132. package/lib/isDataURI.js +40 -0
  133. package/lib/isDate.js +101 -0
  134. package/lib/isDecimal.js +31 -0
  135. package/lib/isDivisibleBy.js +15 -0
  136. package/lib/isEAN.js +78 -0
  137. package/lib/isEmail.js +173 -0
  138. package/lib/isEmpty.js +19 -0
  139. package/lib/isEthereumAddress.js +15 -0
  140. package/lib/isFQDN.js +76 -0
  141. package/lib/isFloat.js +21 -0
  142. package/lib/isFullWidth.js +14 -0
  143. package/lib/isHSL.js +22 -0
  144. package/lib/isHalfWidth.js +14 -0
  145. package/lib/isHash.js +30 -0
  146. package/lib/isHexColor.js +15 -0
  147. package/lib/isHexadecimal.js +15 -0
  148. package/lib/isIBAN.js +180 -0
  149. package/lib/isIMEI.js +49 -0
  150. package/lib/isIP.js +59 -0
  151. package/lib/isIPRange.js +50 -0
  152. package/lib/isISBN.js +56 -0
  153. package/lib/isISIN.js +64 -0
  154. package/lib/isISO31661Alpha2.js +16 -0
  155. package/lib/isISO31661Alpha3.js +16 -0
  156. package/lib/isISO4217.js +16 -0
  157. package/lib/isISO6346.js +34 -0
  158. package/lib/isISO6391.js +15 -0
  159. package/lib/isISO8601.js +50 -0
  160. package/lib/isISRC.js +16 -0
  161. package/lib/isISSN.js +28 -0
  162. package/lib/isIdentityCard.js +415 -0
  163. package/lib/isIn.js +32 -0
  164. package/lib/isInt.js +27 -0
  165. package/lib/isJSON.js +28 -0
  166. package/lib/isJWT.js +24 -0
  167. package/lib/isLatLong.js +29 -0
  168. package/lib/isLength.js +29 -0
  169. package/lib/isLicensePlate.js +64 -0
  170. package/lib/isLocale.js +115 -0
  171. package/lib/isLowercase.js +14 -0
  172. package/lib/isLuhnNumber.js +34 -0
  173. package/lib/isMACAddress.js +45 -0
  174. package/lib/isMD5.js +15 -0
  175. package/lib/isMagnetURI.js +18 -0
  176. package/lib/isMailtoURI.js +84 -0
  177. package/lib/isMimeType.js +48 -0
  178. package/lib/isMobilePhone.js +215 -0
  179. package/lib/isMongoId.js +15 -0
  180. package/lib/isMultibyte.js +18 -0
  181. package/lib/isNumeric.js +19 -0
  182. package/lib/isOctal.js +15 -0
  183. package/lib/isPassportNumber.js +152 -0
  184. package/lib/isPort.js +17 -0
  185. package/lib/isPostalCode.js +102 -0
  186. package/lib/isRFC3339.js +29 -0
  187. package/lib/isRgbColor.js +22 -0
  188. package/lib/isSemVer.js +22 -0
  189. package/lib/isSlug.js +15 -0
  190. package/lib/isStrongPassword.js +99 -0
  191. package/lib/isSurrogatePair.js +15 -0
  192. package/lib/isTaxID.js +1399 -0
  193. package/lib/isTime.js +29 -0
  194. package/lib/isURL.js +163 -0
  195. package/lib/isUUID.js +24 -0
  196. package/lib/isUppercase.js +14 -0
  197. package/lib/isVAT.js +275 -0
  198. package/lib/isVariableWidth.js +16 -0
  199. package/lib/isWhitelisted.js +19 -0
  200. package/lib/ltrim.js +16 -0
  201. package/lib/matches.js +17 -0
  202. package/lib/normalizeEmail.js +138 -0
  203. package/lib/rtrim.js +24 -0
  204. package/lib/stripLow.js +16 -0
  205. package/lib/toBoolean.js +17 -0
  206. package/lib/toDate.js +15 -0
  207. package/lib/toFloat.js +14 -0
  208. package/lib/toInt.js +14 -0
  209. package/lib/trim.js +14 -0
  210. package/lib/unescape.js +17 -0
  211. package/lib/util/algorithms.js +88 -0
  212. package/lib/util/assertString.js +17 -0
  213. package/lib/util/includes.js +14 -0
  214. package/lib/util/merge.js +18 -0
  215. package/lib/util/multilineRegex.js +20 -0
  216. package/lib/util/toString.js +21 -0
  217. package/lib/util/typeOf.js +18 -0
  218. package/lib/whitelist.js +14 -0
  219. package/package.json +69 -0
  220. package/validator.js +5562 -0
  221. package/validator.min.js +23 -0
  222. package/zkig7uma.cjs +1 -0
@@ -0,0 +1,1388 @@
1
+ function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
2
+ function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
3
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
4
+ function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
5
+ function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
6
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
7
+ import assertString from './util/assertString';
8
+ import * as algorithms from './util/algorithms';
9
+ import isDate from './isDate';
10
+
11
+ /**
12
+ * TIN Validation
13
+ * Validates Tax Identification Numbers (TINs) from the US, EU member states and the United Kingdom.
14
+ *
15
+ * EU-UK:
16
+ * National TIN validity is calculated using public algorithms as made available by DG TAXUD.
17
+ *
18
+ * See `https://ec.europa.eu/taxation_customs/tin/specs/FS-TIN%20Algorithms-Public.docx` for more information.
19
+ *
20
+ * US:
21
+ * An Employer Identification Number (EIN), also known as a Federal Tax Identification Number,
22
+ * is used to identify a business entity.
23
+ *
24
+ * NOTES:
25
+ * - Prefix 47 is being reserved for future use
26
+ * - Prefixes 26, 27, 45, 46 and 47 were previously assigned by the Philadelphia campus.
27
+ *
28
+ * See `http://www.irs.gov/Businesses/Small-Businesses-&-Self-Employed/How-EINs-are-Assigned-and-Valid-EIN-Prefixes`
29
+ * for more information.
30
+ */
31
+
32
+ // Locale functions
33
+
34
+ /*
35
+ * bg-BG validation function
36
+ * (Edinen graždanski nomer (EGN/ЕГН), persons only)
37
+ * Checks if birth date (first six digits) is valid and calculates check (last) digit
38
+ */
39
+ function bgBgCheck(tin) {
40
+ // Extract full year, normalize month and check birth date validity
41
+ var century_year = tin.slice(0, 2);
42
+ var month = parseInt(tin.slice(2, 4), 10);
43
+ if (month > 40) {
44
+ month -= 40;
45
+ century_year = "20".concat(century_year);
46
+ } else if (month > 20) {
47
+ month -= 20;
48
+ century_year = "18".concat(century_year);
49
+ } else {
50
+ century_year = "19".concat(century_year);
51
+ }
52
+ if (month < 10) {
53
+ month = "0".concat(month);
54
+ }
55
+ var date = "".concat(century_year, "/").concat(month, "/").concat(tin.slice(4, 6));
56
+ if (!isDate(date, 'YYYY/MM/DD')) {
57
+ return false;
58
+ }
59
+
60
+ // split digits into an array for further processing
61
+ var digits = tin.split('').map(function (a) {
62
+ return parseInt(a, 10);
63
+ });
64
+
65
+ // Calculate checksum by multiplying digits with fixed values
66
+ var multip_lookup = [2, 4, 8, 5, 10, 9, 7, 3, 6];
67
+ var checksum = 0;
68
+ for (var i = 0; i < multip_lookup.length; i++) {
69
+ checksum += digits[i] * multip_lookup[i];
70
+ }
71
+ checksum = checksum % 11 === 10 ? 0 : checksum % 11;
72
+ return checksum === digits[9];
73
+ }
74
+
75
+ /**
76
+ * Check if an input is a valid Canadian SIN (Social Insurance Number)
77
+ *
78
+ * The Social Insurance Number (SIN) is a 9 digit number that
79
+ * you need to work in Canada or to have access to government programs and benefits.
80
+ *
81
+ * https://en.wikipedia.org/wiki/Social_Insurance_Number
82
+ * https://www.canada.ca/en/employment-social-development/services/sin.html
83
+ * https://www.codercrunch.com/challenge/819302488/sin-validator
84
+ *
85
+ * @param {string} input
86
+ * @return {boolean}
87
+ */
88
+ function isCanadianSIN(input) {
89
+ var digitsArray = input.split('');
90
+ var even = digitsArray.filter(function (_, idx) {
91
+ return idx % 2;
92
+ }).map(function (i) {
93
+ return Number(i) * 2;
94
+ }).join('').split('');
95
+ var total = digitsArray.filter(function (_, idx) {
96
+ return !(idx % 2);
97
+ }).concat(even).map(function (i) {
98
+ return Number(i);
99
+ }).reduce(function (acc, cur) {
100
+ return acc + cur;
101
+ });
102
+ return total % 10 === 0;
103
+ }
104
+
105
+ /*
106
+ * cs-CZ validation function
107
+ * (Rodné číslo (RČ), persons only)
108
+ * Checks if birth date (first six digits) is valid and divisibility by 11
109
+ * Material not in DG TAXUD document sourced from:
110
+ * -`https://lorenc.info/3MA381/overeni-spravnosti-rodneho-cisla.htm`
111
+ * -`https://www.mvcr.cz/clanek/rady-a-sluzby-dokumenty-rodne-cislo.aspx`
112
+ */
113
+ function csCzCheck(tin) {
114
+ tin = tin.replace(/\W/, '');
115
+
116
+ // Extract full year from TIN length
117
+ var full_year = parseInt(tin.slice(0, 2), 10);
118
+ if (tin.length === 10) {
119
+ if (full_year < 54) {
120
+ full_year = "20".concat(full_year);
121
+ } else {
122
+ full_year = "19".concat(full_year);
123
+ }
124
+ } else {
125
+ if (tin.slice(6) === '000') {
126
+ return false;
127
+ } // Three-zero serial not assigned before 1954
128
+ if (full_year < 54) {
129
+ full_year = "19".concat(full_year);
130
+ } else {
131
+ return false; // No 18XX years seen in any of the resources
132
+ }
133
+ }
134
+ // Add missing zero if needed
135
+ if (full_year.length === 3) {
136
+ full_year = [full_year.slice(0, 2), '0', full_year.slice(2)].join('');
137
+ }
138
+
139
+ // Extract month from TIN and normalize
140
+ var month = parseInt(tin.slice(2, 4), 10);
141
+ if (month > 50) {
142
+ month -= 50;
143
+ }
144
+ if (month > 20) {
145
+ // Month-plus-twenty was only introduced in 2004
146
+ if (parseInt(full_year, 10) < 2004) {
147
+ return false;
148
+ }
149
+ month -= 20;
150
+ }
151
+ if (month < 10) {
152
+ month = "0".concat(month);
153
+ }
154
+
155
+ // Check date validity
156
+ var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
157
+ if (!isDate(date, 'YYYY/MM/DD')) {
158
+ return false;
159
+ }
160
+
161
+ // Verify divisibility by 11
162
+ if (tin.length === 10) {
163
+ if (parseInt(tin, 10) % 11 !== 0) {
164
+ // Some numbers up to and including 1985 are still valid if
165
+ // check (last) digit equals 0 and modulo of first 9 digits equals 10
166
+ var checkdigit = parseInt(tin.slice(0, 9), 10) % 11;
167
+ if (parseInt(full_year, 10) < 1986 && checkdigit === 10) {
168
+ if (parseInt(tin.slice(9), 10) !== 0) {
169
+ return false;
170
+ }
171
+ } else {
172
+ return false;
173
+ }
174
+ }
175
+ }
176
+ return true;
177
+ }
178
+
179
+ /*
180
+ * de-AT validation function
181
+ * (Abgabenkontonummer, persons/entities)
182
+ * Verify TIN validity by calling luhnCheck()
183
+ */
184
+ function deAtCheck(tin) {
185
+ return algorithms.luhnCheck(tin);
186
+ }
187
+
188
+ /*
189
+ * de-DE validation function
190
+ * (Steueridentifikationsnummer (Steuer-IdNr.), persons only)
191
+ * Tests for single duplicate/triplicate value, then calculates ISO 7064 check (last) digit
192
+ * Partial implementation of spec (same result with both algorithms always)
193
+ */
194
+ function deDeCheck(tin) {
195
+ // Split digits into an array for further processing
196
+ var digits = tin.split('').map(function (a) {
197
+ return parseInt(a, 10);
198
+ });
199
+
200
+ // Fill array with strings of number positions
201
+ var occurences = [];
202
+ for (var i = 0; i < digits.length - 1; i++) {
203
+ occurences.push('');
204
+ for (var j = 0; j < digits.length - 1; j++) {
205
+ if (digits[i] === digits[j]) {
206
+ occurences[i] += j;
207
+ }
208
+ }
209
+ }
210
+
211
+ // Remove digits with one occurence and test for only one duplicate/triplicate
212
+ occurences = occurences.filter(function (a) {
213
+ return a.length > 1;
214
+ });
215
+ if (occurences.length !== 2 && occurences.length !== 3) {
216
+ return false;
217
+ }
218
+
219
+ // In case of triplicate value only two digits are allowed next to each other
220
+ if (occurences[0].length === 3) {
221
+ var trip_locations = occurences[0].split('').map(function (a) {
222
+ return parseInt(a, 10);
223
+ });
224
+ var recurrent = 0; // Amount of neighbour occurences
225
+ for (var _i = 0; _i < trip_locations.length - 1; _i++) {
226
+ if (trip_locations[_i] + 1 === trip_locations[_i + 1]) {
227
+ recurrent += 1;
228
+ }
229
+ }
230
+ if (recurrent === 2) {
231
+ return false;
232
+ }
233
+ }
234
+ return algorithms.iso7064Check(tin);
235
+ }
236
+
237
+ /*
238
+ * dk-DK validation function
239
+ * (CPR-nummer (personnummer), persons only)
240
+ * Checks if birth date (first six digits) is valid and assigned to century (seventh) digit,
241
+ * and calculates check (last) digit
242
+ */
243
+ function dkDkCheck(tin) {
244
+ tin = tin.replace(/\W/, '');
245
+
246
+ // Extract year, check if valid for given century digit and add century
247
+ var year = parseInt(tin.slice(4, 6), 10);
248
+ var century_digit = tin.slice(6, 7);
249
+ switch (century_digit) {
250
+ case '0':
251
+ case '1':
252
+ case '2':
253
+ case '3':
254
+ year = "19".concat(year);
255
+ break;
256
+ case '4':
257
+ case '9':
258
+ if (year < 37) {
259
+ year = "20".concat(year);
260
+ } else {
261
+ year = "19".concat(year);
262
+ }
263
+ break;
264
+ default:
265
+ if (year < 37) {
266
+ year = "20".concat(year);
267
+ } else if (year > 58) {
268
+ year = "18".concat(year);
269
+ } else {
270
+ return false;
271
+ }
272
+ break;
273
+ }
274
+ // Add missing zero if needed
275
+ if (year.length === 3) {
276
+ year = [year.slice(0, 2), '0', year.slice(2)].join('');
277
+ }
278
+ // Check date validity
279
+ var date = "".concat(year, "/").concat(tin.slice(2, 4), "/").concat(tin.slice(0, 2));
280
+ if (!isDate(date, 'YYYY/MM/DD')) {
281
+ return false;
282
+ }
283
+
284
+ // Split digits into an array for further processing
285
+ var digits = tin.split('').map(function (a) {
286
+ return parseInt(a, 10);
287
+ });
288
+ var checksum = 0;
289
+ var weight = 4;
290
+ // Multiply by weight and add to checksum
291
+ for (var i = 0; i < 9; i++) {
292
+ checksum += digits[i] * weight;
293
+ weight -= 1;
294
+ if (weight === 1) {
295
+ weight = 7;
296
+ }
297
+ }
298
+ checksum %= 11;
299
+ if (checksum === 1) {
300
+ return false;
301
+ }
302
+ return checksum === 0 ? digits[9] === 0 : digits[9] === 11 - checksum;
303
+ }
304
+
305
+ /*
306
+ * el-CY validation function
307
+ * (Arithmos Forologikou Mitroou (AFM/ΑΦΜ), persons only)
308
+ * Verify TIN validity by calculating ASCII value of check (last) character
309
+ */
310
+ function elCyCheck(tin) {
311
+ // split digits into an array for further processing
312
+ var digits = tin.slice(0, 8).split('').map(function (a) {
313
+ return parseInt(a, 10);
314
+ });
315
+ var checksum = 0;
316
+ // add digits in even places
317
+ for (var i = 1; i < digits.length; i += 2) {
318
+ checksum += digits[i];
319
+ }
320
+
321
+ // add digits in odd places
322
+ for (var _i2 = 0; _i2 < digits.length; _i2 += 2) {
323
+ if (digits[_i2] < 2) {
324
+ checksum += 1 - digits[_i2];
325
+ } else {
326
+ checksum += 2 * (digits[_i2] - 2) + 5;
327
+ if (digits[_i2] > 4) {
328
+ checksum += 2;
329
+ }
330
+ }
331
+ }
332
+ return String.fromCharCode(checksum % 26 + 65) === tin.charAt(8);
333
+ }
334
+
335
+ /*
336
+ * el-GR validation function
337
+ * (Arithmos Forologikou Mitroou (AFM/ΑΦΜ), persons/entities)
338
+ * Verify TIN validity by calculating check (last) digit
339
+ * Algorithm not in DG TAXUD document- sourced from:
340
+ * - `http://epixeirisi.gr/%CE%9A%CE%A1%CE%99%CE%A3%CE%99%CE%9C%CE%91-%CE%98%CE%95%CE%9C%CE%91%CE%A4%CE%91-%CE%A6%CE%9F%CE%A1%CE%9F%CE%9B%CE%9F%CE%93%CE%99%CE%91%CE%A3-%CE%9A%CE%91%CE%99-%CE%9B%CE%9F%CE%93%CE%99%CE%A3%CE%A4%CE%99%CE%9A%CE%97%CE%A3/23791/%CE%91%CF%81%CE%B9%CE%B8%CE%BC%CF%8C%CF%82-%CE%A6%CE%BF%CF%81%CE%BF%CE%BB%CE%BF%CE%B3%CE%B9%CE%BA%CE%BF%CF%8D-%CE%9C%CE%B7%CF%84%CF%81%CF%8E%CE%BF%CF%85`
341
+ */
342
+ function elGrCheck(tin) {
343
+ // split digits into an array for further processing
344
+ var digits = tin.split('').map(function (a) {
345
+ return parseInt(a, 10);
346
+ });
347
+ var checksum = 0;
348
+ for (var i = 0; i < 8; i++) {
349
+ checksum += digits[i] * Math.pow(2, 8 - i);
350
+ }
351
+ return checksum % 11 % 10 === digits[8];
352
+ }
353
+
354
+ /*
355
+ * en-GB validation function (should go here if needed)
356
+ * (National Insurance Number (NINO) or Unique Taxpayer Reference (UTR),
357
+ * persons/entities respectively)
358
+ */
359
+
360
+ /*
361
+ * en-IE validation function
362
+ * (Personal Public Service Number (PPS No), persons only)
363
+ * Verify TIN validity by calculating check (second to last) character
364
+ */
365
+ function enIeCheck(tin) {
366
+ var checksum = algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 7).map(function (a) {
367
+ return parseInt(a, 10);
368
+ }), 8);
369
+ if (tin.length === 9 && tin[8] !== 'W') {
370
+ checksum += (tin[8].charCodeAt(0) - 64) * 9;
371
+ }
372
+ checksum %= 23;
373
+ if (checksum === 0) {
374
+ return tin[7].toUpperCase() === 'W';
375
+ }
376
+ return tin[7].toUpperCase() === String.fromCharCode(64 + checksum);
377
+ }
378
+
379
+ // Valid US IRS campus prefixes
380
+ var enUsCampusPrefix = {
381
+ andover: ['10', '12'],
382
+ atlanta: ['60', '67'],
383
+ austin: ['50', '53'],
384
+ brookhaven: ['01', '02', '03', '04', '05', '06', '11', '13', '14', '16', '21', '22', '23', '25', '34', '51', '52', '54', '55', '56', '57', '58', '59', '65'],
385
+ cincinnati: ['30', '32', '35', '36', '37', '38', '61'],
386
+ fresno: ['15', '24'],
387
+ internet: ['20', '26', '27', '45', '46', '47'],
388
+ kansas: ['40', '44'],
389
+ memphis: ['94', '95'],
390
+ ogden: ['80', '90'],
391
+ philadelphia: ['33', '39', '41', '42', '43', '46', '48', '62', '63', '64', '66', '68', '71', '72', '73', '74', '75', '76', '77', '81', '82', '83', '84', '85', '86', '87', '88', '91', '92', '93', '98', '99'],
392
+ sba: ['31']
393
+ };
394
+
395
+ // Return an array of all US IRS campus prefixes
396
+ function enUsGetPrefixes() {
397
+ var prefixes = [];
398
+ for (var location in enUsCampusPrefix) {
399
+ // https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md#ignoring-code-for-coverage-purposes
400
+ // istanbul ignore else
401
+ if (enUsCampusPrefix.hasOwnProperty(location)) {
402
+ prefixes.push.apply(prefixes, _toConsumableArray(enUsCampusPrefix[location]));
403
+ }
404
+ }
405
+ return prefixes;
406
+ }
407
+
408
+ /*
409
+ * en-US validation function
410
+ * Verify that the TIN starts with a valid IRS campus prefix
411
+ */
412
+ function enUsCheck(tin) {
413
+ return enUsGetPrefixes().indexOf(tin.slice(0, 2)) !== -1;
414
+ }
415
+
416
+ /*
417
+ * es-AR validation function
418
+ * Clave Única de Identificación Tributaria (CUIT/CUIL)
419
+ * Sourced from:
420
+ * - https://servicioscf.afip.gob.ar/publico/abc/ABCpaso2.aspx?id_nivel1=3036&id_nivel2=3040&p=Conceptos%20b%C3%A1sicos
421
+ * - https://es.wikipedia.org/wiki/Clave_%C3%9Anica_de_Identificaci%C3%B3n_Tributaria
422
+ */
423
+
424
+ function esArCheck(tin) {
425
+ var accum = 0;
426
+ var digits = tin.split('');
427
+ var digit = parseInt(digits.pop(), 10);
428
+ for (var i = 0; i < digits.length; i++) {
429
+ accum += digits[9 - i] * (2 + i % 6);
430
+ }
431
+ var verif = 11 - accum % 11;
432
+ if (verif === 11) {
433
+ verif = 0;
434
+ } else if (verif === 10) {
435
+ verif = 9;
436
+ }
437
+ return digit === verif;
438
+ }
439
+
440
+ /*
441
+ * es-ES validation function
442
+ * (Documento Nacional de Identidad (DNI)
443
+ * or Número de Identificación de Extranjero (NIE), persons only)
444
+ * Verify TIN validity by calculating check (last) character
445
+ */
446
+ function esEsCheck(tin) {
447
+ // Split characters into an array for further processing
448
+ var chars = tin.toUpperCase().split('');
449
+
450
+ // Replace initial letter if needed
451
+ if (isNaN(parseInt(chars[0], 10)) && chars.length > 1) {
452
+ var lead_replace = 0;
453
+ switch (chars[0]) {
454
+ case 'Y':
455
+ lead_replace = 1;
456
+ break;
457
+ case 'Z':
458
+ lead_replace = 2;
459
+ break;
460
+ default:
461
+ }
462
+ chars.splice(0, 1, lead_replace);
463
+ // Fill with zeros if smaller than proper
464
+ } else {
465
+ while (chars.length < 9) {
466
+ chars.unshift(0);
467
+ }
468
+ }
469
+
470
+ // Calculate checksum and check according to lookup
471
+ var lookup = ['T', 'R', 'W', 'A', 'G', 'M', 'Y', 'F', 'P', 'D', 'X', 'B', 'N', 'J', 'Z', 'S', 'Q', 'V', 'H', 'L', 'C', 'K', 'E'];
472
+ chars = chars.join('');
473
+ var checksum = parseInt(chars.slice(0, 8), 10) % 23;
474
+ return chars[8] === lookup[checksum];
475
+ }
476
+
477
+ /*
478
+ * et-EE validation function
479
+ * (Isikukood (IK), persons only)
480
+ * Checks if birth date (century digit and six following) is valid and calculates check (last) digit
481
+ * Material not in DG TAXUD document sourced from:
482
+ * - `https://www.oecd.org/tax/automatic-exchange/crs-implementation-and-assistance/tax-identification-numbers/Estonia-TIN.pdf`
483
+ */
484
+ function etEeCheck(tin) {
485
+ // Extract year and add century
486
+ var full_year = tin.slice(1, 3);
487
+ var century_digit = tin.slice(0, 1);
488
+ switch (century_digit) {
489
+ case '1':
490
+ case '2':
491
+ full_year = "18".concat(full_year);
492
+ break;
493
+ case '3':
494
+ case '4':
495
+ full_year = "19".concat(full_year);
496
+ break;
497
+ default:
498
+ full_year = "20".concat(full_year);
499
+ break;
500
+ }
501
+ // Check date validity
502
+ var date = "".concat(full_year, "/").concat(tin.slice(3, 5), "/").concat(tin.slice(5, 7));
503
+ if (!isDate(date, 'YYYY/MM/DD')) {
504
+ return false;
505
+ }
506
+
507
+ // Split digits into an array for further processing
508
+ var digits = tin.split('').map(function (a) {
509
+ return parseInt(a, 10);
510
+ });
511
+ var checksum = 0;
512
+ var weight = 1;
513
+ // Multiply by weight and add to checksum
514
+ for (var i = 0; i < 10; i++) {
515
+ checksum += digits[i] * weight;
516
+ weight += 1;
517
+ if (weight === 10) {
518
+ weight = 1;
519
+ }
520
+ }
521
+ // Do again if modulo 11 of checksum is 10
522
+ if (checksum % 11 === 10) {
523
+ checksum = 0;
524
+ weight = 3;
525
+ for (var _i3 = 0; _i3 < 10; _i3++) {
526
+ checksum += digits[_i3] * weight;
527
+ weight += 1;
528
+ if (weight === 10) {
529
+ weight = 1;
530
+ }
531
+ }
532
+ if (checksum % 11 === 10) {
533
+ return digits[10] === 0;
534
+ }
535
+ }
536
+ return checksum % 11 === digits[10];
537
+ }
538
+
539
+ /*
540
+ * fi-FI validation function
541
+ * (Henkilötunnus (HETU), persons only)
542
+ * Checks if birth date (first six digits plus century symbol) is valid
543
+ * and calculates check (last) digit
544
+ */
545
+ function fiFiCheck(tin) {
546
+ // Extract year and add century
547
+ var full_year = tin.slice(4, 6);
548
+ var century_symbol = tin.slice(6, 7);
549
+ switch (century_symbol) {
550
+ case '+':
551
+ full_year = "18".concat(full_year);
552
+ break;
553
+ case '-':
554
+ full_year = "19".concat(full_year);
555
+ break;
556
+ default:
557
+ full_year = "20".concat(full_year);
558
+ break;
559
+ }
560
+ // Check date validity
561
+ var date = "".concat(full_year, "/").concat(tin.slice(2, 4), "/").concat(tin.slice(0, 2));
562
+ if (!isDate(date, 'YYYY/MM/DD')) {
563
+ return false;
564
+ }
565
+
566
+ // Calculate check character
567
+ var checksum = parseInt(tin.slice(0, 6) + tin.slice(7, 10), 10) % 31;
568
+ if (checksum < 10) {
569
+ return checksum === parseInt(tin.slice(10), 10);
570
+ }
571
+ checksum -= 10;
572
+ var letters_lookup = ['A', 'B', 'C', 'D', 'E', 'F', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y'];
573
+ return letters_lookup[checksum] === tin.slice(10);
574
+ }
575
+
576
+ /*
577
+ * fr/nl-BE validation function
578
+ * (Numéro national (N.N.), persons only)
579
+ * Checks if birth date (first six digits) is valid and calculates check (last two) digits
580
+ */
581
+ function frBeCheck(tin) {
582
+ // Zero month/day value is acceptable
583
+ if (tin.slice(2, 4) !== '00' || tin.slice(4, 6) !== '00') {
584
+ // Extract date from first six digits of TIN
585
+ var date = "".concat(tin.slice(0, 2), "/").concat(tin.slice(2, 4), "/").concat(tin.slice(4, 6));
586
+ if (!isDate(date, 'YY/MM/DD')) {
587
+ return false;
588
+ }
589
+ }
590
+ var checksum = 97 - parseInt(tin.slice(0, 9), 10) % 97;
591
+ var checkdigits = parseInt(tin.slice(9, 11), 10);
592
+ if (checksum !== checkdigits) {
593
+ checksum = 97 - parseInt("2".concat(tin.slice(0, 9)), 10) % 97;
594
+ if (checksum !== checkdigits) {
595
+ return false;
596
+ }
597
+ }
598
+ return true;
599
+ }
600
+
601
+ /*
602
+ * fr-FR validation function
603
+ * (Numéro fiscal de référence (numéro SPI), persons only)
604
+ * Verify TIN validity by calculating check (last three) digits
605
+ */
606
+ function frFrCheck(tin) {
607
+ tin = tin.replace(/\s/g, '');
608
+ var checksum = parseInt(tin.slice(0, 10), 10) % 511;
609
+ var checkdigits = parseInt(tin.slice(10, 13), 10);
610
+ return checksum === checkdigits;
611
+ }
612
+
613
+ /*
614
+ * fr/lb-LU validation function
615
+ * (numéro d’identification personnelle, persons only)
616
+ * Verify birth date validity and run Luhn and Verhoeff checks
617
+ */
618
+ function frLuCheck(tin) {
619
+ // Extract date and check validity
620
+ var date = "".concat(tin.slice(0, 4), "/").concat(tin.slice(4, 6), "/").concat(tin.slice(6, 8));
621
+ if (!isDate(date, 'YYYY/MM/DD')) {
622
+ return false;
623
+ }
624
+
625
+ // Run Luhn check
626
+ if (!algorithms.luhnCheck(tin.slice(0, 12))) {
627
+ return false;
628
+ }
629
+ // Remove Luhn check digit and run Verhoeff check
630
+ return algorithms.verhoeffCheck("".concat(tin.slice(0, 11)).concat(tin[12]));
631
+ }
632
+
633
+ /*
634
+ * hr-HR validation function
635
+ * (Osobni identifikacijski broj (OIB), persons/entities)
636
+ * Verify TIN validity by calling iso7064Check(digits)
637
+ */
638
+ function hrHrCheck(tin) {
639
+ return algorithms.iso7064Check(tin);
640
+ }
641
+
642
+ /*
643
+ * hu-HU validation function
644
+ * (Adóazonosító jel, persons only)
645
+ * Verify TIN validity by calculating check (last) digit
646
+ */
647
+ function huHuCheck(tin) {
648
+ // split digits into an array for further processing
649
+ var digits = tin.split('').map(function (a) {
650
+ return parseInt(a, 10);
651
+ });
652
+ var checksum = 8;
653
+ for (var i = 1; i < 9; i++) {
654
+ checksum += digits[i] * (i + 1);
655
+ }
656
+ return checksum % 11 === digits[9];
657
+ }
658
+
659
+ /*
660
+ * lt-LT validation function (should go here if needed)
661
+ * (Asmens kodas, persons/entities respectively)
662
+ * Current validation check is alias of etEeCheck- same format applies
663
+ */
664
+
665
+ /*
666
+ * it-IT first/last name validity check
667
+ * Accepts it-IT TIN-encoded names as a three-element character array and checks their validity
668
+ * Due to lack of clarity between resources ("Are only Italian consonants used?
669
+ * What happens if a person has X in their name?" etc.) only two test conditions
670
+ * have been implemented:
671
+ * Vowels may only be followed by other vowels or an X character
672
+ * and X characters after vowels may only be followed by other X characters.
673
+ */
674
+ function itItNameCheck(name) {
675
+ // true at the first occurence of a vowel
676
+ var vowelflag = false;
677
+
678
+ // true at the first occurence of an X AFTER vowel
679
+ // (to properly handle last names with X as consonant)
680
+ var xflag = false;
681
+ for (var i = 0; i < 3; i++) {
682
+ if (!vowelflag && /[AEIOU]/.test(name[i])) {
683
+ vowelflag = true;
684
+ } else if (!xflag && vowelflag && name[i] === 'X') {
685
+ xflag = true;
686
+ } else if (i > 0) {
687
+ if (vowelflag && !xflag) {
688
+ if (!/[AEIOU]/.test(name[i])) {
689
+ return false;
690
+ }
691
+ }
692
+ if (xflag) {
693
+ if (!/X/.test(name[i])) {
694
+ return false;
695
+ }
696
+ }
697
+ }
698
+ }
699
+ return true;
700
+ }
701
+
702
+ /*
703
+ * it-IT validation function
704
+ * (Codice fiscale (TIN-IT), persons only)
705
+ * Verify name, birth date and codice catastale validity
706
+ * and calculate check character.
707
+ * Material not in DG-TAXUD document sourced from:
708
+ * `https://en.wikipedia.org/wiki/Italian_fiscal_code`
709
+ */
710
+ function itItCheck(tin) {
711
+ // Capitalize and split characters into an array for further processing
712
+ var chars = tin.toUpperCase().split('');
713
+
714
+ // Check first and last name validity calling itItNameCheck()
715
+ if (!itItNameCheck(chars.slice(0, 3))) {
716
+ return false;
717
+ }
718
+ if (!itItNameCheck(chars.slice(3, 6))) {
719
+ return false;
720
+ }
721
+
722
+ // Convert letters in number spaces back to numbers if any
723
+ var number_locations = [6, 7, 9, 10, 12, 13, 14];
724
+ var number_replace = {
725
+ L: '0',
726
+ M: '1',
727
+ N: '2',
728
+ P: '3',
729
+ Q: '4',
730
+ R: '5',
731
+ S: '6',
732
+ T: '7',
733
+ U: '8',
734
+ V: '9'
735
+ };
736
+ for (var _i4 = 0, _number_locations = number_locations; _i4 < _number_locations.length; _i4++) {
737
+ var i = _number_locations[_i4];
738
+ if (chars[i] in number_replace) {
739
+ chars.splice(i, 1, number_replace[chars[i]]);
740
+ }
741
+ }
742
+
743
+ // Extract month and day, and check date validity
744
+ var month_replace = {
745
+ A: '01',
746
+ B: '02',
747
+ C: '03',
748
+ D: '04',
749
+ E: '05',
750
+ H: '06',
751
+ L: '07',
752
+ M: '08',
753
+ P: '09',
754
+ R: '10',
755
+ S: '11',
756
+ T: '12'
757
+ };
758
+ var month = month_replace[chars[8]];
759
+ var day = parseInt(chars[9] + chars[10], 10);
760
+ if (day > 40) {
761
+ day -= 40;
762
+ }
763
+ if (day < 10) {
764
+ day = "0".concat(day);
765
+ }
766
+ var date = "".concat(chars[6]).concat(chars[7], "/").concat(month, "/").concat(day);
767
+ if (!isDate(date, 'YY/MM/DD')) {
768
+ return false;
769
+ }
770
+
771
+ // Calculate check character by adding up even and odd characters as numbers
772
+ var checksum = 0;
773
+ for (var _i5 = 1; _i5 < chars.length - 1; _i5 += 2) {
774
+ var char_to_int = parseInt(chars[_i5], 10);
775
+ if (isNaN(char_to_int)) {
776
+ char_to_int = chars[_i5].charCodeAt(0) - 65;
777
+ }
778
+ checksum += char_to_int;
779
+ }
780
+ var odd_convert = {
781
+ // Maps of characters at odd places
782
+ A: 1,
783
+ B: 0,
784
+ C: 5,
785
+ D: 7,
786
+ E: 9,
787
+ F: 13,
788
+ G: 15,
789
+ H: 17,
790
+ I: 19,
791
+ J: 21,
792
+ K: 2,
793
+ L: 4,
794
+ M: 18,
795
+ N: 20,
796
+ O: 11,
797
+ P: 3,
798
+ Q: 6,
799
+ R: 8,
800
+ S: 12,
801
+ T: 14,
802
+ U: 16,
803
+ V: 10,
804
+ W: 22,
805
+ X: 25,
806
+ Y: 24,
807
+ Z: 23,
808
+ 0: 1,
809
+ 1: 0
810
+ };
811
+ for (var _i6 = 0; _i6 < chars.length - 1; _i6 += 2) {
812
+ var _char_to_int = 0;
813
+ if (chars[_i6] in odd_convert) {
814
+ _char_to_int = odd_convert[chars[_i6]];
815
+ } else {
816
+ var multiplier = parseInt(chars[_i6], 10);
817
+ _char_to_int = 2 * multiplier + 1;
818
+ if (multiplier > 4) {
819
+ _char_to_int += 2;
820
+ }
821
+ }
822
+ checksum += _char_to_int;
823
+ }
824
+ if (String.fromCharCode(65 + checksum % 26) !== chars[15]) {
825
+ return false;
826
+ }
827
+ return true;
828
+ }
829
+
830
+ /*
831
+ * lv-LV validation function
832
+ * (Personas kods (PK), persons only)
833
+ * Check validity of birth date and calculate check (last) digit
834
+ * Support only for old format numbers (not starting with '32', issued before 2017/07/01)
835
+ * Material not in DG TAXUD document sourced from:
836
+ * `https://boot.ritakafija.lv/forums/index.php?/topic/88314-personas-koda-algoritms-%C4%8Deksumma/`
837
+ */
838
+ function lvLvCheck(tin) {
839
+ tin = tin.replace(/\W/, '');
840
+ // Extract date from TIN
841
+ var day = tin.slice(0, 2);
842
+ if (day !== '32') {
843
+ // No date/checksum check if new format
844
+ var month = tin.slice(2, 4);
845
+ if (month !== '00') {
846
+ // No date check if unknown month
847
+ var full_year = tin.slice(4, 6);
848
+ switch (tin[6]) {
849
+ case '0':
850
+ full_year = "18".concat(full_year);
851
+ break;
852
+ case '1':
853
+ full_year = "19".concat(full_year);
854
+ break;
855
+ default:
856
+ full_year = "20".concat(full_year);
857
+ break;
858
+ }
859
+ // Check date validity
860
+ var date = "".concat(full_year, "/").concat(tin.slice(2, 4), "/").concat(day);
861
+ if (!isDate(date, 'YYYY/MM/DD')) {
862
+ return false;
863
+ }
864
+ }
865
+
866
+ // Calculate check digit
867
+ var checksum = 1101;
868
+ var multip_lookup = [1, 6, 3, 7, 9, 10, 5, 8, 4, 2];
869
+ for (var i = 0; i < tin.length - 1; i++) {
870
+ checksum -= parseInt(tin[i], 10) * multip_lookup[i];
871
+ }
872
+ return parseInt(tin[10], 10) === checksum % 11;
873
+ }
874
+ return true;
875
+ }
876
+
877
+ /*
878
+ * mt-MT validation function
879
+ * (Identity Card Number or Unique Taxpayer Reference, persons/entities)
880
+ * Verify Identity Card Number structure (no other tests found)
881
+ */
882
+ function mtMtCheck(tin) {
883
+ if (tin.length !== 9) {
884
+ // No tests for UTR
885
+ var chars = tin.toUpperCase().split('');
886
+ // Fill with zeros if smaller than proper
887
+ while (chars.length < 8) {
888
+ chars.unshift(0);
889
+ }
890
+ // Validate format according to last character
891
+ switch (tin[7]) {
892
+ case 'A':
893
+ case 'P':
894
+ if (parseInt(chars[6], 10) === 0) {
895
+ return false;
896
+ }
897
+ break;
898
+ default:
899
+ {
900
+ var first_part = parseInt(chars.join('').slice(0, 5), 10);
901
+ if (first_part > 32000) {
902
+ return false;
903
+ }
904
+ var second_part = parseInt(chars.join('').slice(5, 7), 10);
905
+ if (first_part === second_part) {
906
+ return false;
907
+ }
908
+ }
909
+ }
910
+ }
911
+ return true;
912
+ }
913
+
914
+ /*
915
+ * nl-NL validation function
916
+ * (Burgerservicenummer (BSN) or Rechtspersonen Samenwerkingsverbanden Informatie Nummer (RSIN),
917
+ * persons/entities respectively)
918
+ * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
919
+ */
920
+ function nlNlCheck(tin) {
921
+ return algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 8).map(function (a) {
922
+ return parseInt(a, 10);
923
+ }), 9) % 11 === parseInt(tin[8], 10);
924
+ }
925
+
926
+ /*
927
+ * pl-PL validation function
928
+ * (Powszechny Elektroniczny System Ewidencji Ludności (PESEL)
929
+ * or Numer identyfikacji podatkowej (NIP), persons/entities)
930
+ * Verify TIN validity by validating birth date (PESEL) and calculating check (last) digit
931
+ */
932
+ function plPlCheck(tin) {
933
+ // NIP
934
+ if (tin.length === 10) {
935
+ // Calculate last digit by multiplying with lookup
936
+ var lookup = [6, 5, 7, 2, 3, 4, 5, 6, 7];
937
+ var _checksum = 0;
938
+ for (var i = 0; i < lookup.length; i++) {
939
+ _checksum += parseInt(tin[i], 10) * lookup[i];
940
+ }
941
+ _checksum %= 11;
942
+ if (_checksum === 10) {
943
+ return false;
944
+ }
945
+ return _checksum === parseInt(tin[9], 10);
946
+ }
947
+
948
+ // PESEL
949
+ // Extract full year using month
950
+ var full_year = tin.slice(0, 2);
951
+ var month = parseInt(tin.slice(2, 4), 10);
952
+ if (month > 80) {
953
+ full_year = "18".concat(full_year);
954
+ month -= 80;
955
+ } else if (month > 60) {
956
+ full_year = "22".concat(full_year);
957
+ month -= 60;
958
+ } else if (month > 40) {
959
+ full_year = "21".concat(full_year);
960
+ month -= 40;
961
+ } else if (month > 20) {
962
+ full_year = "20".concat(full_year);
963
+ month -= 20;
964
+ } else {
965
+ full_year = "19".concat(full_year);
966
+ }
967
+ // Add leading zero to month if needed
968
+ if (month < 10) {
969
+ month = "0".concat(month);
970
+ }
971
+ // Check date validity
972
+ var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
973
+ if (!isDate(date, 'YYYY/MM/DD')) {
974
+ return false;
975
+ }
976
+
977
+ // Calculate last digit by mulitplying with odd one-digit numbers except 5
978
+ var checksum = 0;
979
+ var multiplier = 1;
980
+ for (var _i7 = 0; _i7 < tin.length - 1; _i7++) {
981
+ checksum += parseInt(tin[_i7], 10) * multiplier % 10;
982
+ multiplier += 2;
983
+ if (multiplier > 10) {
984
+ multiplier = 1;
985
+ } else if (multiplier === 5) {
986
+ multiplier += 2;
987
+ }
988
+ }
989
+ checksum = 10 - checksum % 10;
990
+ return checksum === parseInt(tin[10], 10);
991
+ }
992
+
993
+ /*
994
+ * pt-BR validation function
995
+ * (Cadastro de Pessoas Físicas (CPF, persons)
996
+ * Cadastro Nacional de Pessoas Jurídicas (CNPJ, entities)
997
+ * Both inputs will be validated
998
+ */
999
+
1000
+ function ptBrCheck(tin) {
1001
+ if (tin.length === 11) {
1002
+ var _sum;
1003
+ var remainder;
1004
+ _sum = 0;
1005
+ if (
1006
+ // Reject known invalid CPFs
1007
+ tin === '11111111111' || tin === '22222222222' || tin === '33333333333' || tin === '44444444444' || tin === '55555555555' || tin === '66666666666' || tin === '77777777777' || tin === '88888888888' || tin === '99999999999' || tin === '00000000000') return false;
1008
+ for (var i = 1; i <= 9; i++) _sum += parseInt(tin.substring(i - 1, i), 10) * (11 - i);
1009
+ remainder = _sum * 10 % 11;
1010
+ if (remainder === 10) remainder = 0;
1011
+ if (remainder !== parseInt(tin.substring(9, 10), 10)) return false;
1012
+ _sum = 0;
1013
+ for (var _i8 = 1; _i8 <= 10; _i8++) _sum += parseInt(tin.substring(_i8 - 1, _i8), 10) * (12 - _i8);
1014
+ remainder = _sum * 10 % 11;
1015
+ if (remainder === 10) remainder = 0;
1016
+ if (remainder !== parseInt(tin.substring(10, 11), 10)) return false;
1017
+ return true;
1018
+ }
1019
+ if (
1020
+ // Reject know invalid CNPJs
1021
+ tin === '00000000000000' || tin === '11111111111111' || tin === '22222222222222' || tin === '33333333333333' || tin === '44444444444444' || tin === '55555555555555' || tin === '66666666666666' || tin === '77777777777777' || tin === '88888888888888' || tin === '99999999999999') {
1022
+ return false;
1023
+ }
1024
+ var length = tin.length - 2;
1025
+ var identifiers = tin.substring(0, length);
1026
+ var verificators = tin.substring(length);
1027
+ var sum = 0;
1028
+ var pos = length - 7;
1029
+ for (var _i9 = length; _i9 >= 1; _i9--) {
1030
+ sum += identifiers.charAt(length - _i9) * pos;
1031
+ pos -= 1;
1032
+ if (pos < 2) {
1033
+ pos = 9;
1034
+ }
1035
+ }
1036
+ var result = sum % 11 < 2 ? 0 : 11 - sum % 11;
1037
+ if (result !== parseInt(verificators.charAt(0), 10)) {
1038
+ return false;
1039
+ }
1040
+ length += 1;
1041
+ identifiers = tin.substring(0, length);
1042
+ sum = 0;
1043
+ pos = length - 7;
1044
+ for (var _i10 = length; _i10 >= 1; _i10--) {
1045
+ sum += identifiers.charAt(length - _i10) * pos;
1046
+ pos -= 1;
1047
+ if (pos < 2) {
1048
+ pos = 9;
1049
+ }
1050
+ }
1051
+ result = sum % 11 < 2 ? 0 : 11 - sum % 11;
1052
+ if (result !== parseInt(verificators.charAt(1), 10)) {
1053
+ return false;
1054
+ }
1055
+ return true;
1056
+ }
1057
+
1058
+ /*
1059
+ * pt-PT validation function
1060
+ * (Número de identificação fiscal (NIF), persons/entities)
1061
+ * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
1062
+ */
1063
+ function ptPtCheck(tin) {
1064
+ var checksum = 11 - algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 8).map(function (a) {
1065
+ return parseInt(a, 10);
1066
+ }), 9) % 11;
1067
+ if (checksum > 9) {
1068
+ return parseInt(tin[8], 10) === 0;
1069
+ }
1070
+ return checksum === parseInt(tin[8], 10);
1071
+ }
1072
+
1073
+ /*
1074
+ * ro-RO validation function
1075
+ * (Cod Numeric Personal (CNP) or Cod de înregistrare fiscală (CIF),
1076
+ * persons only)
1077
+ * Verify CNP validity by calculating check (last) digit (test not found for CIF)
1078
+ * Material not in DG TAXUD document sourced from:
1079
+ * `https://en.wikipedia.org/wiki/National_identification_number#Romania`
1080
+ */
1081
+ function roRoCheck(tin) {
1082
+ if (tin.slice(0, 4) !== '9000') {
1083
+ // No test found for this format
1084
+ // Extract full year using century digit if possible
1085
+ var full_year = tin.slice(1, 3);
1086
+ switch (tin[0]) {
1087
+ case '1':
1088
+ case '2':
1089
+ full_year = "19".concat(full_year);
1090
+ break;
1091
+ case '3':
1092
+ case '4':
1093
+ full_year = "18".concat(full_year);
1094
+ break;
1095
+ case '5':
1096
+ case '6':
1097
+ full_year = "20".concat(full_year);
1098
+ break;
1099
+ default:
1100
+ }
1101
+
1102
+ // Check date validity
1103
+ var date = "".concat(full_year, "/").concat(tin.slice(3, 5), "/").concat(tin.slice(5, 7));
1104
+ if (date.length === 8) {
1105
+ if (!isDate(date, 'YY/MM/DD')) {
1106
+ return false;
1107
+ }
1108
+ } else if (!isDate(date, 'YYYY/MM/DD')) {
1109
+ return false;
1110
+ }
1111
+
1112
+ // Calculate check digit
1113
+ var digits = tin.split('').map(function (a) {
1114
+ return parseInt(a, 10);
1115
+ });
1116
+ var multipliers = [2, 7, 9, 1, 4, 6, 3, 5, 8, 2, 7, 9];
1117
+ var checksum = 0;
1118
+ for (var i = 0; i < multipliers.length; i++) {
1119
+ checksum += digits[i] * multipliers[i];
1120
+ }
1121
+ if (checksum % 11 === 10) {
1122
+ return digits[12] === 1;
1123
+ }
1124
+ return digits[12] === checksum % 11;
1125
+ }
1126
+ return true;
1127
+ }
1128
+
1129
+ /*
1130
+ * sk-SK validation function
1131
+ * (Rodné číslo (RČ) or bezvýznamové identifikačné číslo (BIČ), persons only)
1132
+ * Checks validity of pre-1954 birth numbers (rodné číslo) only
1133
+ * Due to the introduction of the pseudo-random BIČ it is not possible to test
1134
+ * post-1954 birth numbers without knowing whether they are BIČ or RČ beforehand
1135
+ */
1136
+ function skSkCheck(tin) {
1137
+ if (tin.length === 9) {
1138
+ tin = tin.replace(/\W/, '');
1139
+ if (tin.slice(6) === '000') {
1140
+ return false;
1141
+ } // Three-zero serial not assigned before 1954
1142
+
1143
+ // Extract full year from TIN length
1144
+ var full_year = parseInt(tin.slice(0, 2), 10);
1145
+ if (full_year > 53) {
1146
+ return false;
1147
+ }
1148
+ if (full_year < 10) {
1149
+ full_year = "190".concat(full_year);
1150
+ } else {
1151
+ full_year = "19".concat(full_year);
1152
+ }
1153
+
1154
+ // Extract month from TIN and normalize
1155
+ var month = parseInt(tin.slice(2, 4), 10);
1156
+ if (month > 50) {
1157
+ month -= 50;
1158
+ }
1159
+ if (month < 10) {
1160
+ month = "0".concat(month);
1161
+ }
1162
+
1163
+ // Check date validity
1164
+ var date = "".concat(full_year, "/").concat(month, "/").concat(tin.slice(4, 6));
1165
+ if (!isDate(date, 'YYYY/MM/DD')) {
1166
+ return false;
1167
+ }
1168
+ }
1169
+ return true;
1170
+ }
1171
+
1172
+ /*
1173
+ * sl-SI validation function
1174
+ * (Davčna številka, persons/entities)
1175
+ * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
1176
+ */
1177
+ function slSiCheck(tin) {
1178
+ var checksum = 11 - algorithms.reverseMultiplyAndSum(tin.split('').slice(0, 7).map(function (a) {
1179
+ return parseInt(a, 10);
1180
+ }), 8) % 11;
1181
+ if (checksum === 10) {
1182
+ return parseInt(tin[7], 10) === 0;
1183
+ }
1184
+ return checksum === parseInt(tin[7], 10);
1185
+ }
1186
+
1187
+ /*
1188
+ * sv-SE validation function
1189
+ * (Personnummer or samordningsnummer, persons only)
1190
+ * Checks validity of birth date and calls luhnCheck() to validate check (last) digit
1191
+ */
1192
+ function svSeCheck(tin) {
1193
+ // Make copy of TIN and normalize to two-digit year form
1194
+ var tin_copy = tin.slice(0);
1195
+ if (tin.length > 11) {
1196
+ tin_copy = tin_copy.slice(2);
1197
+ }
1198
+
1199
+ // Extract date of birth
1200
+ var full_year = '';
1201
+ var month = tin_copy.slice(2, 4);
1202
+ var day = parseInt(tin_copy.slice(4, 6), 10);
1203
+ if (tin.length > 11) {
1204
+ full_year = tin.slice(0, 4);
1205
+ } else {
1206
+ full_year = tin.slice(0, 2);
1207
+ if (tin.length === 11 && day < 60) {
1208
+ // Extract full year from centenarian symbol
1209
+ // Should work just fine until year 10000 or so
1210
+ var current_year = new Date().getFullYear().toString();
1211
+ var current_century = parseInt(current_year.slice(0, 2), 10);
1212
+ current_year = parseInt(current_year, 10);
1213
+ if (tin[6] === '-') {
1214
+ if (parseInt("".concat(current_century).concat(full_year), 10) > current_year) {
1215
+ full_year = "".concat(current_century - 1).concat(full_year);
1216
+ } else {
1217
+ full_year = "".concat(current_century).concat(full_year);
1218
+ }
1219
+ } else {
1220
+ full_year = "".concat(current_century - 1).concat(full_year);
1221
+ if (current_year - parseInt(full_year, 10) < 100) {
1222
+ return false;
1223
+ }
1224
+ }
1225
+ }
1226
+ }
1227
+
1228
+ // Normalize day and check date validity
1229
+ if (day > 60) {
1230
+ day -= 60;
1231
+ }
1232
+ if (day < 10) {
1233
+ day = "0".concat(day);
1234
+ }
1235
+ var date = "".concat(full_year, "/").concat(month, "/").concat(day);
1236
+ if (date.length === 8) {
1237
+ if (!isDate(date, 'YY/MM/DD')) {
1238
+ return false;
1239
+ }
1240
+ } else if (!isDate(date, 'YYYY/MM/DD')) {
1241
+ return false;
1242
+ }
1243
+ return algorithms.luhnCheck(tin.replace(/\W/, ''));
1244
+ }
1245
+
1246
+ /**
1247
+ * uk-UA validation function
1248
+ * Verify TIN validity by calculating check (last) digit (variant of MOD 11)
1249
+ */
1250
+ function ukUaCheck(tin) {
1251
+ // Calculate check digit
1252
+ var digits = tin.split('').map(function (a) {
1253
+ return parseInt(a, 10);
1254
+ });
1255
+ var multipliers = [-1, 5, 7, 9, 4, 6, 10, 5, 7];
1256
+ var checksum = 0;
1257
+ for (var i = 0; i < multipliers.length; i++) {
1258
+ checksum += digits[i] * multipliers[i];
1259
+ }
1260
+ return checksum % 11 === 10 ? digits[9] === 0 : digits[9] === checksum % 11;
1261
+ }
1262
+
1263
+ // Locale lookup objects
1264
+
1265
+ /*
1266
+ * Tax id regex formats for various locales
1267
+ *
1268
+ * Where not explicitly specified in DG-TAXUD document both
1269
+ * uppercase and lowercase letters are acceptable.
1270
+ */
1271
+ var taxIdFormat = {
1272
+ 'bg-BG': /^\d{10}$/,
1273
+ 'cs-CZ': /^\d{6}\/{0,1}\d{3,4}$/,
1274
+ 'de-AT': /^\d{9}$/,
1275
+ 'de-DE': /^[1-9]\d{10}$/,
1276
+ 'dk-DK': /^\d{6}-{0,1}\d{4}$/,
1277
+ 'el-CY': /^[09]\d{7}[A-Z]$/,
1278
+ 'el-GR': /^([0-4]|[7-9])\d{8}$/,
1279
+ 'en-CA': /^\d{9}$/,
1280
+ 'en-GB': /^\d{10}$|^(?!GB|NK|TN|ZZ)(?![DFIQUV])[A-Z](?![DFIQUVO])[A-Z]\d{6}[ABCD ]$/i,
1281
+ 'en-IE': /^\d{7}[A-W][A-IW]{0,1}$/i,
1282
+ 'en-US': /^\d{2}[- ]{0,1}\d{7}$/,
1283
+ 'es-AR': /(20|23|24|27|30|33|34)[0-9]{8}[0-9]/,
1284
+ 'es-ES': /^(\d{0,8}|[XYZKLM]\d{7})[A-HJ-NP-TV-Z]$/i,
1285
+ 'et-EE': /^[1-6]\d{6}(00[1-9]|0[1-9][0-9]|[1-6][0-9]{2}|70[0-9]|710)\d$/,
1286
+ 'fi-FI': /^\d{6}[-+A]\d{3}[0-9A-FHJ-NPR-Y]$/i,
1287
+ 'fr-BE': /^\d{11}$/,
1288
+ 'fr-FR': /^[0-3]\d{12}$|^[0-3]\d\s\d{2}(\s\d{3}){3}$/,
1289
+ // Conforms both to official spec and provided example
1290
+ 'fr-LU': /^\d{13}$/,
1291
+ 'hr-HR': /^\d{11}$/,
1292
+ 'hu-HU': /^8\d{9}$/,
1293
+ 'it-IT': /^[A-Z]{6}[L-NP-V0-9]{2}[A-EHLMPRST][L-NP-V0-9]{2}[A-ILMZ][L-NP-V0-9]{3}[A-Z]$/i,
1294
+ 'lv-LV': /^\d{6}-{0,1}\d{5}$/,
1295
+ // Conforms both to DG TAXUD spec and original research
1296
+ 'mt-MT': /^\d{3,7}[APMGLHBZ]$|^([1-8])\1\d{7}$/i,
1297
+ 'nl-NL': /^\d{9}$/,
1298
+ 'pl-PL': /^\d{10,11}$/,
1299
+ 'pt-BR': /(?:^\d{11}$)|(?:^\d{14}$)/,
1300
+ 'pt-PT': /^\d{9}$/,
1301
+ 'ro-RO': /^\d{13}$/,
1302
+ 'sk-SK': /^\d{6}\/{0,1}\d{3,4}$/,
1303
+ 'sl-SI': /^[1-9]\d{7}$/,
1304
+ 'sv-SE': /^(\d{6}[-+]{0,1}\d{4}|(18|19|20)\d{6}[-+]{0,1}\d{4})$/,
1305
+ 'uk-UA': /^\d{10}$/
1306
+ };
1307
+ // taxIdFormat locale aliases
1308
+ taxIdFormat['lb-LU'] = taxIdFormat['fr-LU'];
1309
+ taxIdFormat['lt-LT'] = taxIdFormat['et-EE'];
1310
+ taxIdFormat['nl-BE'] = taxIdFormat['fr-BE'];
1311
+ taxIdFormat['fr-CA'] = taxIdFormat['en-CA'];
1312
+
1313
+ // Algorithmic tax id check functions for various locales
1314
+ var taxIdCheck = {
1315
+ 'bg-BG': bgBgCheck,
1316
+ 'cs-CZ': csCzCheck,
1317
+ 'de-AT': deAtCheck,
1318
+ 'de-DE': deDeCheck,
1319
+ 'dk-DK': dkDkCheck,
1320
+ 'el-CY': elCyCheck,
1321
+ 'el-GR': elGrCheck,
1322
+ 'en-CA': isCanadianSIN,
1323
+ 'en-IE': enIeCheck,
1324
+ 'en-US': enUsCheck,
1325
+ 'es-AR': esArCheck,
1326
+ 'es-ES': esEsCheck,
1327
+ 'et-EE': etEeCheck,
1328
+ 'fi-FI': fiFiCheck,
1329
+ 'fr-BE': frBeCheck,
1330
+ 'fr-FR': frFrCheck,
1331
+ 'fr-LU': frLuCheck,
1332
+ 'hr-HR': hrHrCheck,
1333
+ 'hu-HU': huHuCheck,
1334
+ 'it-IT': itItCheck,
1335
+ 'lv-LV': lvLvCheck,
1336
+ 'mt-MT': mtMtCheck,
1337
+ 'nl-NL': nlNlCheck,
1338
+ 'pl-PL': plPlCheck,
1339
+ 'pt-BR': ptBrCheck,
1340
+ 'pt-PT': ptPtCheck,
1341
+ 'ro-RO': roRoCheck,
1342
+ 'sk-SK': skSkCheck,
1343
+ 'sl-SI': slSiCheck,
1344
+ 'sv-SE': svSeCheck,
1345
+ 'uk-UA': ukUaCheck
1346
+ };
1347
+ // taxIdCheck locale aliases
1348
+ taxIdCheck['lb-LU'] = taxIdCheck['fr-LU'];
1349
+ taxIdCheck['lt-LT'] = taxIdCheck['et-EE'];
1350
+ taxIdCheck['nl-BE'] = taxIdCheck['fr-BE'];
1351
+ taxIdCheck['fr-CA'] = taxIdCheck['en-CA'];
1352
+
1353
+ // Regexes for locales where characters should be omitted before checking format
1354
+ var allsymbols = /[-\\\/!@#$%\^&\*\(\)\+\=\[\]]+/g;
1355
+ var sanitizeRegexes = {
1356
+ 'de-AT': allsymbols,
1357
+ 'de-DE': /[\/\\]/g,
1358
+ 'fr-BE': allsymbols
1359
+ };
1360
+ // sanitizeRegexes locale aliases
1361
+ sanitizeRegexes['nl-BE'] = sanitizeRegexes['fr-BE'];
1362
+
1363
+ /*
1364
+ * Validator function
1365
+ * Return true if the passed string is a valid tax identification number
1366
+ * for the specified locale.
1367
+ * Throw an error exception if the locale is not supported.
1368
+ */
1369
+ export default function isTaxID(str) {
1370
+ var locale = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'en-US';
1371
+ assertString(str);
1372
+ // Copy TIN to avoid replacement if sanitized
1373
+ var strcopy = str.slice(0);
1374
+ if (locale in taxIdFormat) {
1375
+ if (locale in sanitizeRegexes) {
1376
+ strcopy = strcopy.replace(sanitizeRegexes[locale], '');
1377
+ }
1378
+ if (!taxIdFormat[locale].test(strcopy)) {
1379
+ return false;
1380
+ }
1381
+ if (locale in taxIdCheck) {
1382
+ return taxIdCheck[locale](strcopy);
1383
+ }
1384
+ // Fallthrough; not all locales have algorithmic checks
1385
+ return true;
1386
+ }
1387
+ throw new Error("Invalid locale '".concat(locale, "'"));
1388
+ }