nmce-func 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/_func/addressFunc.d.ts +31 -31
  2. package/_func/authentication.service.d.ts +27 -27
  3. package/_func/currencyFunc.d.ts +20 -20
  4. package/_func/dateFunc.d.ts +121 -121
  5. package/_func/htmlPrintFunc.d.ts +18 -18
  6. package/_func/index.d.ts +10 -10
  7. package/_func/javascriptFunc.d.ts +10 -9
  8. package/_func/jsonFunc.d.ts +31 -31
  9. package/_func/stringAusFunc.d.ts +40 -40
  10. package/_func/stringFunc.d.ts +41 -41
  11. package/_func/uuidFunc.d.ts +7 -7
  12. package/{esm2020 → esm2022}/_func/addressFunc.mjs +48 -48
  13. package/esm2022/_func/authentication.service.mjs +48 -0
  14. package/esm2022/_func/currencyFunc.mjs +72 -0
  15. package/{esm2020 → esm2022}/_func/dateFunc.mjs +315 -315
  16. package/{esm2020 → esm2022}/_func/htmlPrintFunc.mjs +39 -39
  17. package/{esm2020 → esm2022}/_func/index.mjs +10 -10
  18. package/esm2022/_func/javascriptFunc.mjs +21 -0
  19. package/{esm2020 → esm2022}/_func/jsonFunc.mjs +66 -66
  20. package/esm2022/_func/stringAusFunc.mjs +200 -0
  21. package/{esm2020 → esm2022}/_func/stringFunc.mjs +92 -92
  22. package/{esm2020 → esm2022}/_func/uuidFunc.mjs +16 -16
  23. package/{esm2020 → esm2022}/nmce-func.mjs +4 -4
  24. package/{esm2020 → esm2022}/public-api.mjs +4 -4
  25. package/{fesm2020 → fesm2022}/nmce-func.mjs +902 -895
  26. package/{fesm2020 → fesm2022}/nmce-func.mjs.map +1 -1
  27. package/index.d.ts +5 -5
  28. package/package.json +5 -11
  29. package/public-api.d.ts +1 -1
  30. package/esm2020/_func/authentication.service.mjs +0 -45
  31. package/esm2020/_func/currencyFunc.mjs +0 -72
  32. package/esm2020/_func/javascriptFunc.mjs +0 -17
  33. package/esm2020/_func/stringAusFunc.mjs +0 -200
  34. package/fesm2015/nmce-func.mjs +0 -933
  35. package/fesm2015/nmce-func.mjs.map +0 -1
@@ -1,41 +1,41 @@
1
- export declare class StringFunc {
2
- /**
3
- * Up to 2 letters. For John Smith, returns JS, for Huang, Zijian, returns ZH
4
- * @param s
5
- */
6
- static getAbbr(s: string | null | undefined): string;
7
- /**
8
- * A substring with line breaks replaced by space.
9
- * @param s
10
- * @param length
11
- * @returns result, or empty string if the input is empty, null or undefined
12
- */
13
- static getOneLineDigest(s: string | null | undefined, length: number): string;
14
- /**
15
- * Remove line breaks and econde with encodeURI() so the data could be saved in Azure as meta. If the string is truncated, the return will have ... suffix.
16
- * @param s
17
- * @param length
18
- * @returns result, or empty string if the input is empty, null or undefined
19
- */
20
- static getOneLineDigestOfHtml(s: string | null | undefined, length: number): string;
21
- /**
22
- * Pad number with zero
23
- * @param num
24
- * @param size
25
- * @returns
26
- */
27
- static pad(num: number | undefined, size: number): string;
28
- /**
29
- * get plain text of HTML content
30
- * @param s
31
- * @returns result. If input is empty, null, or undefined, return the same.
32
- */
33
- static getHtmlPlainText(s: string | null | undefined): string | null;
34
- /**
35
- *
36
- * @param s
37
- * @returns result. If input is empty, null, or undefined, return the same.
38
- */
39
- static capitalizeWords(s: string | null | undefined): string | null | undefined;
40
- static validateEmail(email: string | null | undefined): boolean;
41
- }
1
+ export declare class StringFunc {
2
+ /**
3
+ * Up to 2 letters. For John Smith, returns JS, for Huang, Zijian, returns ZH
4
+ * @param s
5
+ */
6
+ static getAbbr(s: string | null | undefined): string;
7
+ /**
8
+ * A substring with line breaks replaced by space.
9
+ * @param s
10
+ * @param length
11
+ * @returns result, or empty string if the input is empty, null or undefined
12
+ */
13
+ static getOneLineDigest(s: string | null | undefined, length: number): string;
14
+ /**
15
+ * Remove line breaks and econde with encodeURI() so the data could be saved in Azure as meta. If the string is truncated, the return will have ... suffix.
16
+ * @param s
17
+ * @param length
18
+ * @returns result, or empty string if the input is empty, null or undefined
19
+ */
20
+ static getOneLineDigestOfHtml(s: string | null | undefined, length: number): string;
21
+ /**
22
+ * Pad number with zero
23
+ * @param num
24
+ * @param size
25
+ * @returns
26
+ */
27
+ static pad(num: number | undefined, size: number): string;
28
+ /**
29
+ * get plain text of HTML content
30
+ * @param s
31
+ * @returns result. If input is empty, null, or undefined, return the same.
32
+ */
33
+ static getHtmlPlainText(s: string | null | undefined): string | null;
34
+ /**
35
+ *
36
+ * @param s
37
+ * @returns result. If input is empty, null, or undefined, return the same.
38
+ */
39
+ static capitalizeWords(s: string | null | undefined): string | null | undefined;
40
+ static validateEmail(email: string | null | undefined): boolean;
41
+ }
@@ -1,7 +1,7 @@
1
- export declare class UuidFunc {
2
- /**
3
- * 36 UUID string including 4 hyphens. MySql stores GUID as 36 bytes anyway rather than 16bytes.
4
- */
5
- static newUUID(): string;
6
- static newUUIDStartWith0(): string;
7
- }
1
+ export declare class UuidFunc {
2
+ /**
3
+ * 36 UUID string including 4 hyphens. MySql stores GUID as 36 bytes anyway rather than 16bytes.
4
+ */
5
+ static newUUID(): string;
6
+ static newUUIDStartWith0(): string;
7
+ }
@@ -1,49 +1,49 @@
1
- export class AddressFunc {
2
- /**
3
- * Compose to one line separated by comma
4
- * @param st1
5
- * @param st2
6
- * @param city
7
- * @param state
8
- * @param postcode
9
- */
10
- static composeOneLineAddress(st1, st2, city, state, postcode) {
11
- return AddressFunc.composeAddress(st1, st2, city, state, postcode, ', ');
12
- }
13
- /**
14
- * Compose to multiple separated by \n
15
- * @param st1
16
- * @param st2
17
- * @param city
18
- * @param state
19
- * @param postcode
20
- */
21
- static composeMultiLineAddress(st1, st2, city, state, postcode) {
22
- return AddressFunc.composeAddress(st1, st2, city, state, postcode, '\n');
23
- }
24
- /**
25
- * Compose with separator
26
- * @param st1
27
- * @param st2
28
- * @param city
29
- * @param state
30
- * @param postcode
31
- * @param sep
32
- */
33
- static composeAddress(st1, st2, city, state, postcode, sep) {
34
- const r = (st1 ? (st1 + sep) : '') + (st2 ? (st2 + sep) : '') + (city ? (city + sep) : '') + (state ? (state + ' ') : '') + (postcode ? postcode : '');
35
- return r;
36
- }
37
- static composeGoogleMapsAuUrl(st1, st2, city, state, country) {
38
- const googleBaseUrl = 'https://www.google.com.au/maps?hl=en&q=';
39
- const fff = (s) => {
40
- if (!s) {
41
- return '';
42
- }
43
- return '+' + encodeURIComponent(s.replace(' ', '+')) + ',';
44
- };
45
- const ss = fff(st1) + fff(st2) + fff(city) + fff(state) + fff(country);
46
- return googleBaseUrl + ss;
47
- }
48
- }
1
+ export class AddressFunc {
2
+ /**
3
+ * Compose to one line separated by comma
4
+ * @param st1
5
+ * @param st2
6
+ * @param city
7
+ * @param state
8
+ * @param postcode
9
+ */
10
+ static composeOneLineAddress(st1, st2, city, state, postcode) {
11
+ return AddressFunc.composeAddress(st1, st2, city, state, postcode, ', ');
12
+ }
13
+ /**
14
+ * Compose to multiple separated by \n
15
+ * @param st1
16
+ * @param st2
17
+ * @param city
18
+ * @param state
19
+ * @param postcode
20
+ */
21
+ static composeMultiLineAddress(st1, st2, city, state, postcode) {
22
+ return AddressFunc.composeAddress(st1, st2, city, state, postcode, '\n');
23
+ }
24
+ /**
25
+ * Compose with separator
26
+ * @param st1
27
+ * @param st2
28
+ * @param city
29
+ * @param state
30
+ * @param postcode
31
+ * @param sep
32
+ */
33
+ static composeAddress(st1, st2, city, state, postcode, sep) {
34
+ const r = (st1 ? (st1 + sep) : '') + (st2 ? (st2 + sep) : '') + (city ? (city + sep) : '') + (state ? (state + ' ') : '') + (postcode ? postcode : '');
35
+ return r;
36
+ }
37
+ static composeGoogleMapsAuUrl(st1, st2, city, state, country) {
38
+ const googleBaseUrl = 'https://www.google.com.au/maps?hl=en&q=';
39
+ const fff = (s) => {
40
+ if (!s) {
41
+ return '';
42
+ }
43
+ return '+' + encodeURIComponent(s.replace(' ', '+')) + ',';
44
+ };
45
+ const ss = fff(st1) + fff(st2) + fff(city) + fff(state) + fff(country);
46
+ return googleBaseUrl + ss;
47
+ }
48
+ }
49
49
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWRkcmVzc0Z1bmMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9ubWNlLWZ1bmMvc3JjL19mdW5jL2FkZHJlc3NGdW5jLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sT0FBTyxXQUFXO0lBQ3ZCOzs7Ozs7O09BT0c7SUFDSCxNQUFNLENBQUMscUJBQXFCLENBQUMsR0FBdUIsRUFBRSxHQUF1QixFQUFFLElBQXdCLEVBQUUsS0FBeUIsRUFBRSxRQUE0QjtRQUMvSixPQUFPLFdBQVcsQ0FBQyxjQUFjLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMxRSxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILE1BQU0sQ0FBQyx1QkFBdUIsQ0FBQyxHQUF1QixFQUFFLEdBQXVCLEVBQUUsSUFBd0IsRUFBRSxLQUF5QixFQUFFLFFBQTRCO1FBQ2pLLE9BQU8sV0FBVyxDQUFDLGNBQWMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzFFLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILE1BQU0sQ0FBQyxjQUFjLENBQUMsR0FBdUIsRUFBRSxHQUF1QixFQUFFLElBQXdCLEVBQUUsS0FBeUIsRUFBRSxRQUE0QixFQUFFLEdBQXVCO1FBQ2pMLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDdkosT0FBTyxDQUFDLENBQUM7SUFDVixDQUFDO0lBRUQsTUFBTSxDQUFDLHNCQUFzQixDQUFDLEdBQXVCLEVBQUUsR0FBdUIsRUFBRSxJQUF3QixFQUFFLEtBQXlCLEVBQUUsT0FBMkI7UUFDL0osTUFBTSxhQUFhLEdBQUcseUNBQXlDLENBQUM7UUFDaEUsTUFBTSxHQUFHLEdBQUcsQ0FBQyxDQUFxQixFQUFVLEVBQUU7WUFDN0MsSUFBSSxDQUFDLENBQUMsRUFBRTtnQkFDUCxPQUFPLEVBQUUsQ0FBQzthQUNWO1lBRUQsT0FBTyxHQUFHLEdBQUcsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUM7UUFDNUQsQ0FBQyxDQUFDO1FBRUYsTUFBTSxFQUFFLEdBQUcsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQztRQUN2RSxPQUFPLGFBQWEsR0FBRyxFQUFFLENBQUM7SUFDM0IsQ0FBQztDQUVEIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0IGNsYXNzIEFkZHJlc3NGdW5jIHtcclxuXHQvKipcclxuXHQgKiBDb21wb3NlIHRvIG9uZSBsaW5lIHNlcGFyYXRlZCBieSBjb21tYVxyXG5cdCAqIEBwYXJhbSBzdDFcclxuXHQgKiBAcGFyYW0gc3QyXHJcblx0ICogQHBhcmFtIGNpdHlcclxuXHQgKiBAcGFyYW0gc3RhdGVcclxuXHQgKiBAcGFyYW0gcG9zdGNvZGVcclxuXHQgKi9cclxuXHRzdGF0aWMgY29tcG9zZU9uZUxpbmVBZGRyZXNzKHN0MTogc3RyaW5nIHwgdW5kZWZpbmVkLCBzdDI6IHN0cmluZyB8IHVuZGVmaW5lZCwgY2l0eTogc3RyaW5nIHwgdW5kZWZpbmVkLCBzdGF0ZTogc3RyaW5nIHwgdW5kZWZpbmVkLCBwb3N0Y29kZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcclxuXHRcdHJldHVybiBBZGRyZXNzRnVuYy5jb21wb3NlQWRkcmVzcyhzdDEsIHN0MiwgY2l0eSwgc3RhdGUsIHBvc3Rjb2RlLCAnLCAnKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENvbXBvc2UgdG8gbXVsdGlwbGUgc2VwYXJhdGVkIGJ5IFxcblxyXG5cdCAqIEBwYXJhbSBzdDFcclxuXHQgKiBAcGFyYW0gc3QyXHJcblx0ICogQHBhcmFtIGNpdHlcclxuXHQgKiBAcGFyYW0gc3RhdGVcclxuXHQgKiBAcGFyYW0gcG9zdGNvZGVcclxuXHQgKi9cclxuXHRzdGF0aWMgY29tcG9zZU11bHRpTGluZUFkZHJlc3Moc3QxOiBzdHJpbmcgfCB1bmRlZmluZWQsIHN0Mjogc3RyaW5nIHwgdW5kZWZpbmVkLCBjaXR5OiBzdHJpbmcgfCB1bmRlZmluZWQsIHN0YXRlOiBzdHJpbmcgfCB1bmRlZmluZWQsIHBvc3Rjb2RlOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xyXG5cdFx0cmV0dXJuIEFkZHJlc3NGdW5jLmNvbXBvc2VBZGRyZXNzKHN0MSwgc3QyLCBjaXR5LCBzdGF0ZSwgcG9zdGNvZGUsICdcXG4nKTtcclxuXHR9XHJcblxyXG5cdC8qKlxyXG5cdCAqIENvbXBvc2Ugd2l0aCBzZXBhcmF0b3JcclxuXHQgKiBAcGFyYW0gc3QxXHJcblx0ICogQHBhcmFtIHN0MlxyXG5cdCAqIEBwYXJhbSBjaXR5XHJcblx0ICogQHBhcmFtIHN0YXRlXHJcblx0ICogQHBhcmFtIHBvc3Rjb2RlXHJcblx0ICogQHBhcmFtIHNlcFxyXG5cdCAqL1xyXG5cdHN0YXRpYyBjb21wb3NlQWRkcmVzcyhzdDE6IHN0cmluZyB8IHVuZGVmaW5lZCwgc3QyOiBzdHJpbmcgfCB1bmRlZmluZWQsIGNpdHk6IHN0cmluZyB8IHVuZGVmaW5lZCwgc3RhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCwgcG9zdGNvZGU6IHN0cmluZyB8IHVuZGVmaW5lZCwgc2VwOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcge1xyXG5cdFx0Y29uc3QgciA9IChzdDEgPyAoc3QxICsgc2VwKSA6ICcnKSArIChzdDIgPyAoc3QyICsgc2VwKSA6ICcnKSArIChjaXR5ID8gKGNpdHkgKyBzZXApIDogJycpICsgKHN0YXRlID8gKHN0YXRlICsgJyAnKSA6ICcnKSArIChwb3N0Y29kZSA/IHBvc3Rjb2RlIDogJycpO1xyXG5cdFx0cmV0dXJuIHI7XHJcblx0fVxyXG5cclxuXHRzdGF0aWMgY29tcG9zZUdvb2dsZU1hcHNBdVVybChzdDE6IHN0cmluZyB8IHVuZGVmaW5lZCwgc3QyOiBzdHJpbmcgfCB1bmRlZmluZWQsIGNpdHk6IHN0cmluZyB8IHVuZGVmaW5lZCwgc3RhdGU6IHN0cmluZyB8IHVuZGVmaW5lZCwgY291bnRyeTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nIHtcclxuXHRcdGNvbnN0IGdvb2dsZUJhc2VVcmwgPSAnaHR0cHM6Ly93d3cuZ29vZ2xlLmNvbS5hdS9tYXBzP2hsPWVuJnE9JztcclxuXHRcdGNvbnN0IGZmZiA9IChzOiBzdHJpbmcgfCB1bmRlZmluZWQpOiBzdHJpbmcgPT4ge1xyXG5cdFx0XHRpZiAoIXMpIHtcclxuXHRcdFx0XHRyZXR1cm4gJyc7XHJcblx0XHRcdH1cclxuXHJcblx0XHRcdHJldHVybiAnKycgKyBlbmNvZGVVUklDb21wb25lbnQocy5yZXBsYWNlKCcgJywgJysnKSkgKyAnLCc7XHJcblx0XHR9O1xyXG5cclxuXHRcdGNvbnN0IHNzID0gZmZmKHN0MSkgKyBmZmYoc3QyKSArIGZmZihjaXR5KSArIGZmZihzdGF0ZSkgKyBmZmYoY291bnRyeSk7XHJcblx0XHRyZXR1cm4gZ29vZ2xlQmFzZVVybCArIHNzO1xyXG5cdH1cclxuXHJcbn1cclxuIl19
@@ -0,0 +1,48 @@
1
+ import { Inject, Injectable } from '@angular/core';
2
+ import { map } from 'rxjs/operators';
3
+ import * as i0 from "@angular/core";
4
+ import * as i1 from "@angular/common/http";
5
+ /**
6
+ * Login and saving tokens in sessionStorage.
7
+ * App needs to provide constant 'auth.tokenUrl'.
8
+ */
9
+ export class AuthenticationService {
10
+ authUri;
11
+ http;
12
+ username;
13
+ constructor(authUri, http) {
14
+ this.authUri = authUri;
15
+ this.http = http;
16
+ }
17
+ /**
18
+ * Login and save tokens to sessionStorage then return an observable.
19
+ * @param username
20
+ * @param password
21
+ */
22
+ login(username, password, headers) {
23
+ const body = 'username=' + username + '&password=' + password + '&grant_type=password';
24
+ const contentTypeHeader = { 'content-type': 'application/x-www-form-urlencoded; charset=UTF-8' };
25
+ const mergedHeaders = headers ? { ...contentTypeHeader, ...headers } : contentTypeHeader;
26
+ const options = { headers: mergedHeaders };
27
+ return this.http.post(this.authUri, body, options)
28
+ .pipe(map(response => {
29
+ //sessionStorage.setItem('access_token', response.access_token); The client code is response to doing these.
30
+ //sessionStorage.setItem('expires_in', response.expires_in.toString());
31
+ //sessionStorage.setItem('token_type', response.token_type);
32
+ //sessionStorage.setItem('issued', response.issued);
33
+ //sessionStorage.setItem('expires', response.expires); // often up to 2 weeks by default in Asp.net identity 2.
34
+ this.username = response.username;
35
+ //APP_STATUSES.userName = this.userName;
36
+ return response;
37
+ }));
38
+ }
39
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.3", ngImport: i0, type: AuthenticationService, deps: [{ token: 'auth.tokenUrl' }, { token: i1.HttpClient }], target: i0.ɵɵFactoryTarget.Injectable });
40
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.3", ngImport: i0, type: AuthenticationService });
41
+ }
42
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.3", ngImport: i0, type: AuthenticationService, decorators: [{
43
+ type: Injectable
44
+ }], ctorParameters: function () { return [{ type: undefined, decorators: [{
45
+ type: Inject,
46
+ args: ['auth.tokenUrl']
47
+ }] }, { type: i1.HttpClient }]; } });
48
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aGVudGljYXRpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25tY2UtZnVuYy9zcmMvX2Z1bmMvYXV0aGVudGljYXRpb24uc2VydmljZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFDQSxPQUFPLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNuRCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7OztBQUVyQzs7O0dBR0c7QUFFSCxNQUFNLE9BQU8scUJBQXFCO0lBR1k7SUFBeUI7SUFGdEUsUUFBUSxDQUFVO0lBRWxCLFlBQTZDLE9BQWUsRUFBVSxJQUFnQjtRQUF6QyxZQUFPLEdBQVAsT0FBTyxDQUFRO1FBQVUsU0FBSSxHQUFKLElBQUksQ0FBWTtJQUN0RixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILEtBQUssQ0FBQyxRQUFnQixFQUFFLFFBQWdCLEVBQUUsT0FBYTtRQUN0RCxNQUFNLElBQUksR0FBRyxXQUFXLEdBQUcsUUFBUSxHQUFHLFlBQVksR0FBRyxRQUFRLEdBQUcsc0JBQXNCLENBQUM7UUFDdkYsTUFBTSxpQkFBaUIsR0FBRyxFQUFFLGNBQWMsRUFBRSxrREFBa0QsRUFBRSxDQUFDO1FBQ2pHLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxHQUFHLGlCQUFpQixFQUFFLEdBQUcsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDO1FBQ3pGLE1BQU0sT0FBTyxHQUFHLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxDQUFDO1FBQzNDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBT2xCLElBQUksQ0FBQyxPQUFPLEVBQUUsSUFBSSxFQUFFLE9BQU8sQ0FBQzthQUM3QixJQUFJLENBQUMsR0FBRyxDQUNSLFFBQVEsQ0FBQyxFQUFFO1lBQ1YsNEdBQTRHO1lBQzVHLHVFQUF1RTtZQUN2RSw0REFBNEQ7WUFDNUQsb0RBQW9EO1lBQ3BELCtHQUErRztZQUMvRyxJQUFJLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQyxRQUFRLENBQUM7WUFDbEMsd0NBQXdDO1lBQ3hDLE9BQU8sUUFBUSxDQUFDO1FBQ2pCLENBQUMsQ0FFRCxDQUFDLENBQUM7SUFDTCxDQUFDO3VHQXJDVyxxQkFBcUIsa0JBR2IsZUFBZTsyR0FIdkIscUJBQXFCOzsyRkFBckIscUJBQXFCO2tCQURqQyxVQUFVOzswQkFJRyxNQUFNOzJCQUFDLGVBQWUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xyXG5pbXBvcnQgeyBJbmplY3QsIEluamVjdGFibGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5cclxuLyoqXHJcbiAqIExvZ2luIGFuZCBzYXZpbmcgdG9rZW5zIGluIHNlc3Npb25TdG9yYWdlLlxyXG4gKiBBcHAgbmVlZHMgdG8gcHJvdmlkZSBjb25zdGFudCAnYXV0aC50b2tlblVybCcuXHJcbiAqL1xyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBBdXRoZW50aWNhdGlvblNlcnZpY2Uge1xyXG5cdHVzZXJuYW1lPzogc3RyaW5nO1xyXG5cclxuXHRjb25zdHJ1Y3RvcihASW5qZWN0KCdhdXRoLnRva2VuVXJsJykgcHJpdmF0ZSBhdXRoVXJpOiBzdHJpbmcsIHByaXZhdGUgaHR0cDogSHR0cENsaWVudCkge1xyXG5cdH1cclxuXHJcblx0LyoqXHJcblx0ICogTG9naW4gYW5kIHNhdmUgdG9rZW5zIHRvIHNlc3Npb25TdG9yYWdlIHRoZW4gcmV0dXJuIGFuIG9ic2VydmFibGUuXHJcblx0ICogQHBhcmFtIHVzZXJuYW1lXHJcblx0ICogQHBhcmFtIHBhc3N3b3JkXHJcblx0ICovXHJcblx0bG9naW4odXNlcm5hbWU6IHN0cmluZywgcGFzc3dvcmQ6IHN0cmluZywgaGVhZGVycz86IGFueSkge1xyXG5cdFx0Y29uc3QgYm9keSA9ICd1c2VybmFtZT0nICsgdXNlcm5hbWUgKyAnJnBhc3N3b3JkPScgKyBwYXNzd29yZCArICcmZ3JhbnRfdHlwZT1wYXNzd29yZCc7XHJcblx0XHRjb25zdCBjb250ZW50VHlwZUhlYWRlciA9IHsgJ2NvbnRlbnQtdHlwZSc6ICdhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLTgnIH07XHJcblx0XHRjb25zdCBtZXJnZWRIZWFkZXJzID0gaGVhZGVycyA/IHsgLi4uY29udGVudFR5cGVIZWFkZXIsIC4uLmhlYWRlcnMgfSA6IGNvbnRlbnRUeXBlSGVhZGVyO1xyXG5cdFx0Y29uc3Qgb3B0aW9ucyA9IHsgaGVhZGVyczogbWVyZ2VkSGVhZGVycyB9O1xyXG5cdFx0cmV0dXJuIHRoaXMuaHR0cC5wb3N0PHtcclxuXHRcdFx0YWNjZXNzX3Rva2VuOiBzdHJpbmc7XHJcblx0XHRcdGV4cGlyZXM6IHN0cmluZztcclxuXHRcdFx0ZXhwaXJlc19pbjogbnVtYmVyO1xyXG5cdFx0XHRpc3N1ZWQ6IHN0cmluZztcclxuXHRcdFx0dG9rZW5fdHlwZTogc3RyaW5nO1xyXG5cdFx0XHR1c2VybmFtZTogc3RyaW5nO1xyXG5cdFx0fT4odGhpcy5hdXRoVXJpLCBib2R5LCBvcHRpb25zKVxyXG5cdFx0XHQucGlwZShtYXAoXHJcblx0XHRcdFx0cmVzcG9uc2UgPT4ge1xyXG5cdFx0XHRcdFx0Ly9zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCdhY2Nlc3NfdG9rZW4nLCByZXNwb25zZS5hY2Nlc3NfdG9rZW4pOyBUaGUgY2xpZW50IGNvZGUgaXMgcmVzcG9uc2UgdG8gZG9pbmcgdGhlc2UuXHJcblx0XHRcdFx0XHQvL3Nlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ2V4cGlyZXNfaW4nLCByZXNwb25zZS5leHBpcmVzX2luLnRvU3RyaW5nKCkpO1xyXG5cdFx0XHRcdFx0Ly9zZXNzaW9uU3RvcmFnZS5zZXRJdGVtKCd0b2tlbl90eXBlJywgcmVzcG9uc2UudG9rZW5fdHlwZSk7XHJcblx0XHRcdFx0XHQvL3Nlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ2lzc3VlZCcsIHJlc3BvbnNlLmlzc3VlZCk7XHJcblx0XHRcdFx0XHQvL3Nlc3Npb25TdG9yYWdlLnNldEl0ZW0oJ2V4cGlyZXMnLCByZXNwb25zZS5leHBpcmVzKTsgLy8gb2Z0ZW4gdXAgdG8gMiB3ZWVrcyBieSBkZWZhdWx0IGluIEFzcC5uZXQgaWRlbnRpdHkgMi5cclxuXHRcdFx0XHRcdHRoaXMudXNlcm5hbWUgPSByZXNwb25zZS51c2VybmFtZTtcclxuXHRcdFx0XHRcdC8vQVBQX1NUQVRVU0VTLnVzZXJOYW1lID0gdGhpcy51c2VyTmFtZTtcclxuXHRcdFx0XHRcdHJldHVybiByZXNwb25zZTtcclxuXHRcdFx0XHR9XHJcblxyXG5cdFx0XHQpKTtcclxuXHR9XHJcblxyXG59XHJcbiJdfQ==
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Currency calculations. Undefined input of number is considered zero, just like null.
3
+ */
4
+ export class CurrencyFunc {
5
+ static DECIMAL_SEPARATOR = '.';
6
+ static THOUSANDS_SEPARATOR = ',';
7
+ static PADDING = '000000';
8
+ /**
9
+ *
10
+ * @param num
11
+ * @param decimalPlaces default 0
12
+ */
13
+ static bankerRound(num, decimalPlaces) {
14
+ if (!num) {
15
+ return 0;
16
+ }
17
+ const d = decimalPlaces || 0;
18
+ const m = Math.pow(10, d);
19
+ const n = +(d ? num * m : num).toFixed(8); // Avoid rounding errors
20
+ const i = Math.floor(n), f = n - i;
21
+ const e = 1e-8; // Allow for rounding errors in f
22
+ const r = (f > 0.5 - e && f < 0.5 + e) ?
23
+ ((i % 2 === 0) ? i : i + 1) : Math.round(n);
24
+ return d ? r / m : r;
25
+ }
26
+ static bankerRoundTo5cents(num) {
27
+ if (!num) {
28
+ return 0;
29
+ }
30
+ const r = this.bankerRound(Math.ceil(num * 20 - 0.5) / 20, 2);
31
+ return r;
32
+ }
33
+ static ceilTo5cents(num) {
34
+ if (!num) {
35
+ return 0;
36
+ }
37
+ const r = this.bankerRound(Math.ceil(num * 20) / 20, 4);
38
+ const roundup = Math.ceil(r * 10000) / 10000;
39
+ return roundup;
40
+ }
41
+ static transformCurrency(value, fractionSize = 2) {
42
+ let [integer, fraction = ''] = (value || '').toString()
43
+ .split(this.DECIMAL_SEPARATOR);
44
+ fraction = fractionSize > 0
45
+ ? this.DECIMAL_SEPARATOR + (fraction + this.PADDING).substring(0, fractionSize)
46
+ : '';
47
+ integer = integer.replace(/\B(?=(\d{3})+(?!\d))/g, this.THOUSANDS_SEPARATOR);
48
+ return integer + fraction;
49
+ }
50
+ static parseCurrency(value, fractionSize = 2) {
51
+ let [integer, fraction = ''] = (value || '').split(this.DECIMAL_SEPARATOR);
52
+ integer = integer.replace(new RegExp(this.THOUSANDS_SEPARATOR, 'g'), '');
53
+ fraction = parseInt(fraction, 10) > 0 && fractionSize > 0
54
+ ? this.DECIMAL_SEPARATOR + (fraction + this.PADDING).substring(0, fractionSize)
55
+ : '';
56
+ return integer + fraction;
57
+ }
58
+ //http://stackoverflow.com/questions/2998784/how-to-output-integers-with-leading-zeros-in-javascript
59
+ static pad(num, size) {
60
+ num = null;
61
+ let s = num + '';
62
+ while (s.length < size) {
63
+ s = '0' + s;
64
+ }
65
+ return s;
66
+ }
67
+ static sum(ns) {
68
+ const r = ns.reduce((a, b) => (a ?? 0) + (b ?? 0), 0);
69
+ return r;
70
+ }
71
+ }
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VycmVuY3lGdW5jLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbm1jZS1mdW5jL3NyYy9fZnVuYy9jdXJyZW5jeUZ1bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7O0dBRUc7QUFDSCxNQUFNLE9BQU8sWUFBWTtJQUNoQixNQUFNLENBQUMsaUJBQWlCLEdBQUcsR0FBRyxDQUFDO0lBQy9CLE1BQU0sQ0FBQyxtQkFBbUIsR0FBRyxHQUFHLENBQUM7SUFFakMsTUFBTSxDQUFDLE9BQU8sR0FBRyxRQUFRLENBQUM7SUFFbEM7Ozs7T0FJRztJQUNILE1BQU0sQ0FBQyxXQUFXLENBQUMsR0FBOEIsRUFBRSxhQUFzQjtRQUN4RSxJQUFJLENBQUMsR0FBRyxFQUFFO1lBQ1QsT0FBTyxDQUFDLENBQUM7U0FDVDtRQUVELE1BQU0sQ0FBQyxHQUFHLGFBQWEsSUFBSSxDQUFDLENBQUM7UUFDN0IsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDMUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsd0JBQXdCO1FBQ25FLE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDbkMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsaUNBQWlDO1FBQ2pELE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3ZDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENB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QUksQ0FBQyxHQUFHLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDakIsT0FBTyxDQUFDLENBQUMsTUFBTSxHQUFHLElBQUksRUFBRTtZQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDO1NBQUU7UUFDeEMsT0FBTyxDQUFDLENBQUM7SUFDVixDQUFDO0lBRUQsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFpQztRQUMzQyxNQUFNLENBQUMsR0FBVyxFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDOUQsT0FBTyxDQUFDLENBQUM7SUFDVixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXHJcbiAqIEN1cnJlbmN5IGNhbGN1bGF0aW9ucy4gVW5kZWZpbmVkIGlucHV0IG9mIG51bWJlciBpcyBjb25zaWRlcmVkIHplcm8sIGp1c3QgbGlrZSBudWxsLlxyXG4gKi9cclxuZXhwb3J0IGNsYXNzIEN1cnJlbmN5RnVuYyB7XHJcblx0cHJpdmF0ZSBzdGF0aWMgREVDSU1BTF9TRVBBUkFUT1IgPSAnLic7XHJcblx0cHJpdmF0ZSBzdGF0aWMgVEhPVVNBTkRTX1NFUEFSQVRPUiA9ICcsJztcclxuXHJcblx0cHJpdmF0ZSBzdGF0aWMgUEFERElORyA9ICcwMDAwMDAnO1xyXG5cclxuXHQvKipcclxuXHQgKlxyXG5cdCAqIEBwYXJhbSBudW1cclxuXHQgKiBAcGFyYW0gZGVjaW1hbFBsYWNlcyBkZWZhdWx0IDBcclxuXHQgKi9cclxuXHRzdGF0aWMgYmFua2VyUm91bmQobnVtOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkLCBkZWNpbWFsUGxhY2VzPzogbnVtYmVyKTogbnVtYmVyIHsvL2h0dHA6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvMzEwODk4Ni9nYXVzc2lhbi1iYW5rZXJzLXJvdW5kaW5nLWluLWphdmFzY3JpcHRcclxuXHRcdGlmICghbnVtKSB7XHJcblx0XHRcdHJldHVybiAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IGQgPSBkZWNpbWFsUGxhY2VzIHx8IDA7XHJcblx0XHRjb25zdCBtID0gTWF0aC5wb3coMTAsIGQpO1xyXG5cdFx0Y29uc3QgbiA9ICsoZCA/IG51bSAqIG0gOiBudW0pLnRvRml4ZWQoOCk7IC8vIEF2b2lkIHJvdW5kaW5nIGVycm9yc1xyXG5cdFx0Y29uc3QgaSA9IE1hdGguZmxvb3IobiksIGYgPSBuIC0gaTtcclxuXHRcdGNvbnN0IGUgPSAxZS04OyAvLyBBbGxvdyBmb3Igcm91bmRpbmcgZXJyb3JzIGluIGZcclxuXHRcdGNvbnN0IHIgPSAoZiA+IDAuNSAtIGUgJiYgZiA8IDAuNSArIGUpID9cclxuXHRcdFx0KChpICUgMiA9PT0gMCkgPyBpIDogaSArIDEpIDogTWF0aC5yb3VuZChuKTtcclxuXHRcdHJldHVybiBkID8gciAvIG0gOiByO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIGJhbmtlclJvdW5kVG81Y2VudHMobnVtOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcclxuXHRcdGlmICghbnVtKSB7XHJcblx0XHRcdHJldHVybiAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IHIgPSB0aGlzLmJhbmtlclJvdW5kKE1hdGguY2VpbChudW0gKiAyMCAtIDAuNSkgLyAyMCwgMik7XHJcblx0XHRyZXR1cm4gcjtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBjZWlsVG81Y2VudHMobnVtOiBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkKTogbnVtYmVyIHtcclxuXHRcdGlmICghbnVtKSB7XHJcblx0XHRcdHJldHVybiAwO1xyXG5cdFx0fVxyXG5cclxuXHRcdGNvbnN0IHIgPSB0aGlzLmJhbmtlclJvdW5kKE1hdGguY2VpbChudW0gKiAyMCkgLyAyMCwgNCk7XHJcblx0XHRjb25zdCByb3VuZHVwID0gTWF0aC5jZWlsKHIgKiAxMDAwMCkgLyAxMDAwMDtcclxuXHRcdHJldHVybiByb3VuZHVwO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHRyYW5zZm9ybUN1cnJlbmN5KHZhbHVlOiBudW1iZXIgfCBzdHJpbmcgfCB1bmRlZmluZWQsIGZyYWN0aW9uU2l6ZTogbnVtYmVyID0gMik6IHN0cmluZyB7XHJcblx0XHRsZXQgW2ludGVnZXIsIGZyYWN0aW9uID0gJyddID0gKHZhbHVlIHx8ICcnKS50b1N0cmluZygpXHJcblx0XHRcdC5zcGxpdCh0aGlzLkRFQ0lNQUxfU0VQQVJBVE9SKTtcclxuXHJcblx0XHRmcmFjdGlvbiA9IGZyYWN0aW9uU2l6ZSA+IDBcclxuXHRcdFx0PyB0aGlzLkRFQ0lNQUxfU0VQQVJBVE9SICsgKGZyYWN0aW9uICsgdGhpcy5QQURESU5HKS5zdWJzdHJpbmcoMCwgZnJhY3Rpb25TaXplKVxyXG5cdFx0XHQ6ICcnO1xyXG5cclxuXHRcdGludGVnZXIgPSBpbnRlZ2VyLnJlcGxhY2UoL1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csIHRoaXMuVEhPVVNBTkRTX1NFUEFSQVRPUik7XHJcblxyXG5cdFx0cmV0dXJuIGludGVnZXIgKyBmcmFjdGlvbjtcclxuXHR9XHJcblxyXG5cdHN0YXRpYyBwYXJzZUN1cnJlbmN5KHZhbHVlOiBzdHJpbmcgfCB1bmRlZmluZWQsIGZyYWN0aW9uU2l6ZTogbnVtYmVyID0gMik6IHN0cmluZyB7XHJcblx0XHRsZXQgW2ludGVnZXIsIGZyYWN0aW9uID0gJyddID0gKHZhbHVlIHx8ICcnKS5zcGxpdCh0aGlzLkRFQ0lNQUxfU0VQQVJBVE9SKTtcclxuXHJcblx0XHRpbnRlZ2VyID0gaW50ZWdlci5yZXBsYWNlKG5ldyBSZWdFeHAodGhpcy5USE9VU0FORFNfU0VQQVJBVE9SLCAnZycpLCAnJyk7XHJcblxyXG5cdFx0ZnJhY3Rpb24gPSBwYXJzZUludChmcmFjdGlvbiwgMTApID4gMCAmJiBmcmFjdGlvblNpemUgPiAwXHJcblx0XHRcdD8gdGhpcy5ERUNJTUFMX1NFUEFSQVRPUiArIChmcmFjdGlvbiArIHRoaXMuUEFERElORykuc3Vic3RyaW5nKDAsIGZyYWN0aW9uU2l6ZSlcclxuXHRcdFx0OiAnJztcclxuXHJcblx0XHRyZXR1cm4gaW50ZWdlciArIGZyYWN0aW9uO1xyXG5cdH1cclxuXHJcblxyXG5cdC8vaHR0cDovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8yOTk4Nzg0L2hvdy10by1vdXRwdXQtaW50ZWdlcnMtd2l0aC1sZWFkaW5nLXplcm9zLWluLWphdmFzY3JpcHRcclxuXHRzdGF0aWMgcGFkKG51bTogbnVtYmVyIHwgbnVsbCB8IHVuZGVmaW5lZCwgc2l6ZTogbnVtYmVyKTogc3RyaW5nIHtcclxuXHJcblx0XHRudW0gPSBudWxsO1xyXG5cdFx0bGV0IHMgPSBudW0gKyAnJztcclxuXHRcdHdoaWxlIChzLmxlbmd0aCA8IHNpemUpIHsgcyA9ICcwJyArIHM7IH1cclxuXHRcdHJldHVybiBzO1xyXG5cdH1cclxuXHJcblx0c3RhdGljIHN1bShuczogKG51bWJlciB8IG51bGwgfCB1bmRlZmluZWQpW10pOiBudW1iZXIge1xyXG5cdFx0Y29uc3QgciA9IDxudW1iZXI+bnMucmVkdWNlKChhLCBiKSA9PiAoYSA/PyAwKSArIChiID8/IDApLCAwKTtcclxuXHRcdHJldHVybiByO1xyXG5cdH1cclxuXHJcbn1cclxuIl19