zavadil-ts-common 2.2.0 → 2.2.1
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.
- package/dist/index.d.ts +26 -25
- package/dist/index.esm.js +1 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/oauth/OAuthRestClient.d.ts +1 -35
- package/dist/oauth/OAuthTokenManager.d.ts +2 -1
- package/dist/oauth/OAuthUtil.d.ts +19 -0
- package/dist/oauth/RestClientWithOAuth.d.ts +1 -1
- package/dist/oauth/Types.d.ts +35 -0
- package/dist/oauth/index.d.ts +2 -0
- package/dist/oauth/tokenprovider/OAuthRefreshTokenProvider.d.ts +1 -1
- package/dist/oauth/tokenprovider/RefreshTokenProviderDefault.d.ts +1 -1
- package/dist/oauth/tokenprovider/RefreshTokenProviderLogin.d.ts +1 -1
- package/dist/oauth/tokenprovider/RefreshTokenProviderStorage.d.ts +1 -1
- package/dist/oauth/tokenprovider/RefreshTokenProviderUrl.d.ts +1 -1
- package/dist/util/index.d.ts +0 -1
- package/package.json +1 -1
- package/src/oauth/OAuthRestClient.ts +8 -47
- package/src/oauth/OAuthTokenManager.ts +3 -3
- package/src/{util → oauth}/OAuthUtil.ts +2 -7
- package/src/oauth/RestClientWithOAuth.ts +1 -1
- package/src/oauth/Types.ts +47 -0
- package/src/oauth/index.ts +2 -0
- package/src/oauth/tokenprovider/OAuthRefreshTokenProvider.ts +1 -1
- package/src/oauth/tokenprovider/RefreshTokenProviderDefault.ts +1 -1
- package/src/oauth/tokenprovider/RefreshTokenProviderLogin.ts +1 -1
- package/src/oauth/tokenprovider/RefreshTokenProviderStorage.ts +2 -2
- package/src/oauth/tokenprovider/RefreshTokenProviderUrl.ts +2 -3
- package/src/util/index.ts +0 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/cache/LazyAsync.ts","../src/cache/CacheAsync.ts","../src/cache/HashCacheAsync.ts","../src/util/ObjectUtil.ts","../src/util/HashUtil.ts","../src/util/StringUtil.ts","../src/util/ArrayUtil.ts","../src/util/AsyncUtil.ts","../src/util/PagingUtil.ts","../src/util/NumberUtil.ts","../src/util/DateUtil.ts","../src/util/JsonUtil.ts","../src/util/UrlUtil.ts","../src/oauth/OAuthRestClient.ts","../src/oauth/OAuthTokenManager.ts","../src/oauth/tokenprovider/RedirectionProvider.ts","../src/oauth/tokenprovider/RefreshTokenProviderLogin.ts","../src/oauth/tokenprovider/RefreshTokenProviderUrl.ts","../src/oauth/tokenprovider/RefreshTokenProviderStorage.ts","../src/oauth/tokenprovider/RefreshTokenProviderDefault.ts","../src/util/OAuthUtil.ts","../src/client/RestClient.ts","../src/client/EntityClient.ts","../src/component/EventManager.ts","../src/type/UserAlert.ts","../src/vector/Vector2.ts","../src/localization/Dictionary.ts","../src/localization/Localization.ts","../src/util/ByteUtil.ts","../src/component/CancellablePromise.ts","../src/client/EntityCachedClient.ts","../src/client/EntityClientWithStub.ts","../src/cache/Lazy.ts","../src/client/LookupClient.ts","../src/oauth/RestClientWithOAuth.ts","../src/component/UserAlerts.ts"],"sourcesContent":["export class LazyAsync<T> {\n\n\tprotected cache?: T;\n\n\tprotected supplier: () => Promise<T>;\n\n\tprivate promise?: Promise<T>;\n\n\tconstructor(supplier: () => Promise<T>) {\n\t\tthis.supplier = supplier;\n\t}\n\n\tget(): Promise<T> {\n\t\tif (this.cache !== undefined) {\n\t\t\treturn Promise.resolve(this.cache);\n\t\t}\n\n\t\tif (this.promise === undefined) {\n\t\t\tthis.promise = this.supplier()\n\t\t\t\t.then((v: T) => {\n\t\t\t\t\tthis.cache = v;\n\t\t\t\t\tthis.promise = undefined;\n\t\t\t\t\treturn Promise.resolve(v);\n\t\t\t\t}).catch((err) => {\n\t\t\t\t\tthis.promise = undefined;\n\t\t\t\t\treturn Promise.reject(err);\n\t\t\t\t});\n\t\t}\n\n\t\treturn this.promise;\n\t}\n\n\treset() {\n\t\tthis.cache = undefined;\n\t}\n\n\thasCache() {\n\t\treturn (this.cache !== undefined);\n\t}\n\n\tgetCache(): T | undefined {\n\t\treturn this.cache;\n\t}\n}\n","import {LazyAsync} from \"./LazyAsync\";\n\nexport class CacheAsync<T> extends LazyAsync<T> {\n\n\tprivate maxAgeMs?: number;\n\n\tprivate expires?: Date;\n\n\tconstructor(supplier: () => Promise<T>, maxAgeMs?: number) {\n\t\tsuper(supplier);\n\t\tthis.maxAgeMs = maxAgeMs;\n\t}\n\n\tget(): Promise<T> {\n\t\tif (this.expires && this.expires > new Date()) {\n\t\t\tthis.reset();\n\t\t}\n\t\treturn super.get();\n\t}\n\n\tset(v: T, expires?: Date) {\n\t\tthis.cache = v;\n\t\tthis.expires = expires;\n\t\tif (this.maxAgeMs && this.expires === undefined) {\n\t\t\tthis.expires = new Date(new Date().getTime() + this.maxAgeMs);\n\t\t}\n\t}\n\n}\n","import { HashCacheStats } from \"../type\";\nimport {CacheAsync} from \"./CacheAsync\";\n\nexport class HashCacheAsync<K, V> {\n\n\tprivate cache = new Map<K, CacheAsync<V>>;\n\n\tprivate supplier: (k: K) => Promise<V>;\n\n\tprivate maxSize: number = 100;\n\n\tconstructor(supplier: (k: K) => Promise<V>, maxSize?: number) {\n\t\tthis.supplier = supplier;\n\t\tif (maxSize) this.maxSize = maxSize;\n\t}\n\n\tprotected obtainCache(k: K): CacheAsync<V> {\n\t\tlet c = this.cache.get(k);\n\t\tif (!c) {\n\t\t\tc = new CacheAsync(() => this.supplier(k));\n\t\t\tthis.cache.set(k, c);\n\t\t}\n\t\treturn c;\n\t}\n\n\tget(k: K): Promise<V> {\n\t\treturn this.obtainCache(k).get();\n\t}\n\n\tset(k: K, v: V, expires?: Date){\n\t\tthis.obtainCache(k).set(v, expires);\n\t}\n\n\treset(k?: K) {\n\t\tif (!k) {\n\t\t\tthis.cache.clear();\n\t\t} else {\n\t\t\tthis.cache.delete(k);\n\t\t}\n\t}\n\n\tgetSize() {\n\t\treturn this.cache.size;\n\t}\n\n\tgetMaxSize() {\n\t\treturn this.maxSize;\n\t}\n\n\tgetStats(): HashCacheStats {\n\t\treturn {\n\t\t\tcachedItems: this.getSize(),\n\t\t\tcapacity: this.getMaxSize()\n\t\t}\n\t}\n\n\thasCache(k: K) {\n\t\treturn this.cache.has(k);\n\t}\n}\n","export class ObjectUtil {\r\n\r\n\tstatic isEmpty(obj: any): obj is null | undefined {\r\n\t\treturn obj === undefined || obj === null;\r\n\t}\r\n\r\n\tstatic notEmpty(obj: any): obj is object {\r\n\t\treturn !ObjectUtil.isEmpty(obj);\r\n\t}\r\n\r\n\tstatic clone<T>(obj: T): T {\r\n\t\tif (obj === null) {\r\n\t\t\tthrow new Error(\"Null cannot be cloned!\");\r\n\t\t}\r\n\t\tif (typeof obj !== 'object') {\r\n\t\t\tthrow new Error(\"Not an object, cannot be cloned!\");\r\n\t\t}\r\n\t\treturn {...obj};\r\n\t}\r\n\r\n\tstatic getNestedValue(obj: any, path: string): string {\r\n\t\tif (!obj || obj === '') return '';\r\n\r\n\t\tconst keys = path.split('.');\r\n\r\n\t\tlet current = obj;\r\n\t\tfor (const key of keys) {\r\n\t\t\tif (current && typeof current === 'object' && key in current) {\r\n\t\t\t\tcurrent = current[key];\r\n\t\t\t} else {\r\n\t\t\t\treturn '';\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn current;\r\n\t}\r\n\r\n}\r\n","export class HashUtil {\n\n\tstatic crc32hex(str: string): string {\n\t\t// Encode string to UTF-8 bytes\n\t\tconst encoder = new TextEncoder();\n\t\tconst data = encoder.encode(str);\n\n\t\t// Generate CRC32 table once\n\t\tconst table = new Uint32Array(256);\n\t\tfor (let i = 0; i < 256; i++) {\n\t\t\tlet c = i;\n\t\t\tfor (let j = 0; j < 8; j++) {\n\t\t\t\tc = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);\n\t\t\t}\n\t\t\ttable[i] = c >>> 0;\n\t\t}\n\n\t\tlet crc = 0 ^ -1;\n\t\tfor (let i = 0; i < data.length; i++) {\n\t\t\tcrc = (crc >>> 8) ^ table[(crc ^ data[i]) & 0xFF];\n\t\t}\n\t\tcrc = (crc ^ -1) >>> 0;\n\n\t\treturn crc.toString(16);\n\t}\n}\n","import {HashUtil} from \"./HashUtil\";\nimport {ObjectUtil} from \"./ObjectUtil\";\n\nexport class StringUtil {\n\tstatic isString(s: any): boolean {\n\t\treturn typeof s === \"string\";\n\t}\n\n\tstatic toString(s: any): string {\n\t\tif (StringUtil.isString(s)) return s;\n\t\tif (StringUtil.isString(s.message)) return s.message; // Errors\n\t\treturn s?.toString?.() ?? \"\";\n\t}\n\n\tstatic isEmpty(str: string | null | undefined): str is null | undefined {\n\t\tif (ObjectUtil.isEmpty(str)) return true;\n\t\treturn str.length === 0;\n\t}\n\n\tstatic notEmpty(str: string | null | undefined): str is string {\n\t\treturn !StringUtil.isEmpty(str);\n\t}\n\n\tstatic isBlank(str: string | null | undefined): str is null | undefined | \"\" {\n\t\treturn StringUtil.isEmpty(StringUtil.safeTrim(str));\n\t}\n\n\tstatic notBlank(str: string | null | undefined): str is string {\n\t\treturn !StringUtil.isBlank(str);\n\t}\n\n\tstatic substr(\n\t\tstr: string | null | undefined,\n\t\tstart: number,\n\t\tlength?: number,\n\t): string {\n\t\tif (this.isEmpty(str)) return \"\";\n\n\t\t// @ts-ignore\n\t\treturn str.substring(start, length);\n\t}\n\n\tstatic replace(\n\t\tstr: string | null | undefined,\n\t\tfind?: null | string,\n\t\treplace?: string,\n\t): string {\n\t\tif (this.isEmpty(str) || this.isEmpty(find)) return \"\";\n\t\treturn str.replace(find, String(replace));\n\t}\n\n\tstatic containsLineBreaks(str: string | null | undefined): str is string {\n\t\treturn StringUtil.safeContains(str, \"\\n\");\n\t}\n\n\tstatic safeContains(haystack: string | null | undefined, needle: string | null | undefined, caseSensitive: boolean = true): haystack is string {\n\t\tif (StringUtil.isBlank(haystack) || StringUtil.isBlank(needle)) return false;\n\t\tif (caseSensitive) return StringUtil.safeContains(haystack.toLowerCase(), needle.toLowerCase(), false);\n\t\treturn haystack.includes(needle);\n\t}\n\n\tstatic trimLeadingSlashes(str: string | null): string {\n\t\tif (this.isEmpty(str)) return \"\";\n\t\treturn StringUtil.toString(str).replace(/^\\//g, \"\");\n\t}\n\n\tstatic trimTrailingSlashes(str: string | null): string {\n\t\tif (this.isEmpty(str)) return \"\";\n\t\treturn StringUtil.toString(str).replace(/\\/$/g, \"\");\n\t}\n\n\tstatic trimSlashes(str: string | null): string {\n\t\tif (this.isEmpty(str)) return \"\";\n\t\treturn StringUtil.toString(str).replace(/^\\/|\\/$/g, \"\");\n\t}\n\n\tstatic safeTruncate(\n\t\tstr: string | null | undefined,\n\t\tlen: number,\n\t\tellipsis: string = \"\",\n\t): string {\n\t\tif (StringUtil.isEmpty(str) || !str) return \"\";\n\t\tstr = StringUtil.toString(str);\n\t\tif (str.length <= len) return String(str);\n\t\treturn str.substring(0, len - ellipsis.length) + ellipsis;\n\t}\n\n\tstatic ellipsis(\n\t\tstr: string | null | undefined,\n\t\tlen: number,\n\t\tellipsis: string = \"...\",\n\t): string {\n\t\treturn StringUtil.safeTruncate(str, len, ellipsis);\n\t}\n\n\tstatic safeTrim(str: string | null | undefined): string {\n\t\tif (StringUtil.isEmpty(str)) return \"\";\n\t\treturn StringUtil.toString(str).trim();\n\t}\n\n\tstatic safeLowercase(str: string | null | undefined): string {\n\t\tif (StringUtil.isEmpty(str) || !str) return \"\";\n\t\treturn StringUtil.toString(str).toLowerCase();\n\t}\n\n\tstatic safeUppercase(str: string | null | undefined): string {\n\t\tif (StringUtil.isEmpty(str) || !str) return \"\";\n\t\treturn StringUtil.toString(str).toUpperCase();\n\t}\n\n\tstatic capitalizeFirstLetter(str: string | null | undefined): string {\n\t\tif (StringUtil.isBlank(str)) return \"\";\n\t\treturn (\n\t\t\tStringUtil.safeUppercase(str.charAt(0)) +\n\t\t\tStringUtil.safeLowercase(StringUtil.substr(str, 1))\n\t\t);\n\t}\n\n\tstatic toBigInt(str: string | null): bigint | null {\n\t\tif (this.isEmpty(str)) return null;\n\n\t\t// @ts-ignore\n\t\treturn BigInt(str);\n\t}\n\n\tstatic getNonEmpty(...args: Array<string | null | undefined>): string {\n\t\treturn args.find((a) => StringUtil.notEmpty(a)) || \"\";\n\t}\n\n\tstatic getNonBlank(...args: Array<string | null | undefined>): string {\n\t\treturn args.find((a) => StringUtil.notBlank(a)) || \"\";\n\t}\n\n\tstatic emptyToNull(str: string | null | undefined): string | null {\n\t\treturn StringUtil.isEmpty(str) ? null : String(str);\n\t}\n\n\tstatic blankToNull(str: string | null | undefined): string | null {\n\t\treturn StringUtil.isBlank(str) ? null : String(str);\n\t}\n\n\tstatic randomString(): string {\n\t\treturn HashUtil.crc32hex(Date() + Math.random());\n\t}\n}\n","import { ObjectUtil } from \"./ObjectUtil\";\r\n\r\nexport class ArrayUtil {\r\n\r\n\tstatic isEmpty(arr?: Array<any> | null): boolean {\r\n\t\t// @ts-ignore\r\n\t\treturn ObjectUtil.isEmpty(arr) || arr.length === 0;\r\n\t}\r\n\r\n\tstatic notEmpty(arr?: Array<any> | null): arr is Array<any> {\r\n\t\treturn !ArrayUtil.isEmpty(arr);\r\n\t}\r\n\r\n\tstatic remove(arr?: Array<any> | null, element?: any): Array<any> {\r\n\t\tif (ArrayUtil.isEmpty(arr)) return [];\r\n\t\t// @ts-ignore\r\n\t\treturn arr?.filter(e => e !== element);\r\n\t}\r\n\r\n\tstatic extract(arr?: Array<any> | null, start: number = 0, length?: number): Array<any> {\r\n\t\tif ((!arr) || arr.length <= start) return [];\r\n\t\tconst end = length === undefined ? undefined : start + length;\r\n\t\treturn arr.slice(start, end);\r\n\t}\r\n\r\n\tstatic extractStart(arr: Array<any> | null | undefined, length: number): Array<any> {\r\n\t\treturn ArrayUtil.extract(arr, 0, length);\r\n\t}\r\n\r\n}\r\n","export class AsyncUtil {\n\tstatic sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n}\n","import {PagingRequest, SortingField, SortingRequest} from \"../type\";\nimport {StringUtil} from \"./StringUtil\";\n\nexport const FIRST_PAGE: PagingRequest = {page: 0, size: 10};\n\nexport class PagingUtil {\n\n\tstatic sortingFieldToString(s: SortingField): string {\n\t\tif (!s) return '';\n\t\tconst parts = [];\n\t\tparts.push(s.name);\n\t\tparts.push(s.desc ? 'desc' : '');\n\t\tparts.push(s.nullsLast ? 'nl' : '');\n\t\treturn parts.join('-');\n\t}\n\n\tstatic sortingFieldFromString(s: string): SortingField {\n\t\tconst arr = s.split('-');\n\t\treturn {\n\t\t\tname: arr[0],\n\t\t\tdesc: arr.length > 1 && StringUtil.safeLowercase(arr[1]) === 'desc',\n\t\t\tnullsLast: arr.length > 2 && StringUtil.safeLowercase(arr[2]) === 'nl'\n\t\t}\n\t}\n\n\tstatic sortingRequestToString(s: SortingRequest): string | undefined {\n\t\treturn s.map((s: SortingField) => PagingUtil.sortingFieldToString(s)).join('+');\n\t}\n\n\tstatic sortingRequestFromString(s?: string | null): SortingRequest {\n\t\tif (!s) return [];\n\t\tconst arr = s.split('+');\n\t\treturn arr.map((s) => PagingUtil.sortingFieldFromString(s));\n\t}\n\n\tstatic pagingRequestToQueryParams(pr?: PagingRequest | null): any {\n\t\tif (!pr) return;\n\t\tconst result: any = {\n\t\t\tpage: pr.page,\n\t\t\tsize: pr.size\n\t\t}\n\t\tif (pr.search) {\n\t\t\tresult.search = pr.search;\n\t\t}\n\t\tif (pr.sorting) {\n\t\t\tresult.sorting = PagingUtil.sortingRequestToString(pr.sorting);\n\t\t}\n\t\treturn result;\n\t}\n\n\tstatic pagingRequestToString(pr?: PagingRequest): string {\n\t\tif (!pr) return '';\n\t\tconst arr = [];\n\t\tarr.push(String(pr.page));\n\t\tarr.push(String(pr.size));\n\t\tarr.push(StringUtil.safeTrim(pr.search));\n\t\tarr.push(pr.sorting ? PagingUtil.sortingRequestToString(pr.sorting) : '');\n\t\treturn arr.join(':');\n\t}\n\n\tstatic pagingRequestFromString(pr?: string): PagingRequest {\n\t\tif (!pr || StringUtil.isEmpty(pr)) return {...FIRST_PAGE};\n\t\tconst arr = pr.split(':');\n\t\tif (arr.length < 4) return {...FIRST_PAGE};\n\t\treturn {\n\t\t\tpage: Number(arr[0]),\n\t\t\tsize: Number(arr[1]),\n\t\t\tsearch: String(arr[2]),\n\t\t\tsorting: StringUtil.isEmpty(arr[3]) ? undefined : PagingUtil.sortingRequestFromString(arr[3])\n\t\t}\n\t}\n\n}\n","export class NumberUtil {\r\n\r\n\tstatic isEmpty(n: any): n is null | undefined {\r\n\t\treturn n === undefined || n === null || Number.isNaN(n);\r\n\t}\r\n\r\n\tstatic notEmpty(n?: number | null): n is number {\r\n\t\treturn !NumberUtil.isEmpty(n);\r\n\t}\r\n\r\n\tstatic parseNumber(str: string | null | undefined): number | null {\r\n\t\tif (!str) return null;\r\n\t\tconst n = Number(str);\r\n\t\treturn Number.isNaN(n) ? null : n;\r\n\t}\r\n\r\n\tstatic round(n: number, d?: number) {\r\n\t\tif (!d) d = 0;\r\n\t\tconst c = Math.pow(10, d);\r\n\t\treturn Math.round( n * c) / c;\r\n\t}\r\n\r\n\tstatic portionToPercent(p: number, d?: number): string {\r\n\t\tif (p === null || p === undefined) return '';\r\n\t\tconst n = NumberUtil.round(p * 100, d);\r\n\t\treturn `${n}%`\r\n\t}\r\n\r\n}\r\n","import {ObjectUtil} from \"./ObjectUtil\";\r\nimport {NumberUtil} from \"./NumberUtil\";\r\n\r\nexport class DateUtil {\r\n\r\n\tstatic formatNumber(n: number, digits = 2) {\r\n\t\tconst s = String(n);\r\n\t\treturn s.padStart(digits, '0');\r\n\t}\r\n\r\n\tstatic parseDate(d: Date | string | null | undefined): Date | undefined {\r\n\t\tif (!d) return undefined;\r\n\t\tif (typeof d === 'string') {\r\n\t\t\treturn new Date(d);\r\n\t\t}\r\n\t\treturn d;\r\n\t}\r\n\r\n\tstatic formatDateForHumans(d: Date | string | null | undefined, showTime: boolean = false): string {\r\n\t\td = DateUtil.parseDate(d);\r\n\t\tif (!d) return '';\r\n\r\n\t\tconst year = d.getFullYear();\r\n\t\tconst month = DateUtil.formatNumber(d.getMonth() + 1);\r\n\t\tconst day = DateUtil.formatNumber(d.getDate());\r\n\r\n\t\tif (!showTime) {\r\n\t\t\treturn `${year}-${month}-${day}`;\r\n\t\t}\r\n\r\n\t\tconst hours = DateUtil.formatNumber(d.getHours());\r\n\t\tconst minutes = DateUtil.formatNumber(d.getMinutes());\r\n\t\tconst seconds = DateUtil.formatNumber(d.getSeconds());\r\n\t\treturn `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;\r\n\t}\r\n\r\n\tstatic formatDateTimeForHumans(d: Date | string | null | undefined): string {\r\n\t\treturn DateUtil.formatDateForHumans(d, true);\r\n\t}\r\n\r\n\tstatic formatDateForInput(d: any, showTime: boolean = false): string {\r\n\t\td = DateUtil.parseDate(d);\r\n\t\tif (!d) return '';\r\n\t\tconst year = d.getFullYear();\r\n\t\tconst month = DateUtil.formatNumber(d.getMonth() + 1);\r\n\t\tconst day = DateUtil.formatNumber(d.getDate());\r\n\r\n\t\tif (!showTime) {\r\n\t\t\treturn `${year}-${month}-${day}`;\r\n\t\t}\r\n\r\n\t\tconst hours = DateUtil.formatNumber(d.getHours());\r\n\t\tconst minutes = DateUtil.formatNumber(d.getMinutes());\r\n\t\tconst seconds = DateUtil.formatNumber(d.getSeconds());\r\n\t\treturn `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;\r\n\t}\r\n\r\n\tstatic formatDateTimeForInput(d: Date | string | null | undefined): string {\r\n\t\treturn DateUtil.formatDateForInput(d, true);\r\n\t}\r\n\r\n\tstatic getDurationMs(d1?: Date | string | null, d2?: Date | string | null): number | null {\r\n\t\td1 = DateUtil.parseDate(d1);\r\n\t\td2 = DateUtil.parseDate(d2);\r\n\t\tif (ObjectUtil.isEmpty(d1) || ObjectUtil.isEmpty(d2)) return null;\r\n\t\ttry {\r\n\t\t\t// @ts-ignore\r\n\t\t\treturn d2.getTime() - d1.getTime();\r\n\t\t} catch (e) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t}\r\n\r\n\tstatic getSinceDurationMs(d1?: Date | string | null): number | null {\r\n\t\treturn DateUtil.getDurationMs(d1, new Date());\r\n\t}\r\n\r\n\tstatic formatDuration(ms?: number | null): string {\r\n\t\tif (!ms) {\r\n\t\t\treturn '';\r\n\t\t}\r\n\r\n\t\tlet secs = Math.floor(ms / 1000);\r\n\t\tms -= secs * 1000;\r\n\t\tlet mins = Math.floor(secs / 60);\r\n\t\tsecs -= mins * 60;\r\n\t\tlet hrs = Math.floor(mins / 60);\r\n\t\tmins -= hrs * 60;\r\n\t\tlet days = Math.floor(hrs / 24);\r\n\t\thrs -= days * 24;\r\n\r\n\t\tconst items = [];\r\n\t\tif (days > 0) items.push(`${days}d`);\r\n\t\tif (hrs > 0) items.push(`${hrs}h`);\r\n\t\tif (mins > 0) items.push(`${mins}m`);\r\n\t\tif (secs > 0 && days === 0 && hrs === 0) items.push(`${secs}s`);\r\n\t\tif (ms > 0 && days === 0 && hrs === 0 && mins === 0) items.push(`${NumberUtil.round(ms, 2)}ms`);\r\n\r\n\t\treturn items.join(' ');\r\n\t}\r\n}\r\n","import {StringUtil} from \"./StringUtil\";\n\nexport class JsonUtil {\n\n\tstatic reISO = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*))(?:Z|(\\+|-)([\\d|:]*))?$/;\n\n\tstatic dateParser(key: string, value: any): any {\n\t\tif (typeof value === 'string' && JsonUtil.reISO.exec(value)) return new Date(value);\n\t\treturn value;\n\t}\n\n\tstatic parseWithDates(json?: string | null): any {\n\t\tif (StringUtil.isBlank(json)) return undefined;\n\t\treturn JSON.parse(StringUtil.getNonEmpty(json), JsonUtil.dateParser);\n\t}\n\n\tstatic parse(json?: string | null): any {\n\t\treturn JsonUtil.parseWithDates(json);\n\t}\n}\n","import {StringUtil} from \"./StringUtil\";\n\nexport class UrlUtil {\n\n\tstatic deleteParamFromUrl(url: string, paramName: string): string {\n\t\tconst urlObj = new URL(url);\n\t\turlObj.searchParams.delete(paramName);\n\t\treturn StringUtil.trimTrailingSlashes(urlObj.toString());\n\t}\n\n\tstatic extractParamFromUrl(url: string, name: string): string | null {\n\t\tconst usp = new URLSearchParams(new URL(url).search);\n\t\treturn usp.get(name);\n\t}\n\n\tstatic paramExistsInUrl(url: string, name: string): boolean {\n\t\treturn StringUtil.notBlank(UrlUtil.extractParamFromUrl(url, name));\n\t}\n\n\tstatic extractHostFromUrl(url: string): string | null {\n\t\tif (StringUtil.isBlank(url)) return null;\n\t\treturn new URL(url).host;\n\t}\n\n\tstatic extractDomainFromUrl(url: string): string | null {\n\t\tconst host = UrlUtil.extractHostFromUrl(url);\n\t\tif (StringUtil.isBlank(host)) return null;\n\t\treturn host.split('.').slice(-2).join('.');\n\t}\n}\n","import { RestClient } from \"../client\";\nimport { StringUtil } from \"../util\";\n\nexport const PERMISSION_LEVELS = [\"read\", \"write\", \"admin\"] as const;\n\nexport type PermissionLevel = (typeof PERMISSION_LEVELS)[number];\n\nexport type TokenRequestPayloadBase = {\n targetAudience: string;\n};\n\nexport type RequestAccessTokenPayload = TokenRequestPayloadBase & {\n refreshToken: string;\n scope: string;\n};\n\nexport type RenewRefreshTokenPayload = {\n refreshToken: string;\n};\n\nexport type RequestRefreshTokenFromLoginPayload = TokenRequestPayloadBase & {\n login: string;\n password: string;\n};\n\nexport type TokenResponsePayloadBase = {\n token: string;\n issuedAt: Date;\n expires?: Date | null;\n};\n\nexport type IdTokenPayload = TokenResponsePayloadBase & {};\n\nexport type AccessTokenPayload = TokenResponsePayloadBase & {\n scopes?: Array<string>;\n};\n\nexport type RefreshTokenPayload = TokenResponsePayloadBase & {};\n\nexport type JwKeyPayload = {\n kty: string;\n kid: string;\n n: string;\n e: string;\n};\n\nexport type JwksPayload = {\n keys: Array<JwKeyPayload>;\n};\n\n/**\n * This implements rest client for OAuth server - https://github.com/lotcz/oauth-server\n * Provide basic url, /api/oauth path prefix will be added automatically\n */\nexport class OAuthRestClient extends RestClient {\n constructor(oauthUrl: string) {\n super(`${StringUtil.trimSlashes(oauthUrl)}/api/oauth`);\n }\n\n jwks(): Promise<JwksPayload> {\n return this.getJson(\"jwks.json\");\n }\n\n verifyRefreshToken(refreshToken: string): Promise<RefreshTokenPayload> {\n return this.getJson(`refresh-tokens/verify/${refreshToken}`);\n }\n\n verifyAccessToken(accessToken: string): Promise<AccessTokenPayload> {\n return this.getJson(`access-tokens/verify/${accessToken}`);\n }\n\n verifyIdToken(idToken: string): Promise<IdTokenPayload> {\n return this.getJson(`id-tokens/verify/${idToken}`);\n }\n\n requestRefreshTokenFromLogin(\n request: RequestRefreshTokenFromLoginPayload,\n ): Promise<RefreshTokenPayload> {\n return this.postJson(\"refresh-tokens/from-login\", request);\n }\n\n renewRefreshToken(\n request: RenewRefreshTokenPayload,\n ): Promise<RefreshTokenPayload> {\n return this.postJson(\"refresh-tokens/renew\", request);\n }\n\n requestAccessToken(\n request: RequestAccessTokenPayload,\n ): Promise<AccessTokenPayload> {\n return this.postJson(\"access-tokens/from-refresh-token\", request);\n }\n}\n","import {\n\tAccessTokenPayload,\n\tIdTokenPayload,\n\tOAuthRestClient,\n\tRefreshTokenPayload,\n} from \"./OAuthRestClient\";\nimport {OAuthRefreshTokenProvider} from \"./tokenprovider/OAuthRefreshTokenProvider\";\nimport {OAuthUtil} from \"../util/OAuthUtil\";\n\n/**\n * Manages refresh of id and access tokens.\n */\nexport class OAuthTokenManager implements OAuthRefreshTokenProvider {\n\toAuthServer: OAuthRestClient;\n\n\taudience: string;\n\n\trefreshToken?: RefreshTokenPayload;\n\n\tinitialRefreshTokenProvider: OAuthRefreshTokenProvider;\n\n\taccessTokens: Map<string, AccessTokenPayload>;\n\n\tconstructor(\n\t\toAuthServerBaseUrl: string,\n\t\ttargetAudience: string,\n\t\tinitialRefreshTokenProvider: OAuthRefreshTokenProvider,\n\t) {\n\t\tthis.initialRefreshTokenProvider = initialRefreshTokenProvider;\n\t\tthis.audience = targetAudience;\n\t\tthis.oAuthServer = new OAuthRestClient(oAuthServerBaseUrl);\n\t\tthis.accessTokens = new Map<string, AccessTokenPayload>();\n\t}\n\n\thasValidRefreshToken(): boolean {\n\t\treturn OAuthUtil.isValidToken(this.refreshToken);\n\t}\n\n\thasValidAccessToken(privilege: string): boolean {\n\t\treturn OAuthUtil.isValidToken(this.accessTokens.get(privilege));\n\t}\n\n\treset(): Promise<any> {\n\t\tthis.refreshToken = undefined;\n\t\tthis.accessTokens.clear();\n\t\treturn this.initialRefreshTokenProvider.reset();\n\t}\n\n\t/**\n\t * Get stored id token or ask the provider, this will trigger redirect to login screen in case of the default provider\n\t */\n\tgetRefreshTokenInternal(): Promise<RefreshTokenPayload> {\n\t\tif (this.refreshToken !== undefined && this.hasValidRefreshToken()) {\n\t\t\treturn Promise.resolve(this.refreshToken);\n\t\t}\n\t\treturn this.initialRefreshTokenProvider.getRefreshToken();\n\t}\n\n\t/**\n\t * Get id token, refresh it if needed\n\t */\n\tgetRefreshToken(): Promise<IdTokenPayload> {\n\t\treturn this.getRefreshTokenInternal().then(\n\t\t\t(t: RefreshTokenPayload) => {\n\t\t\t\tif (!OAuthUtil.isValidToken(t)) {\n\t\t\t\t\tconsole.log(\"invalid refresh token\", t);\n\t\t\t\t\treturn Promise.reject(\"Received invalid refresh token!\");\n\t\t\t\t}\n\t\t\t\tif (OAuthUtil.isTokenReadyForRefresh(t)) {\n\t\t\t\t\treturn this.oAuthServer\n\t\t\t\t\t\t.renewRefreshToken({refreshToken: t.token})\n\t\t\t\t\t\t.then((t) => {\n\t\t\t\t\t\t\tthis.setRefreshToken(t);\n\t\t\t\t\t\t\treturn t;\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis.setRefreshToken(t);\n\t\t\t\treturn Promise.resolve(t);\n\t\t\t}\n\t\t);\n\t}\n\n\tgetRefreshTokenRaw(): Promise<string> {\n\t\treturn this.getRefreshToken().then((t) => t.token);\n\t}\n\n\tsetRefreshToken(token?: RefreshTokenPayload) {\n\t\tthis.refreshToken = token;\n\t}\n\n\tverifyRefreshToken(token: string): Promise<RefreshTokenPayload> {\n\t\treturn this.oAuthServer.verifyRefreshToken(token);\n\t}\n\n\tlogin(login: string, password: string): Promise<RefreshTokenPayload> {\n\t\tthis.reset();\n\t\treturn this.oAuthServer\n\t\t\t.requestRefreshTokenFromLogin({\n\t\t\t\tlogin: login,\n\t\t\t\tpassword: password,\n\t\t\t\ttargetAudience: this.audience,\n\t\t\t})\n\t\t\t.then((t) => {\n\t\t\t\tthis.setRefreshToken(t);\n\t\t\t\treturn t;\n\t\t\t});\n\t}\n\n\tprivate storeAccessToken(scope: string, token: AccessTokenPayload) {\n\t\tthis.accessTokens.set(scope, token);\n\t}\n\n\tprivate findStoredAccessToken(scope: string): AccessTokenPayload | undefined {\n\t\tconst level = OAuthUtil.extractPermissionLevel(scope);\n\t\tconst privilege = OAuthUtil.extractPrivilege(scope);\n\t\tfor (const [s, token] of this.accessTokens) {\n\t\t\tif (OAuthUtil.hasPermission(s, privilege, level)) return token;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate getAccessTokenInternal(scope: string): Promise<AccessTokenPayload> {\n\t\treturn this.getRefreshTokenRaw().then(\n\t\t\t(refreshToken: string) => this.oAuthServer\n\t\t\t\t.requestAccessToken(\n\t\t\t\t\t{\n\t\t\t\t\t\trefreshToken: refreshToken,\n\t\t\t\t\t\ttargetAudience: this.audience,\n\t\t\t\t\t\tscope: scope,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\t.then(\n\t\t\t\t\t(act: AccessTokenPayload) => {\n\t\t\t\t\t\tif (!OAuthUtil.isValidToken(act)) {\n\t\t\t\t\t\t\treturn Promise.reject(\"Received access token is not valid!\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (act.scopes && act.scopes.length > 0) {\n\t\t\t\t\t\t\tact.scopes.forEach((s) => this.storeAccessToken(s, act));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.storeAccessToken(scope, act);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn act;\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t);\n\t}\n\n\tgetAccessToken(scope: string): Promise<string> {\n\t\tconst existing = this.findStoredAccessToken(scope);\n\t\tif (existing === undefined || !OAuthUtil.isValidToken(existing))\n\t\t\treturn this.getAccessTokenInternal(scope).then((t) => t.token);\n\t\t// preload access token if it is going to expire soon\n\t\tif (OAuthUtil.isTokenReadyForRefresh(existing))\n\t\t\tthis.getAccessTokenInternal(scope);\n\t\treturn Promise.resolve(existing.token);\n\t}\n}\n","import {StringUtil} from \"../../util\";\n\nexport class RedirectionProvider {\n\n\tprivate redirecting?: string;\n\n\tredirectTo(url: string): Promise<any> {\n\t\tthis.redirecting = url;\n\t\tdocument.location.href = url;\n\t\treturn Promise.reject(`Redirecting to ${url}`);\n\t}\n\n\tisRedirecting(): boolean {\n\t\treturn StringUtil.notBlank(this.redirecting);\n\t}\n\n\tredirectingTo(): string {\n\t\treturn StringUtil.getNonEmpty(this.redirecting);\n\t}\n\n}\n","import {OAuthRefreshTokenProvider} from \"./OAuthRefreshTokenProvider\";\nimport {IdTokenPayload} from \"../OAuthRestClient\";\nimport {RedirectionProvider} from \"./RedirectionProvider\";\nimport {RestClientWithOAuth} from \"../RestClientWithOAuth\";\nimport {UrlUtil} from \"../../util\";\n\nexport class RefreshTokenProviderLogin extends RedirectionProvider implements OAuthRefreshTokenProvider {\n\n\tclient: RestClientWithOAuth;\n\n\ttokenQueryName: string;\n\n\tconstructor(client: RestClientWithOAuth, tokenQueryName?: string) {\n\t\tsuper();\n\t\tthis.client = client;\n\t\tthis.tokenQueryName = tokenQueryName || 'token';\n\t}\n\n\tredirectToLogin(): Promise<any> {\n\t\treturn this.client.getServerInfo().then(\n\t\t\t(si) => {\n\t\t\t\tconst thisUrl = UrlUtil.deleteParamFromUrl(document.location.toString(), this.tokenQueryName);\n\t\t\t\tconst location = `${si.oauthServerUrl}/login?app_name=${si.targetAudience}&redirect_url=${thisUrl}`;\n\t\t\t\treturn this.redirectTo(location);\n\t\t\t}\n\t\t).catch((err) => {\n\t\t\tconsole.error('Redirection failed: OAuth info not fetched:', err);\n\t\t\treturn Promise.reject(err);\n\t\t});\n\t}\n\n\tgetRefreshToken(): Promise<IdTokenPayload> {\n return this.redirectToLogin();\n }\n\n\treset(): Promise<any> {\n\t\treturn Promise.resolve();\n\t}\n}\n","import {OAuthRefreshTokenProvider} from \"./OAuthRefreshTokenProvider\";\nimport {RefreshTokenPayload} from \"../OAuthRestClient\";\nimport {RestClientWithOAuth} from \"../RestClientWithOAuth\";\nimport {StringUtil} from \"../../util\";\nimport {UrlUtil} from \"../../util\";\nimport {RedirectionProvider} from \"./RedirectionProvider\";\n\nexport class RefreshTokenProviderUrl extends RedirectionProvider implements OAuthRefreshTokenProvider {\n\n\tclient: RestClientWithOAuth;\n\n\ttokenQueryName: string;\n\n\tconstructor(client: RestClientWithOAuth, tokenQueryName?: string) {\n\t\tsuper();\n\t\tthis.client = client;\n\t\tthis.tokenQueryName = tokenQueryName || 'token';\n\t}\n\n\tgetRefreshTokenFromUrl(): string | null {\n\t\treturn UrlUtil.extractParamFromUrl(document.location.toString(), this.tokenQueryName);\n\t}\n\n\tgetRefreshToken(): Promise<RefreshTokenPayload> {\n\t\tconst raw = this.getRefreshTokenFromUrl();\n\t\tif (raw === null || StringUtil.isBlank(raw)) return Promise.reject(\"No token in URL!\");\n\t\treturn this.client\n\t\t\t.getTokenManager()\n\t\t\t.then(m => m.verifyRefreshToken(raw));\n }\n\n\treset(): Promise<any> {\n\t\tconst raw = this.getRefreshTokenFromUrl();\n\t\tif (raw === null || StringUtil.isBlank(raw)) return Promise.resolve();\n\t\tconsole.log(\"Token in URL, redirecting...\");\n\t\tconst thisUrl = UrlUtil.deleteParamFromUrl(document.location.toString(), this.tokenQueryName);\n\t\treturn this.redirectTo(thisUrl);\n\t}\n}\n","import {OAuthRefreshTokenProvider} from \"./OAuthRefreshTokenProvider\";\nimport {RefreshTokenPayload} from \"../OAuthRestClient\";\nimport {JsonUtil} from \"../../util\";\nimport {OAuthUtil} from \"../../util/OAuthUtil\";\n\nexport class RefreshTokenProviderStorage implements OAuthRefreshTokenProvider {\n\n\tkey: string;\n\n\tconstructor(storageKey?: string) {\n\t\tthis.key = storageKey || 'refresh-token';\n\t}\n\n\tsaveRefreshTokenToLocalStorage(token: RefreshTokenPayload | null) {\n\t\tconst raw = token ? JSON.stringify(token) : null;\n\t\tif (raw === null) {\n\t\t\tlocalStorage.removeItem(this.key);\n\t\t\treturn;\n\t\t}\n\t\tlocalStorage.setItem(this.key, raw);\n\t}\n\n\tgetRefreshTokenFromLocalStorage(): RefreshTokenPayload | null | undefined {\n\t\treturn JsonUtil.parse(localStorage.getItem(this.key));\n\t}\n\n\tgetRefreshToken(): Promise<RefreshTokenPayload> {\n const token = this.getRefreshTokenFromLocalStorage();\n\t\tif (token && OAuthUtil.isValidToken(token)) return Promise.resolve(token);\n\t\treturn Promise.reject(\"No valid token found in storage!\");\n }\n\n\treset(): Promise<any> {\n\t\tthis.saveRefreshTokenToLocalStorage(null);\n\t\treturn Promise.resolve();\n\t}\n}\n","import {OAuthRefreshTokenProvider} from \"./OAuthRefreshTokenProvider\";\nimport {IdTokenPayload} from \"../OAuthRestClient\";\nimport {RefreshTokenProviderLogin} from \"./RefreshTokenProviderLogin\";\nimport {RestClientWithOAuth} from \"../RestClientWithOAuth\";\nimport {RefreshTokenProviderUrl} from \"./RefreshTokenProviderUrl\";\nimport {RefreshTokenProviderStorage} from \"./RefreshTokenProviderStorage\";\n\nexport class RefreshTokenProviderDefault implements OAuthRefreshTokenProvider {\n\n\tlogin: RefreshTokenProviderLogin;\n\n\turl: RefreshTokenProviderUrl;\n\n\tstorage: RefreshTokenProviderStorage;\n\n\tconstructor(client: RestClientWithOAuth, tokenStorageKey?: string, tokenUrlName?: string) {\n\t\tthis.login = new RefreshTokenProviderLogin(client, tokenUrlName);\n\t\tthis.url = new RefreshTokenProviderUrl(client, tokenUrlName);\n\t\tthis.storage = new RefreshTokenProviderStorage(tokenStorageKey);\n\t}\n\n\tgetRefreshToken(): Promise<IdTokenPayload> {\n\t\treturn this.url\n\t\t\t.getRefreshToken()\n\t\t\t.catch(\n\t\t\t\t(err) => {\n\t\t\t\t\tconsole.log(\"No token in url, loading from storage:\", err);\n\t\t\t\t\treturn this.storage\n\t\t\t\t\t\t.getRefreshToken()\n\t\t\t\t\t\t.catch(\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tconsole.log(\"No token in storage, redirecting to login page:\", err);\n\t\t\t\t\t\t\t\treturn this.login.getRefreshToken();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t)\n\t\t\t.then(\n\t\t\t\t(t) => {\n\t\t\t\t\tconsole.log(\"Token found, saving to storage...\");\n\t\t\t\t\tthis.storage.saveRefreshTokenToLocalStorage(t);\n\t\t\t\t\t// redirect if token is in url\n\t\t\t\t\treturn this.url.reset().then(() => t);\n\t\t\t\t}\n\t\t\t);\n }\n\n\treset(): Promise<any> {\n\t\treturn this.storage.reset().then(() => this.url.reset());\n\t}\n\n}\n","import {\n PermissionLevel,\n PERMISSION_LEVELS,\n TokenResponsePayloadBase,\n} from \"../oauth\";\nimport { StringUtil } from \"./StringUtil\";\nimport { ObjectUtil } from \"./ObjectUtil\";\n\nexport class OAuthUtil {\n static isValidToken(token?: TokenResponsePayloadBase | null): boolean {\n return (\n ObjectUtil.notEmpty(token) &&\n StringUtil.notBlank(token.token) &&\n !OAuthUtil.isTokenExpired(token)\n );\n }\n\n static isTokenExpired(token?: TokenResponsePayloadBase | null): boolean {\n if (token === undefined || token === null) return false;\n if (token.expires === undefined || token.expires === null) return false;\n return token.expires < new Date();\n }\n\n static isTokenReadyForRefresh(\n token?: TokenResponsePayloadBase | null,\n ): boolean {\n if (token === undefined || token === null) return false;\n if (OAuthUtil.isTokenExpired(token)) return false;\n if (token.expires === undefined || token.expires === null) return false;\n const middle = new Date(\n (token.expires.getTime() + token.issuedAt.getTime()) / 2,\n );\n const now = new Date();\n return middle < now;\n }\n\n public static getScopeString(privilege: string, level: PermissionLevel) {\n return `${level}:${privilege}`;\n }\n\n public static extractPrivilege(scope: string): string {\n const arr = scope.split(\":\");\n if (arr.length < 2) return \"\";\n return arr[1];\n }\n\n public static isPermissionLevel(value: string): value is PermissionLevel {\n return (PERMISSION_LEVELS as readonly string[]).includes(value);\n }\n\n public static extractPermissionLevel(scope: string): PermissionLevel {\n const arr = scope.split(\":\");\n if (arr.length === 0) throw new Error(`Scope value ${scope} is invalid!`);\n const str = arr[0];\n if (!OAuthUtil.isPermissionLevel(str))\n throw new Error(`\"${str} is not valid permission level!`);\n return str;\n }\n\n public static getLevel(level: PermissionLevel): number {\n switch (level) {\n case \"admin\":\n return 3;\n case \"write\":\n return 2;\n case \"read\":\n return 1;\n default:\n return 0;\n }\n }\n\n /**\n * Returns true if given scope grants permission for specific privilege on at least required level.\n *\n * @param ownedScope Existing scope, usually owned by user in form of access token\n * @param requiredScopeOrPrivilege Required privilege name or whole scope (omit minLevel)\n * @param minLevel Required minimal permission level\n */\n public static hasPermission(\n ownedScope: string,\n requiredScopeOrPrivilege: string,\n minLevel?: PermissionLevel,\n ): boolean {\n if (minLevel === undefined) {\n try {\n minLevel = OAuthUtil.extractPermissionLevel(requiredScopeOrPrivilege);\n requiredScopeOrPrivilege = OAuthUtil.extractPrivilege(\n requiredScopeOrPrivilege,\n );\n } catch (e) {\n minLevel = \"admin\";\n }\n }\n\n const ownedLevel = OAuthUtil.extractPermissionLevel(ownedScope);\n // owned level must be at least equal to the required\n if (OAuthUtil.getLevel(ownedLevel) < OAuthUtil.getLevel(minLevel))\n return false;\n\n const ownedPrivilege = OAuthUtil.extractPrivilege(ownedScope);\n // super admin, has privilege for all resources\n if (ownedPrivilege === \"*\") return true;\n // user has exactly the required privilege\n if (ownedPrivilege === requiredScopeOrPrivilege) return true;\n // now the only possibility is that user has privilege ending with * covering the required privilege\n if (!ownedPrivilege?.endsWith(\"/*\")) return false;\n\n const ownedParent = ownedPrivilege.replace(\"/*\", \"\");\n return requiredScopeOrPrivilege?.startsWith(ownedParent) ?? false;\n }\n}\n","import { StringUtil, PagingUtil, JsonUtil } from \"../util\";\nimport { PagingRequest } from \"../type\";\n\nexport type RequestOptions = RequestInit & {\n headers: Headers;\n};\n\nexport class RestClient {\n private baseUrl: URL;\n\n constructor(baseUrl: string) {\n if (StringUtil.isBlank(baseUrl)) {\n this.baseUrl = RestClient.baseHostUrl();\n return;\n }\n if (!baseUrl.endsWith(\"/\")) baseUrl = baseUrl + \"/\";\n this.baseUrl = baseUrl.startsWith(\"http\")\n ? new URL(baseUrl)\n : new URL(baseUrl, RestClient.baseHostUrl());\n }\n\n static baseHostUrl(): URL {\n return new URL(`${window.location.protocol}//${window.location.host}/`);\n }\n\n static pagingRequestToQueryParams(pr?: PagingRequest | null): any {\n return PagingUtil.pagingRequestToQueryParams(pr);\n }\n\n static paramsToQueryString(params?: any): string {\n if (!params) return \"\";\n const original = new URLSearchParams(params);\n const cleaned = new URLSearchParams();\n original.forEach((value, key) => {\n if (value !== \"\" && value !== undefined && value !== \"undefined\")\n cleaned.set(key, value);\n });\n const str = cleaned.toString();\n return StringUtil.isEmpty(str) ? \"\" : `?${str}`;\n }\n\n /**\n * Override this to customize http headers.\n */\n getHeaders(endpoint: string): Promise<Headers> {\n const headers = new Headers();\n headers.set(\"Content-Type\", \"application/json\");\n return Promise.resolve(headers);\n }\n\n getBaseUrl(): URL {\n return this.baseUrl;\n }\n\n getUrl(endpoint: string, params?: any): URL {\n const url = new URL(\n StringUtil.trimLeadingSlashes(endpoint),\n this.getBaseUrl(),\n );\n if (params) {\n Object.keys(params).forEach((key) => {\n const value = params[key];\n if (value !== \"\" && value !== undefined && value !== \"undefined\")\n url.searchParams.set(key, value);\n });\n }\n return url;\n }\n\n getRequestOptions(\n endpoint: string,\n method: string = \"GET\",\n data: any = null,\n ): Promise<RequestOptions> {\n return this.getHeaders(endpoint).then((headers) => {\n return {\n method: method,\n headers: headers,\n body:\n data === null\n ? null\n : (data instanceof FormData || typeof data === 'string')\n ? data\n : JSON.stringify(data),\n };\n });\n }\n\n processRequest(\n endpoint: string,\n params?: any,\n requestOptions?: RequestOptions,\n ): Promise<Response> {\n return fetch(this.getUrl(endpoint, params), requestOptions).then(\n (response) => {\n if (!response.ok) {\n const options = { cause: response.status };\n if (response.headers.get(\"Content-Type\") === \"application/json\") {\n return response.json().then(\n (json) => {\n if (json.message) {\n // @ts-ignore\n throw new Error(json.message, options);\n }\n if (json.error) {\n // @ts-ignore\n throw new Error(json.error, options);\n }\n // @ts-ignore\n throw new Error(response.statusText, options);\n },\n () => {\n // @ts-ignore\n throw new Error(response.statusText, options);\n },\n );\n } else {\n return response.text().then(\n (t) => {\n if (StringUtil.isEmpty(t)) {\n // @ts-ignore\n throw new Error(response.statusText, options);\n } else {\n // @ts-ignore\n throw new Error(t, options);\n }\n },\n () => {\n // @ts-ignore\n throw new Error(response.statusText, options);\n },\n );\n }\n }\n return response;\n },\n );\n }\n\n processRequestJson(\n endpoint: string,\n params?: any,\n requestOptions?: RequestOptions,\n ): Promise<any> {\n return this.processRequest(endpoint, params, requestOptions).then(\n (response) => {\n return response.text().then(JsonUtil.parseWithDates);\n },\n );\n }\n\n getJson(url: string, params?: any): Promise<any> {\n return this.getRequestOptions(url).then((o) =>\n this.processRequestJson(url, params, o),\n );\n }\n\n postJson(\n url: string,\n data: object | null = null,\n params?: any,\n ): Promise<any> {\n return this.getRequestOptions(url, \"POST\", data).then((o) =>\n this.processRequestJson(url, params, o),\n );\n }\n\n postForm(url: string, data: FormData, params?: any): Promise<Response> {\n return this.getRequestOptions(url, \"POST\", data).then((o) => {\n o.headers.delete(\"Content-Type\"); // content type with boundary value will be auto-generated\n return this.processRequest(url, params, o);\n });\n }\n\n postFormJson(url: string, data: FormData, params?: any): Promise<any> {\n return this.getRequestOptions(url, \"POST\", data).then((o) => {\n o.headers.delete(\"Content-Type\"); // content type with boundary value will be auto-generated\n return this.processRequestJson(url, params, o);\n });\n }\n\n putJson(url: string, data: object | null = null, params?: any): Promise<any> {\n return this.getRequestOptions(url, \"PUT\", data).then((o) =>\n this.processRequestJson(url, params, o),\n );\n }\n\n get(endpoint: string, params?: any): Promise<Response> {\n return this.getRequestOptions(endpoint).then((o) =>\n this.processRequest(endpoint, params, o),\n );\n }\n\n del(url: string, params?: any): Promise<Response> {\n return this.getRequestOptions(url, \"DELETE\").then((o) =>\n this.processRequest(url, params, o),\n );\n }\n\n post(\n url: string,\n data: any = null,\n params?: any,\n ): Promise<Response> {\n return this.getRequestOptions(url, \"POST\", data).then((o) =>\n this.processRequest(url, params, o),\n );\n }\n\n put(\n url: string,\n data: any = null,\n params?: any,\n ): Promise<Response> {\n return this.getRequestOptions(url, \"PUT\", data).then((o) =>\n this.processRequest(url, params, o),\n );\n }\n}\n","import {EntityBase} from \"../type/Entity\";\r\nimport {RestClient} from \"./RestClient\";\r\nimport {Page, PagingRequest} from \"../type\";\r\n\r\nexport class EntityClient<T extends EntityBase> {\r\n\r\n\tclient: RestClient;\r\n\r\n\tname: string;\r\n\r\n\tconstructor(client: RestClient, name: string) {\r\n\t\tthis.client = client;\r\n\t\tthis.name = name;\r\n\t}\r\n\r\n\tloadSingle(id: number): Promise<T> {\r\n\t\treturn this.client.getJson(`${this.name}/${id}`);\r\n\t}\r\n\r\n\tloadPage(pr: PagingRequest): Promise<Page<T>> {\r\n\t\treturn this.client.getJson(this.name, RestClient.pagingRequestToQueryParams(pr));\r\n\t}\r\n\r\n\tsave(d: T): Promise<T> {\r\n\t\tif (d.id) {\r\n\t\t\treturn this.client.putJson(`${this.name}/${d.id}`, d);\r\n\t\t} else {\r\n\t\t\treturn this.client.postJson(this.name, d);\r\n\t\t}\r\n\t}\r\n\r\n\tdelete(id: number): Promise<any> {\r\n\t\treturn this.client.del(`${this.name}/${id}`);\r\n\t}\r\n\r\n}\r\n","export type Func = { (arg?: any): void; }\r\nexport type FuncHandlers = Array<Func>;\r\nexport type FuncHandlersCache = Map<string, FuncHandlers>;\r\n\r\nexport class EventManager {\r\n\r\n\thandlers: FuncHandlersCache;\r\n\r\n\tconstructor() {\r\n\t\tthis.handlers = new Map<string, FuncHandlers>();\r\n\t}\r\n\r\n\taddEventListener(event: string, handler: Func) {\r\n\t\tif (!this.handlers.has(event)) this.handlers.set(event, []);\r\n\t\t// @ts-ignore\r\n\t\tthis.handlers.get(event).push(handler);\r\n\t}\r\n\r\n\tremoveEventListener(event: string, handler: Func) {\r\n\t\tconst handlers: FuncHandlers | undefined = this.handlers.get(event);\r\n\t\tif (handlers) handlers.splice(handlers.indexOf(handler), 1);\r\n\t}\r\n\r\n\ttriggerEvent(event: string, arg?: any) {\r\n\t\tif (!this.handlers.has(event)) return;\r\n\t\t// @ts-ignore\r\n\t\tthis.handlers.get(event).forEach((h: Func) => h(arg));\r\n\t}\r\n\r\n}\r\n","export enum UserAlertType {\r\n\tinfo = 'info',\r\n\twarning = 'warning',\r\n\terror = 'danger'\r\n}\r\n\r\nexport type UserAlert = {\r\n\ttime: Date;\r\n\ttype: UserAlertType;\r\n\tmessage: string;\r\n\tremainsMs?: number; //remain visible for this amount of seconds\r\n}\r\n","import {NumberUtil} from \"../util\";\r\n\r\nexport class Vector2 {\r\n\tx: number;\r\n\ty: number;\r\n\r\n\tconstructor(x: number, y: number) {\r\n\t\tthis.x = x;\r\n\t\tthis.y = y;\r\n\t}\r\n\r\n\tdistanceTo(v: Vector2) {\r\n\t\treturn Math.sqrt(Math.pow(this.x - v.x, 2) + Math.pow(this.y - v.y, 2));\r\n\t}\r\n\r\n\tequalsTo(v: Vector2) {\r\n\t\treturn (v) ? this.x === v.x && this.y === v.y : false;\r\n\t}\r\n\r\n\tsize() {\r\n\t\treturn this.distanceTo(new Vector2(0, 0));\r\n\t}\r\n\r\n\tinSize(size: number): Vector2 {\r\n\t\tconst currentSize = this.size();\r\n\t\tif (currentSize !== 0) {\r\n\t\t\tconst ratio = size / currentSize;\r\n\t\t\treturn new Vector2(this.x * ratio, this.y * ratio);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\r\n\tround(): Vector2 {\r\n\t\treturn new Vector2(Math.round(this.x), Math.round(this.y));\r\n\t}\r\n\r\n\tadd(v: Vector2): Vector2 {\r\n\t\treturn new Vector2(this.x + v.x, this.y + v.y);\r\n\t}\r\n\r\n\tmultiply(s: number): Vector2 {\r\n\t\treturn new Vector2(this.x * s, this.y * s);\r\n\t}\r\n\r\n\tsubtract(v: Vector2): Vector2 {\r\n\t\treturn new Vector2(this.x - v.x, this.y - v.y);\r\n\t}\r\n\r\n\tsub(v: Vector2): Vector2 {\r\n\t\treturn this.subtract(v);\r\n\t}\r\n\r\n\ttoArray(): number[] {\r\n\t\treturn [this.x, this.y];\r\n\t}\r\n\r\n\tstatic fromArray(arr: number[]) {\r\n\t\tif (typeof arr === 'object' && arr.length === 2) {\r\n\t\t\treturn new Vector2(arr[0], arr[1]);\r\n\t\t}\r\n\t}\r\n\r\n\tclone(): Vector2 {\r\n\t\treturn new Vector2(this.x, this.y);\r\n\t}\r\n\r\n\t/***\r\n\t * Return angle between AB and Y axis in radians\r\n\t * @param {Vector2} b\r\n\t * @returns {number}\r\n\t */\r\n\tgetAngleToYAxis(b: Vector2): number {\r\n\t\tconst diff = b.subtract(this);\r\n\t\tconst down = diff.y < 0;\r\n\t\tconst sinX = diff.x / diff.size();\r\n\t\tconst angle = Math.asin(sinX);\r\n\t\tconst result = down ?\r\n\t\t\tMath.PI - angle :\r\n\t\t\tangle;\r\n\t\treturn result || 0;\r\n\t}\r\n\r\n\tgetNeighborPositions(size = 1, includeCenter = false) {\r\n\t\tconst neighbors = [];\r\n\t\tconst maxX = this.x + size;\r\n\t\tfor (let x = this.x - size; x <= maxX; x++) {\r\n\t\t\tconst maxY = this.y + size;\r\n\t\t\tfor (let y = this.y - size; y <= maxY; y++) {\r\n\t\t\t\tconst n = new Vector2(x, y);\r\n\t\t\t\tif (includeCenter || !this.equalsTo(n)) {\r\n\t\t\t\t\tneighbors.push(n);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn neighbors;\r\n\t}\r\n\r\n\tgetClosest(positions: Vector2[]): Vector2 | null {\r\n\t\tif ((!positions) || positions.length === 0) return null;\r\n\t\tif (positions.length === 1) return positions[0];\r\n\t\tlet closest = positions[0];\r\n\t\tlet distance = this.distanceTo(closest);\r\n\t\tfor (let i = 1, max = positions.length; i < max; i++) {\r\n\t\t\tconst d = this.distanceTo(positions[i]);\r\n\t\t\tif (d < distance) {\r\n\t\t\t\tclosest = positions[i];\r\n\t\t\t\tdistance = d;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn closest;\r\n\t}\r\n\r\n\ttoString(decimals = 2) {\r\n\t\treturn `[${NumberUtil.round(this.x, decimals)},${NumberUtil.round(this.y, decimals)}]`;\r\n\t}\r\n}\r\n","import CzechBasicData from './lang/dictionary.cs.json';\r\nimport EnglishBasicData from './lang/dictionary.en.json';\r\n\r\nexport type TranslateParams = {\r\n\ttags?: Array<string>;\r\n}\r\n\r\nexport interface Dictionary {\r\n\ttranslate: (key: string, p?: TranslateParams) => string | undefined;\r\n}\r\n\r\nexport type DictionaryMemoryValue = {\r\n\ttags?: Array<string>;\r\n\tvalue: string;\r\n}\r\n\r\nexport interface DictionaryMemoryData {\r\n\t[key: string]: string | Array<DictionaryMemoryValue>;\r\n}\r\n\r\nexport class MemoryDictionary implements Dictionary {\r\n\r\n\tprivate data: DictionaryMemoryData;\r\n\r\n\tconstructor(data: DictionaryMemoryData) {\r\n\t\tthis.data = data;\r\n\t}\r\n\r\n\ttranslate(key: string, p?: TranslateParams) {\r\n\t\tconst r = this.data[key];\r\n\t\tif (r === undefined || typeof r === 'string') return r;\r\n\t\tconst def = r.find(\r\n\t\t\t(v) => (v.tags === undefined || v.tags.length === 0)\r\n\t\t);\r\n\t\tif ((p === undefined || p.tags === undefined || p.tags.length === 0) && def !== undefined) return def.value;\r\n\t\tconst cands = r.filter(\r\n\t\t\t(v) => {\r\n\t\t\t\tif (v.tags === undefined || v.tags.length === 0) return false;\r\n\t\t\t\treturn p && p.tags && p.tags.every((t) => v.tags && v.tags.includes(t));\r\n\t\t\t}\r\n\t\t);\r\n\t\tif (cands.length > 0) return cands[0].value;\r\n\t\treturn def ? def.value : undefined;\r\n\t};\r\n\r\n}\r\n\r\nexport class CzechBasicDictionary extends MemoryDictionary {\r\n\tconstructor() {\r\n\t\tsuper(CzechBasicData);\r\n\t}\r\n}\r\n\r\nexport class EnglishBasicDictionary extends MemoryDictionary {\r\n\tconstructor() {\r\n\t\tsuper(EnglishBasicData);\r\n\t}\r\n}\r\n\r\nexport class DictionaryWithFallback implements Dictionary {\r\n\r\n\tprivate primary: Dictionary;\r\n\r\n\tprivate fallback: Dictionary;\r\n\r\n\tconstructor(primary: Dictionary, fallback: Dictionary) {\r\n\t\tthis.primary = primary;\r\n\t\tthis.fallback = fallback;\r\n\t}\r\n\r\n\ttranslate(key: string, p?: TranslateParams) {\r\n\t\tconst pt = this.primary.translate(key, p);\r\n\t\tif (pt === undefined) return this.fallback.translate(key, p);\r\n\t\treturn pt;\r\n\t};\r\n}\r\n","import {CzechBasicDictionary, Dictionary, DictionaryWithFallback, EnglishBasicDictionary, TranslateParams} from \"./Dictionary\";\r\n\r\nexport class Localization implements Dictionary {\r\n\r\n\tprivate language: string | undefined;\r\n\r\n\tprivate dictionaries = new Map<string, Dictionary>;\r\n\r\n\tconstructor(language?: string) {\r\n\t\tthis.setLanguage(language);\r\n\t}\r\n\r\n\taddDictionary(language: string, dictionary: Dictionary) {\r\n\t\tconst existing = this.dictionaries.get(language);\r\n\t\tif (existing) {\r\n\t\t\tthis.dictionaries.set(language, new DictionaryWithFallback(dictionary, existing));\r\n\t\t} else {\r\n\t\t\tthis.dictionaries.set(language, dictionary);\r\n\t\t}\r\n\t}\r\n\r\n\thasDictionary(language?: string) {\r\n\t\tif (!language) return false;\r\n\t\treturn this.dictionaries.has(language);\r\n\t}\r\n\r\n\tgetLanguage(): string | undefined {\r\n\t\treturn this.language;\r\n\t}\r\n\r\n\tgetLanguages(): Array<string> {\r\n\t\treturn Array.from(this.dictionaries.keys());\r\n\t}\r\n\r\n\tsetLanguage(language?: string) {\r\n\t\tthis.language = language && this.hasDictionary(language)\r\n\t\t\t? language\r\n\t\t\t: this.hasDictionary(navigator.language) ? navigator.language : undefined\r\n\t}\r\n\r\n\ttranslate(key: string, p?: TranslateParams, language?: string) {\r\n\t\tlanguage = language ? language : this.language;\r\n\t\tif (!language) return key;\r\n\t\tconst d = this.dictionaries.get(language);\r\n\t\tif (!d) return key;\r\n\t\tconst t = d.translate(key, p);\r\n\t\tif (t === undefined) return key;\r\n\t\treturn t;\r\n\t}\r\n}\r\n\r\nexport class BasicLocalization extends Localization {\r\n\tconstructor(language?: string) {\r\n\t\tsuper();\r\n\t\tthis.addDictionary(\"cs\", new CzechBasicDictionary());\r\n\t\tthis.addDictionary(\"en\", new EnglishBasicDictionary());\r\n\t\tthis.setLanguage(language);\r\n\t}\r\n}\r\n","export class ByteUtil {\r\n\r\n\tstatic formatByteSize(size?: number | null): string {\r\n\t\tconst n = Number(size);\r\n\t\tif (n === null || Number.isNaN(n)) return '';\r\n\t\tif (n === 0) return '0';\r\n\t\tconst l = Math.floor(Math.log(n) / Math.log(1024));\r\n\t\treturn +((n / Math.pow(1024, l)).toFixed(2)) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][l];\r\n\t}\r\n\r\n}\r\n","type CancelledWrapper = { value: boolean};\r\n\r\nexport class CancellablePromise {\r\n\r\n\tisCancelled: CancelledWrapper = { value: false };\r\n\r\n\tthrowWhenCancelled: boolean;\r\n\r\n\tpromise: Promise<any | void>;\r\n\r\n\tconstructor(promise: Promise<any | void>, throwWhenCancelled: boolean = false) {\r\n\t\tthis.throwWhenCancelled = throwWhenCancelled;\r\n\t\tthis.promise = new Promise(\r\n\t\t\t(resolve, reject) => {\r\n\t\t\t\tpromise\r\n\t\t\t\t\t.then(\r\n\t\t\t\t\t\tresult => {\r\n\t\t\t\t\t\t\tif (!this.isCancelled.value) {\r\n\t\t\t\t\t\t\t\treturn resolve(result);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t)\r\n\t\t\t\t\t.catch(\r\n\t\t\t\t\t\te => {\r\n\t\t\t\t\t\t\tif (this.throwWhenCancelled || !this.isCancelled.value) {\r\n\t\t\t\t\t\t\t\treject(e);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t);\r\n\t\t\t}\r\n\t\t);\r\n\t}\r\n\r\n\tcancel() {\r\n\t\tthis.isCancelled.value = true;\r\n\t}\r\n\r\n}\r\n","import {EntityClient} from \"./EntityClient\";\r\nimport {EntityBase} from \"../type/Entity\";\r\nimport { HashCacheAsync } from \"../cache\";\r\nimport { RestClient } from \"./RestClient\";\r\nimport {HashCacheStats} from \"../type\";\r\n\r\nexport class EntityCachedClient<T extends EntityBase> extends EntityClient<T> {\r\n\r\n\tprotected cache: HashCacheAsync<number, T>;\r\n\r\n\tconstructor(client: RestClient, name: string, maxSize?: number) {\r\n\t\tsuper(client, name);\r\n\t\tthis.cache = new HashCacheAsync<number, T>((id: number) => super.loadSingle(id), maxSize);\r\n\t}\r\n\r\n\tloadSingle(id: number): Promise<T> {\r\n\t\treturn this.cache.get(id);\r\n\t}\r\n\r\n\tsave(d: T): Promise<T> {\r\n\t\treturn super.save(d).then(\r\n\t\t\t(s: T): T => {\r\n\t\t\t\tif (s.id) this.cache.set(s.id, s);\r\n\t\t\t\treturn s;\r\n\t\t\t});\r\n\t}\r\n\r\n\tdelete(id: number): Promise<any> {\r\n\t\treturn super.delete(id).then(() => this.cache.reset(id));\r\n\t}\r\n\r\n\treset(id?: number) {\r\n\t\tthis.cache.reset(id);\r\n\t}\r\n\r\n\tgetStats(): HashCacheStats {\r\n\t\treturn this.cache.getStats();\r\n\t}\r\n}\r\n","import {EntityClient} from \"./EntityClient\";\r\nimport {EntityBase} from \"../type\";\r\n\r\nexport class EntityClientWithStub<T extends EntityBase, TStub extends EntityBase> extends EntityClient<T> {\r\n\r\n\tloadSingle(id: number): Promise<T> {\r\n\t\tthrow new Error(\"Use loadSingleStub() instead!\");\r\n\t}\r\n\r\n\tloadSingleStub(id: number): Promise<TStub> {\r\n\t\treturn this.client.getJson(`${this.name}/${id}`);\r\n\t}\r\n\r\n\tsave(d: T): Promise<T> {\r\n\t\tthrow new Error(\"Use saveStub() instead!\");\r\n\t}\r\n\r\n\tsaveStub(d: TStub): Promise<TStub> {\r\n\t\tif (d.id) {\r\n\t\t\treturn this.client.putJson(`${this.name}/${d.id}`, d);\r\n\t\t} else {\r\n\t\t\treturn this.client.postJson(this.name, d);\r\n\t\t}\r\n\t}\r\n\r\n}\r\n","export class Lazy<T> {\n\n\tprivate cache?: T;\n\n\tprivate supplier: () => T;\n\tconstructor(supplier: () => T) {\n\t\tthis.supplier = supplier;\n\t}\n\n\tget(): T {\n\t\tif (this.cache === undefined) {\n\t\t\tthis.cache = this.supplier();\n\t\t}\n\t\treturn this.cache;\n\t}\n\n\treset() {\n\t\tthis.cache = undefined;\n\t}\n\n\thasCache() {\n\t\treturn (this.cache !== undefined);\n\t}\n}\n","import {EntityClient} from \"./EntityClient\";\r\nimport {EntityBase} from \"../type/Entity\";\r\nimport { LazyAsync } from \"../cache\";\r\nimport { RestClient } from \"./RestClient\";\r\nimport {HashCacheStats} from \"../type\";\r\n\r\nexport class LookupClient<T extends EntityBase> extends EntityClient<T> {\r\n\r\n\tprotected cache: LazyAsync<Array<T>>;\r\n\r\n\tconstructor(client: RestClient, name: string) {\r\n\t\tsuper(client, name);\r\n\t\tthis.cache = new LazyAsync<Array<T>>(() => this.loadAllInternal());\r\n\t}\r\n\r\n\tprivate loadAllInternal(): Promise<Array<T>> {\r\n\t\treturn this.client.getJson(`${this.name}/all`);\r\n\t}\r\n\r\n\tloadAll(): Promise<Array<T>> {\r\n\t\treturn this.cache.get();\r\n\t}\r\n\r\n\tloadSingle(id: number): Promise<T> {\r\n\t\t// @ts-ignore\r\n\t\treturn this.loadAll().then(\r\n\t\t\t(all: Array<T>) => {\r\n\t\t\t\tconst d = all.find((l) => l.id === id);\r\n\t\t\t\tif (id === undefined) throw new Error(`${this.name} id ${id} not found!`);\r\n\t\t\t\treturn d;\r\n\t\t\t}\r\n\t\t);\r\n\t}\r\n\r\n\tsave(d: T): Promise<T> {\r\n\t\treturn super.save(d)\r\n\t\t\t.then((s) => {\r\n\t\t\t\tthis.cache.reset();\r\n\t\t\t\treturn s;\r\n\t\t\t});\r\n\t}\r\n\r\n\tdelete(id: number): Promise<any> {\r\n\t\treturn super.delete(id).then(() => this.cache.reset());\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.cache.reset();\r\n\t}\r\n\r\n\tgetStats(): HashCacheStats {\r\n\t\tconst size = this.cache.getCache()?.length;\r\n\t\treturn {\r\n\t\t\tcachedItems: size || 0,\r\n\t\t\tcapacity: size || 0\r\n\t\t}\r\n\t}\r\n}\r\n","import { OAuthTokenManager } from \"./OAuthTokenManager\";\nimport { RestClient } from \"../client\";\nimport { IdTokenPayload, RefreshTokenPayload } from \"./OAuthRestClient\";\nimport { LazyAsync } from \"../cache\";\nimport { OAuthRefreshTokenProvider } from \"./tokenprovider/OAuthRefreshTokenProvider\";\nimport { RefreshTokenProviderDefault } from \"./tokenprovider/RefreshTokenProviderDefault\";\n\nexport type ServerOAuthInfoPayload = {\n debugMode?: boolean;\n targetAudience: string;\n oauthServerUrl: string;\n version: string;\n};\n\nexport class RestClientWithOAuth\n extends RestClient\n implements OAuthRefreshTokenProvider\n{\n private insecureClient: RestClient;\n\n private freshIdTokenProvider: OAuthRefreshTokenProvider;\n\n private tokenManager: LazyAsync<OAuthTokenManager>;\n\n private serverInfo: LazyAsync<ServerOAuthInfoPayload>;\n\n private defaultScope: string;\n\n constructor(\n url: string,\n freshIdTokenProvider?: OAuthRefreshTokenProvider,\n defaultScope: string = \"admin:*\",\n ) {\n super(url);\n\n this.freshIdTokenProvider =\n freshIdTokenProvider || new RefreshTokenProviderDefault(this);\n this.defaultScope = defaultScope;\n\n // rest client without OAuth headers\n this.insecureClient = new RestClient(url);\n\n this.serverInfo = new LazyAsync<ServerOAuthInfoPayload>(() =>\n this.getServerInfoInternal(),\n );\n this.tokenManager = new LazyAsync<OAuthTokenManager>(() =>\n this.getTokenManagerInternal(),\n );\n }\n\n getRefreshToken(): Promise<IdTokenPayload> {\n return this.getTokenManager().then((t) => t.getRefreshToken());\n }\n\n /**\n * Attempt to get ID token from token manager\n */\n initialize(): Promise<any> {\n return this.getRefreshToken();\n }\n\n logout(): Promise<any> {\n return this.reset().then(() => this.initialize());\n }\n\n reset(): Promise<any> {\n return this.getTokenManager().then((m) => m.reset());\n }\n\n /**\n * Override this if a different privilege is needed for different endpoints\n * @param url\n */\n getScope(url: string): string {\n return this.defaultScope;\n }\n\n private getServerInfoInternal(): Promise<ServerOAuthInfoPayload> {\n return this.insecureClient.getJson(\"status/oauth/info\");\n }\n\n getServerInfo(): Promise<ServerOAuthInfoPayload> {\n return this.serverInfo.get();\n }\n\n protected getTokenManagerInternal(): Promise<OAuthTokenManager> {\n return this.getServerInfo().then(\n (info) =>\n new OAuthTokenManager(\n info.oauthServerUrl,\n info.targetAudience,\n this.freshIdTokenProvider,\n ),\n );\n }\n\n getTokenManager(): Promise<OAuthTokenManager> {\n return this.tokenManager.get();\n }\n\n login(login: string, password: string): Promise<RefreshTokenPayload> {\n return this.getTokenManager().then((m) => m.login(login, password));\n }\n\n setIdToken(token: IdTokenPayload): Promise<any> {\n return this.getTokenManager().then((m) => m.setRefreshToken(token));\n }\n\n getHeaders(endpoint: string): Promise<Headers> {\n return this.getTokenManager()\n .then((tm) => tm.getAccessToken(this.getScope(endpoint)))\n .then((accessToken) =>\n super.getHeaders(endpoint).then((headers) => {\n headers.set(\"Authorization\", `Bearer ${accessToken}`);\n return headers;\n }),\n );\n }\n}\n","import {UserAlert, UserAlertType} from \"../type\";\r\nimport {EventManager, Func} from \"./EventManager\";\r\nimport {DateUtil} from \"../util\";\r\n\r\nexport class UserAlerts {\r\n\r\n\tprivate maxAlerts: number;\r\n\r\n\tpublic maxVisibilityMs: number;\r\n\r\n\tprivate em: EventManager;\r\n\r\n\tpublic alerts: Array<UserAlert>;\r\n\r\n\tpublic visibleAlerts: Array<UserAlert>;\r\n\r\n\tconstructor(maxAlerts: number = 20, maxVisibilityMs: number = 7000) {\r\n\t\tthis.maxAlerts = maxAlerts;\r\n\t\tthis.maxVisibilityMs = maxVisibilityMs;\r\n\t\tthis.em = new EventManager();\r\n\t\tthis.alerts = [];\r\n\t\tthis.visibleAlerts = [];\r\n\t}\r\n\r\n\taddOnChangeHandler(h: Func) {\r\n\t\tthis.em.addEventListener('change', h);\r\n\t}\r\n\r\n\tremoveOnChangeHandler(h: Func) {\r\n\t\tthis.em.removeEventListener('change', h);\r\n\t}\r\n\r\n\ttriggerChange() {\r\n\t\tthis.em.triggerEvent('change');\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.alerts = [];\r\n\t\tthis.visibleAlerts = [];\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\thide(alert: UserAlert) {\r\n\t\tthis.visibleAlerts.splice(this.visibleAlerts.indexOf(alert), 1);\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\thideAll() {\r\n\t\tthis.visibleAlerts = [];\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\tupdateVisibility() {\r\n\t\tthis.visibleAlerts.forEach(\r\n\t\t\ta => {\r\n\t\t\t\tconst elapsedMs = DateUtil.getSinceDurationMs(a.time) || this.maxVisibilityMs;\r\n\t\t\t\tconst remainsMs = this.maxVisibilityMs - elapsedMs;\r\n\t\t\t\tif (remainsMs > 0) {\r\n\t\t\t\t\ta.remainsMs = remainsMs;\r\n\t\t\t\t} else {\r\n\t\t\t\t\ta.remainsMs = undefined;\r\n\t\t\t\t\tthis.hide(a);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t);\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\tremove(alert: UserAlert) {\r\n\t\tthis.alerts.splice(this.alerts.indexOf(alert), 1);\r\n\t\tthis.triggerChange();\r\n\t};\r\n\r\n\tadd(alert: UserAlert) {\r\n\t\tif (alert.remainsMs === undefined) {\r\n\t\t\talert.remainsMs = this.maxVisibilityMs;\r\n\t\t}\r\n\t\tthis.alerts.push(alert);\r\n\t\tthis.visibleAlerts.push(alert);\r\n\t\twhile (this.alerts.length > this.maxAlerts) {\r\n\t\t\tthis.alerts.shift();\r\n\t\t}\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\tcustom(type: UserAlertType, message: string) {\r\n\t\tthis.add({\r\n\t\t\ttime: new Date(),\r\n\t\t\ttype: type,\r\n\t\t\tmessage: message\r\n\t\t});\r\n\t}\r\n\r\n\terr(error: string | Error) {\r\n\t\tthis.custom(UserAlertType.error, typeof error === 'string' ? error : error.toString());\r\n\t}\r\n\r\n\twarn(message: string) {\r\n\t\tthis.custom(UserAlertType.warning, message);\r\n\t}\r\n\r\n\tinfo(message: string) {\r\n\t\tthis.custom(UserAlertType.info, message);\r\n\t}\r\n\r\n\tgetSummary(): Map<UserAlertType, number> {\r\n\t\tconst map= new Map<UserAlertType, number>;\r\n\t\tconst types = Object.values(UserAlertType);\r\n\t\ttypes.forEach((t, index) => {\r\n\t\t\tmap.set(t, 0);\r\n\t\t});\r\n\t\tfor (let i = 0; i < this.alerts.length; i++) {\r\n\t\t\tconst alert = this.alerts[i];\r\n\t\t\tconst n: number = map.get(alert.type) || 0;\r\n\t\t\tmap.set(alert.type, n + 1);\r\n\t\t}\r\n\t\treturn map;\r\n\t}\r\n\r\n}\r\n"],"names":["LazyAsync","constructor","supplier","this","get","undefined","cache","Promise","resolve","promise","then","v","catch","err","reject","reset","hasCache","getCache","CacheAsync","maxAgeMs","super","expires","Date","set","getTime","HashCacheAsync","maxSize","Map","obtainCache","k","c","delete","clear","getSize","size","getMaxSize","getStats","cachedItems","capacity","has","ObjectUtil","isEmpty","obj","notEmpty","clone","Error","getNestedValue","path","keys","split","current","key","HashUtil","crc32hex","str","data","TextEncoder","encode","table","Uint32Array","i","j","crc","length","toString","StringUtil","isString","s","message","isBlank","safeTrim","notBlank","substr","start","substring","replace","find","String","containsLineBreaks","safeContains","haystack","needle","caseSensitive","toLowerCase","includes","trimLeadingSlashes","trimTrailingSlashes","trimSlashes","safeTruncate","len","ellipsis","trim","safeLowercase","safeUppercase","toUpperCase","capitalizeFirstLetter","charAt","toBigInt","BigInt","getNonEmpty","args","a","getNonBlank","emptyToNull","blankToNull","randomString","Math","random","ArrayUtil","arr","remove","element","filter","e","extract","end","slice","extractStart","AsyncUtil","sleep","ms","r","setTimeout","FIRST_PAGE","page","PagingUtil","sortingFieldToString","parts","push","name","desc","nullsLast","join","sortingFieldFromString","sortingRequestToString","map","sortingRequestFromString","pagingRequestToQueryParams","pr","result","search","sorting","pagingRequestToString","pagingRequestFromString","Number","NumberUtil","n","isNaN","parseNumber","round","d","pow","portionToPercent","p","DateUtil","formatNumber","digits","padStart","parseDate","formatDateForHumans","showTime","year","getFullYear","month","getMonth","day","getDate","getHours","getMinutes","getSeconds","formatDateTimeForHumans","formatDateForInput","formatDateTimeForInput","getDurationMs","d1","d2","getSinceDurationMs","formatDuration","secs","floor","mins","hrs","days","items","JsonUtil","dateParser","value","reISO","exec","parseWithDates","json","JSON","parse","UrlUtil","deleteParamFromUrl","url","paramName","urlObj","URL","searchParams","extractParamFromUrl","URLSearchParams","paramExistsInUrl","extractHostFromUrl","host","extractDomainFromUrl","PERMISSION_LEVELS","OAuthRestClient","RestClient","oauthUrl","jwks","getJson","verifyRefreshToken","refreshToken","verifyAccessToken","accessToken","verifyIdToken","idToken","requestRefreshTokenFromLogin","request","postJson","renewRefreshToken","requestAccessToken","OAuthTokenManager","oAuthServerBaseUrl","targetAudience","initialRefreshTokenProvider","audience","oAuthServer","accessTokens","hasValidRefreshToken","OAuthUtil","isValidToken","hasValidAccessToken","privilege","getRefreshTokenInternal","getRefreshToken","t","isTokenReadyForRefresh","token","setRefreshToken","console","log","getRefreshTokenRaw","login","password","storeAccessToken","scope","findStoredAccessToken","level","extractPermissionLevel","extractPrivilege","hasPermission","getAccessTokenInternal","act","scopes","forEach","getAccessToken","existing","RedirectionProvider","redirectTo","redirecting","document","location","href","isRedirecting","redirectingTo","RefreshTokenProviderLogin","client","tokenQueryName","redirectToLogin","getServerInfo","si","thisUrl","oauthServerUrl","error","RefreshTokenProviderUrl","getRefreshTokenFromUrl","raw","getTokenManager","m","RefreshTokenProviderStorage","storageKey","saveRefreshTokenToLocalStorage","stringify","localStorage","setItem","removeItem","getRefreshTokenFromLocalStorage","getItem","RefreshTokenProviderDefault","tokenStorageKey","tokenUrlName","storage","isTokenExpired","issuedAt","getScopeString","isPermissionLevel","getLevel","ownedScope","requiredScopeOrPrivilege","minLevel","ownedLevel","ownedPrivilege","endsWith","ownedParent","startsWith","baseUrl","baseHostUrl","window","protocol","paramsToQueryString","params","original","cleaned","getHeaders","endpoint","headers","Headers","getBaseUrl","getUrl","Object","getRequestOptions","method","body","FormData","processRequest","requestOptions","fetch","response","ok","options","cause","status","statusText","text","processRequestJson","o","postForm","postFormJson","putJson","del","post","put","EntityClient","loadSingle","id","loadPage","save","EventManager","handlers","addEventListener","event","handler","removeEventListener","splice","indexOf","triggerEvent","arg","h","UserAlertType","Vector2","x","y","distanceTo","sqrt","equalsTo","inSize","currentSize","ratio","add","multiply","subtract","sub","toArray","fromArray","getAngleToYAxis","b","diff","down","sinX","angle","asin","PI","getNeighborPositions","includeCenter","neighbors","maxX","maxY","getClosest","positions","closest","distance","max","decimals","MemoryDictionary","translate","def","tags","cands","every","CzechBasicDictionary","CzechBasicData","EnglishBasicDictionary","EnglishBasicData","DictionaryWithFallback","primary","fallback","pt","Localization","language","dictionaries","setLanguage","addDictionary","dictionary","hasDictionary","getLanguage","getLanguages","Array","from","navigator","formatByteSize","l","toFixed","throwWhenCancelled","isCancelled","cancel","loadSingleStub","saveStub","loadAllInternal","loadAll","all","freshIdTokenProvider","defaultScope","insecureClient","serverInfo","getServerInfoInternal","tokenManager","getTokenManagerInternal","initialize","logout","getScope","info","setIdToken","tm","maxAlerts","maxVisibilityMs","em","alerts","visibleAlerts","addOnChangeHandler","removeOnChangeHandler","triggerChange","hide","alert","hideAll","updateVisibility","elapsedMs","time","remainsMs","shift","custom","type","warn","warning","getSummary","values","index"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/cache/LazyAsync.ts","../src/cache/CacheAsync.ts","../src/cache/HashCacheAsync.ts","../src/util/ObjectUtil.ts","../src/util/HashUtil.ts","../src/util/StringUtil.ts","../src/util/ArrayUtil.ts","../src/util/AsyncUtil.ts","../src/util/PagingUtil.ts","../src/util/NumberUtil.ts","../src/util/DateUtil.ts","../src/util/JsonUtil.ts","../src/util/UrlUtil.ts","../src/client/RestClient.ts","../src/client/EntityClient.ts","../src/component/EventManager.ts","../src/type/UserAlert.ts","../src/oauth/Types.ts","../src/oauth/OAuthUtil.ts","../src/oauth/OAuthRestClient.ts","../src/oauth/OAuthTokenManager.ts","../src/oauth/tokenprovider/RedirectionProvider.ts","../src/oauth/tokenprovider/RefreshTokenProviderLogin.ts","../src/oauth/tokenprovider/RefreshTokenProviderUrl.ts","../src/oauth/tokenprovider/RefreshTokenProviderStorage.ts","../src/oauth/tokenprovider/RefreshTokenProviderDefault.ts","../src/vector/Vector2.ts","../src/localization/Dictionary.ts","../src/localization/Localization.ts","../src/util/ByteUtil.ts","../src/component/CancellablePromise.ts","../src/client/EntityCachedClient.ts","../src/client/EntityClientWithStub.ts","../src/cache/Lazy.ts","../src/client/LookupClient.ts","../src/oauth/RestClientWithOAuth.ts","../src/component/UserAlerts.ts"],"sourcesContent":["export class LazyAsync<T> {\n\n\tprotected cache?: T;\n\n\tprotected supplier: () => Promise<T>;\n\n\tprivate promise?: Promise<T>;\n\n\tconstructor(supplier: () => Promise<T>) {\n\t\tthis.supplier = supplier;\n\t}\n\n\tget(): Promise<T> {\n\t\tif (this.cache !== undefined) {\n\t\t\treturn Promise.resolve(this.cache);\n\t\t}\n\n\t\tif (this.promise === undefined) {\n\t\t\tthis.promise = this.supplier()\n\t\t\t\t.then((v: T) => {\n\t\t\t\t\tthis.cache = v;\n\t\t\t\t\tthis.promise = undefined;\n\t\t\t\t\treturn Promise.resolve(v);\n\t\t\t\t}).catch((err) => {\n\t\t\t\t\tthis.promise = undefined;\n\t\t\t\t\treturn Promise.reject(err);\n\t\t\t\t});\n\t\t}\n\n\t\treturn this.promise;\n\t}\n\n\treset() {\n\t\tthis.cache = undefined;\n\t}\n\n\thasCache() {\n\t\treturn (this.cache !== undefined);\n\t}\n\n\tgetCache(): T | undefined {\n\t\treturn this.cache;\n\t}\n}\n","import {LazyAsync} from \"./LazyAsync\";\n\nexport class CacheAsync<T> extends LazyAsync<T> {\n\n\tprivate maxAgeMs?: number;\n\n\tprivate expires?: Date;\n\n\tconstructor(supplier: () => Promise<T>, maxAgeMs?: number) {\n\t\tsuper(supplier);\n\t\tthis.maxAgeMs = maxAgeMs;\n\t}\n\n\tget(): Promise<T> {\n\t\tif (this.expires && this.expires > new Date()) {\n\t\t\tthis.reset();\n\t\t}\n\t\treturn super.get();\n\t}\n\n\tset(v: T, expires?: Date) {\n\t\tthis.cache = v;\n\t\tthis.expires = expires;\n\t\tif (this.maxAgeMs && this.expires === undefined) {\n\t\t\tthis.expires = new Date(new Date().getTime() + this.maxAgeMs);\n\t\t}\n\t}\n\n}\n","import { HashCacheStats } from \"../type\";\nimport {CacheAsync} from \"./CacheAsync\";\n\nexport class HashCacheAsync<K, V> {\n\n\tprivate cache = new Map<K, CacheAsync<V>>;\n\n\tprivate supplier: (k: K) => Promise<V>;\n\n\tprivate maxSize: number = 100;\n\n\tconstructor(supplier: (k: K) => Promise<V>, maxSize?: number) {\n\t\tthis.supplier = supplier;\n\t\tif (maxSize) this.maxSize = maxSize;\n\t}\n\n\tprotected obtainCache(k: K): CacheAsync<V> {\n\t\tlet c = this.cache.get(k);\n\t\tif (!c) {\n\t\t\tc = new CacheAsync(() => this.supplier(k));\n\t\t\tthis.cache.set(k, c);\n\t\t}\n\t\treturn c;\n\t}\n\n\tget(k: K): Promise<V> {\n\t\treturn this.obtainCache(k).get();\n\t}\n\n\tset(k: K, v: V, expires?: Date){\n\t\tthis.obtainCache(k).set(v, expires);\n\t}\n\n\treset(k?: K) {\n\t\tif (!k) {\n\t\t\tthis.cache.clear();\n\t\t} else {\n\t\t\tthis.cache.delete(k);\n\t\t}\n\t}\n\n\tgetSize() {\n\t\treturn this.cache.size;\n\t}\n\n\tgetMaxSize() {\n\t\treturn this.maxSize;\n\t}\n\n\tgetStats(): HashCacheStats {\n\t\treturn {\n\t\t\tcachedItems: this.getSize(),\n\t\t\tcapacity: this.getMaxSize()\n\t\t}\n\t}\n\n\thasCache(k: K) {\n\t\treturn this.cache.has(k);\n\t}\n}\n","export class ObjectUtil {\r\n\r\n\tstatic isEmpty(obj: any): obj is null | undefined {\r\n\t\treturn obj === undefined || obj === null;\r\n\t}\r\n\r\n\tstatic notEmpty(obj: any): obj is object {\r\n\t\treturn !ObjectUtil.isEmpty(obj);\r\n\t}\r\n\r\n\tstatic clone<T>(obj: T): T {\r\n\t\tif (obj === null) {\r\n\t\t\tthrow new Error(\"Null cannot be cloned!\");\r\n\t\t}\r\n\t\tif (typeof obj !== 'object') {\r\n\t\t\tthrow new Error(\"Not an object, cannot be cloned!\");\r\n\t\t}\r\n\t\treturn {...obj};\r\n\t}\r\n\r\n\tstatic getNestedValue(obj: any, path: string): string {\r\n\t\tif (!obj || obj === '') return '';\r\n\r\n\t\tconst keys = path.split('.');\r\n\r\n\t\tlet current = obj;\r\n\t\tfor (const key of keys) {\r\n\t\t\tif (current && typeof current === 'object' && key in current) {\r\n\t\t\t\tcurrent = current[key];\r\n\t\t\t} else {\r\n\t\t\t\treturn '';\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn current;\r\n\t}\r\n\r\n}\r\n","export class HashUtil {\n\n\tstatic crc32hex(str: string): string {\n\t\t// Encode string to UTF-8 bytes\n\t\tconst encoder = new TextEncoder();\n\t\tconst data = encoder.encode(str);\n\n\t\t// Generate CRC32 table once\n\t\tconst table = new Uint32Array(256);\n\t\tfor (let i = 0; i < 256; i++) {\n\t\t\tlet c = i;\n\t\t\tfor (let j = 0; j < 8; j++) {\n\t\t\t\tc = (c & 1) ? (0xEDB88320 ^ (c >>> 1)) : (c >>> 1);\n\t\t\t}\n\t\t\ttable[i] = c >>> 0;\n\t\t}\n\n\t\tlet crc = 0 ^ -1;\n\t\tfor (let i = 0; i < data.length; i++) {\n\t\t\tcrc = (crc >>> 8) ^ table[(crc ^ data[i]) & 0xFF];\n\t\t}\n\t\tcrc = (crc ^ -1) >>> 0;\n\n\t\treturn crc.toString(16);\n\t}\n}\n","import {HashUtil} from \"./HashUtil\";\nimport {ObjectUtil} from \"./ObjectUtil\";\n\nexport class StringUtil {\n\tstatic isString(s: any): boolean {\n\t\treturn typeof s === \"string\";\n\t}\n\n\tstatic toString(s: any): string {\n\t\tif (StringUtil.isString(s)) return s;\n\t\tif (StringUtil.isString(s.message)) return s.message; // Errors\n\t\treturn s?.toString?.() ?? \"\";\n\t}\n\n\tstatic isEmpty(str: string | null | undefined): str is null | undefined {\n\t\tif (ObjectUtil.isEmpty(str)) return true;\n\t\treturn str.length === 0;\n\t}\n\n\tstatic notEmpty(str: string | null | undefined): str is string {\n\t\treturn !StringUtil.isEmpty(str);\n\t}\n\n\tstatic isBlank(str: string | null | undefined): str is null | undefined | \"\" {\n\t\treturn StringUtil.isEmpty(StringUtil.safeTrim(str));\n\t}\n\n\tstatic notBlank(str: string | null | undefined): str is string {\n\t\treturn !StringUtil.isBlank(str);\n\t}\n\n\tstatic substr(\n\t\tstr: string | null | undefined,\n\t\tstart: number,\n\t\tlength?: number,\n\t): string {\n\t\tif (this.isEmpty(str)) return \"\";\n\n\t\t// @ts-ignore\n\t\treturn str.substring(start, length);\n\t}\n\n\tstatic replace(\n\t\tstr: string | null | undefined,\n\t\tfind?: null | string,\n\t\treplace?: string,\n\t): string {\n\t\tif (this.isEmpty(str) || this.isEmpty(find)) return \"\";\n\t\treturn str.replace(find, String(replace));\n\t}\n\n\tstatic containsLineBreaks(str: string | null | undefined): str is string {\n\t\treturn StringUtil.safeContains(str, \"\\n\");\n\t}\n\n\tstatic safeContains(haystack: string | null | undefined, needle: string | null | undefined, caseSensitive: boolean = true): haystack is string {\n\t\tif (StringUtil.isBlank(haystack) || StringUtil.isBlank(needle)) return false;\n\t\tif (caseSensitive) return StringUtil.safeContains(haystack.toLowerCase(), needle.toLowerCase(), false);\n\t\treturn haystack.includes(needle);\n\t}\n\n\tstatic trimLeadingSlashes(str: string | null): string {\n\t\tif (this.isEmpty(str)) return \"\";\n\t\treturn StringUtil.toString(str).replace(/^\\//g, \"\");\n\t}\n\n\tstatic trimTrailingSlashes(str: string | null): string {\n\t\tif (this.isEmpty(str)) return \"\";\n\t\treturn StringUtil.toString(str).replace(/\\/$/g, \"\");\n\t}\n\n\tstatic trimSlashes(str: string | null): string {\n\t\tif (this.isEmpty(str)) return \"\";\n\t\treturn StringUtil.toString(str).replace(/^\\/|\\/$/g, \"\");\n\t}\n\n\tstatic safeTruncate(\n\t\tstr: string | null | undefined,\n\t\tlen: number,\n\t\tellipsis: string = \"\",\n\t): string {\n\t\tif (StringUtil.isEmpty(str) || !str) return \"\";\n\t\tstr = StringUtil.toString(str);\n\t\tif (str.length <= len) return String(str);\n\t\treturn str.substring(0, len - ellipsis.length) + ellipsis;\n\t}\n\n\tstatic ellipsis(\n\t\tstr: string | null | undefined,\n\t\tlen: number,\n\t\tellipsis: string = \"...\",\n\t): string {\n\t\treturn StringUtil.safeTruncate(str, len, ellipsis);\n\t}\n\n\tstatic safeTrim(str: string | null | undefined): string {\n\t\tif (StringUtil.isEmpty(str)) return \"\";\n\t\treturn StringUtil.toString(str).trim();\n\t}\n\n\tstatic safeLowercase(str: string | null | undefined): string {\n\t\tif (StringUtil.isEmpty(str) || !str) return \"\";\n\t\treturn StringUtil.toString(str).toLowerCase();\n\t}\n\n\tstatic safeUppercase(str: string | null | undefined): string {\n\t\tif (StringUtil.isEmpty(str) || !str) return \"\";\n\t\treturn StringUtil.toString(str).toUpperCase();\n\t}\n\n\tstatic capitalizeFirstLetter(str: string | null | undefined): string {\n\t\tif (StringUtil.isBlank(str)) return \"\";\n\t\treturn (\n\t\t\tStringUtil.safeUppercase(str.charAt(0)) +\n\t\t\tStringUtil.safeLowercase(StringUtil.substr(str, 1))\n\t\t);\n\t}\n\n\tstatic toBigInt(str: string | null): bigint | null {\n\t\tif (this.isEmpty(str)) return null;\n\n\t\t// @ts-ignore\n\t\treturn BigInt(str);\n\t}\n\n\tstatic getNonEmpty(...args: Array<string | null | undefined>): string {\n\t\treturn args.find((a) => StringUtil.notEmpty(a)) || \"\";\n\t}\n\n\tstatic getNonBlank(...args: Array<string | null | undefined>): string {\n\t\treturn args.find((a) => StringUtil.notBlank(a)) || \"\";\n\t}\n\n\tstatic emptyToNull(str: string | null | undefined): string | null {\n\t\treturn StringUtil.isEmpty(str) ? null : String(str);\n\t}\n\n\tstatic blankToNull(str: string | null | undefined): string | null {\n\t\treturn StringUtil.isBlank(str) ? null : String(str);\n\t}\n\n\tstatic randomString(): string {\n\t\treturn HashUtil.crc32hex(Date() + Math.random());\n\t}\n}\n","import { ObjectUtil } from \"./ObjectUtil\";\r\n\r\nexport class ArrayUtil {\r\n\r\n\tstatic isEmpty(arr?: Array<any> | null): boolean {\r\n\t\t// @ts-ignore\r\n\t\treturn ObjectUtil.isEmpty(arr) || arr.length === 0;\r\n\t}\r\n\r\n\tstatic notEmpty(arr?: Array<any> | null): arr is Array<any> {\r\n\t\treturn !ArrayUtil.isEmpty(arr);\r\n\t}\r\n\r\n\tstatic remove(arr?: Array<any> | null, element?: any): Array<any> {\r\n\t\tif (ArrayUtil.isEmpty(arr)) return [];\r\n\t\t// @ts-ignore\r\n\t\treturn arr?.filter(e => e !== element);\r\n\t}\r\n\r\n\tstatic extract(arr?: Array<any> | null, start: number = 0, length?: number): Array<any> {\r\n\t\tif ((!arr) || arr.length <= start) return [];\r\n\t\tconst end = length === undefined ? undefined : start + length;\r\n\t\treturn arr.slice(start, end);\r\n\t}\r\n\r\n\tstatic extractStart(arr: Array<any> | null | undefined, length: number): Array<any> {\r\n\t\treturn ArrayUtil.extract(arr, 0, length);\r\n\t}\r\n\r\n}\r\n","export class AsyncUtil {\n\tstatic sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));\n}\n","import {PagingRequest, SortingField, SortingRequest} from \"../type\";\nimport {StringUtil} from \"./StringUtil\";\n\nexport const FIRST_PAGE: PagingRequest = {page: 0, size: 10};\n\nexport class PagingUtil {\n\n\tstatic sortingFieldToString(s: SortingField): string {\n\t\tif (!s) return '';\n\t\tconst parts = [];\n\t\tparts.push(s.name);\n\t\tparts.push(s.desc ? 'desc' : '');\n\t\tparts.push(s.nullsLast ? 'nl' : '');\n\t\treturn parts.join('-');\n\t}\n\n\tstatic sortingFieldFromString(s: string): SortingField {\n\t\tconst arr = s.split('-');\n\t\treturn {\n\t\t\tname: arr[0],\n\t\t\tdesc: arr.length > 1 && StringUtil.safeLowercase(arr[1]) === 'desc',\n\t\t\tnullsLast: arr.length > 2 && StringUtil.safeLowercase(arr[2]) === 'nl'\n\t\t}\n\t}\n\n\tstatic sortingRequestToString(s: SortingRequest): string | undefined {\n\t\treturn s.map((s: SortingField) => PagingUtil.sortingFieldToString(s)).join('+');\n\t}\n\n\tstatic sortingRequestFromString(s?: string | null): SortingRequest {\n\t\tif (!s) return [];\n\t\tconst arr = s.split('+');\n\t\treturn arr.map((s) => PagingUtil.sortingFieldFromString(s));\n\t}\n\n\tstatic pagingRequestToQueryParams(pr?: PagingRequest | null): any {\n\t\tif (!pr) return;\n\t\tconst result: any = {\n\t\t\tpage: pr.page,\n\t\t\tsize: pr.size\n\t\t}\n\t\tif (pr.search) {\n\t\t\tresult.search = pr.search;\n\t\t}\n\t\tif (pr.sorting) {\n\t\t\tresult.sorting = PagingUtil.sortingRequestToString(pr.sorting);\n\t\t}\n\t\treturn result;\n\t}\n\n\tstatic pagingRequestToString(pr?: PagingRequest): string {\n\t\tif (!pr) return '';\n\t\tconst arr = [];\n\t\tarr.push(String(pr.page));\n\t\tarr.push(String(pr.size));\n\t\tarr.push(StringUtil.safeTrim(pr.search));\n\t\tarr.push(pr.sorting ? PagingUtil.sortingRequestToString(pr.sorting) : '');\n\t\treturn arr.join(':');\n\t}\n\n\tstatic pagingRequestFromString(pr?: string): PagingRequest {\n\t\tif (!pr || StringUtil.isEmpty(pr)) return {...FIRST_PAGE};\n\t\tconst arr = pr.split(':');\n\t\tif (arr.length < 4) return {...FIRST_PAGE};\n\t\treturn {\n\t\t\tpage: Number(arr[0]),\n\t\t\tsize: Number(arr[1]),\n\t\t\tsearch: String(arr[2]),\n\t\t\tsorting: StringUtil.isEmpty(arr[3]) ? undefined : PagingUtil.sortingRequestFromString(arr[3])\n\t\t}\n\t}\n\n}\n","export class NumberUtil {\r\n\r\n\tstatic isEmpty(n: any): n is null | undefined {\r\n\t\treturn n === undefined || n === null || Number.isNaN(n);\r\n\t}\r\n\r\n\tstatic notEmpty(n?: number | null): n is number {\r\n\t\treturn !NumberUtil.isEmpty(n);\r\n\t}\r\n\r\n\tstatic parseNumber(str: string | null | undefined): number | null {\r\n\t\tif (!str) return null;\r\n\t\tconst n = Number(str);\r\n\t\treturn Number.isNaN(n) ? null : n;\r\n\t}\r\n\r\n\tstatic round(n: number, d?: number) {\r\n\t\tif (!d) d = 0;\r\n\t\tconst c = Math.pow(10, d);\r\n\t\treturn Math.round( n * c) / c;\r\n\t}\r\n\r\n\tstatic portionToPercent(p: number, d?: number): string {\r\n\t\tif (p === null || p === undefined) return '';\r\n\t\tconst n = NumberUtil.round(p * 100, d);\r\n\t\treturn `${n}%`\r\n\t}\r\n\r\n}\r\n","import {ObjectUtil} from \"./ObjectUtil\";\r\nimport {NumberUtil} from \"./NumberUtil\";\r\n\r\nexport class DateUtil {\r\n\r\n\tstatic formatNumber(n: number, digits = 2) {\r\n\t\tconst s = String(n);\r\n\t\treturn s.padStart(digits, '0');\r\n\t}\r\n\r\n\tstatic parseDate(d: Date | string | null | undefined): Date | undefined {\r\n\t\tif (!d) return undefined;\r\n\t\tif (typeof d === 'string') {\r\n\t\t\treturn new Date(d);\r\n\t\t}\r\n\t\treturn d;\r\n\t}\r\n\r\n\tstatic formatDateForHumans(d: Date | string | null | undefined, showTime: boolean = false): string {\r\n\t\td = DateUtil.parseDate(d);\r\n\t\tif (!d) return '';\r\n\r\n\t\tconst year = d.getFullYear();\r\n\t\tconst month = DateUtil.formatNumber(d.getMonth() + 1);\r\n\t\tconst day = DateUtil.formatNumber(d.getDate());\r\n\r\n\t\tif (!showTime) {\r\n\t\t\treturn `${year}-${month}-${day}`;\r\n\t\t}\r\n\r\n\t\tconst hours = DateUtil.formatNumber(d.getHours());\r\n\t\tconst minutes = DateUtil.formatNumber(d.getMinutes());\r\n\t\tconst seconds = DateUtil.formatNumber(d.getSeconds());\r\n\t\treturn `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`;\r\n\t}\r\n\r\n\tstatic formatDateTimeForHumans(d: Date | string | null | undefined): string {\r\n\t\treturn DateUtil.formatDateForHumans(d, true);\r\n\t}\r\n\r\n\tstatic formatDateForInput(d: any, showTime: boolean = false): string {\r\n\t\td = DateUtil.parseDate(d);\r\n\t\tif (!d) return '';\r\n\t\tconst year = d.getFullYear();\r\n\t\tconst month = DateUtil.formatNumber(d.getMonth() + 1);\r\n\t\tconst day = DateUtil.formatNumber(d.getDate());\r\n\r\n\t\tif (!showTime) {\r\n\t\t\treturn `${year}-${month}-${day}`;\r\n\t\t}\r\n\r\n\t\tconst hours = DateUtil.formatNumber(d.getHours());\r\n\t\tconst minutes = DateUtil.formatNumber(d.getMinutes());\r\n\t\tconst seconds = DateUtil.formatNumber(d.getSeconds());\r\n\t\treturn `${year}-${month}-${day}T${hours}:${minutes}:${seconds}`;\r\n\t}\r\n\r\n\tstatic formatDateTimeForInput(d: Date | string | null | undefined): string {\r\n\t\treturn DateUtil.formatDateForInput(d, true);\r\n\t}\r\n\r\n\tstatic getDurationMs(d1?: Date | string | null, d2?: Date | string | null): number | null {\r\n\t\td1 = DateUtil.parseDate(d1);\r\n\t\td2 = DateUtil.parseDate(d2);\r\n\t\tif (ObjectUtil.isEmpty(d1) || ObjectUtil.isEmpty(d2)) return null;\r\n\t\ttry {\r\n\t\t\t// @ts-ignore\r\n\t\t\treturn d2.getTime() - d1.getTime();\r\n\t\t} catch (e) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\t}\r\n\r\n\tstatic getSinceDurationMs(d1?: Date | string | null): number | null {\r\n\t\treturn DateUtil.getDurationMs(d1, new Date());\r\n\t}\r\n\r\n\tstatic formatDuration(ms?: number | null): string {\r\n\t\tif (!ms) {\r\n\t\t\treturn '';\r\n\t\t}\r\n\r\n\t\tlet secs = Math.floor(ms / 1000);\r\n\t\tms -= secs * 1000;\r\n\t\tlet mins = Math.floor(secs / 60);\r\n\t\tsecs -= mins * 60;\r\n\t\tlet hrs = Math.floor(mins / 60);\r\n\t\tmins -= hrs * 60;\r\n\t\tlet days = Math.floor(hrs / 24);\r\n\t\thrs -= days * 24;\r\n\r\n\t\tconst items = [];\r\n\t\tif (days > 0) items.push(`${days}d`);\r\n\t\tif (hrs > 0) items.push(`${hrs}h`);\r\n\t\tif (mins > 0) items.push(`${mins}m`);\r\n\t\tif (secs > 0 && days === 0 && hrs === 0) items.push(`${secs}s`);\r\n\t\tif (ms > 0 && days === 0 && hrs === 0 && mins === 0) items.push(`${NumberUtil.round(ms, 2)}ms`);\r\n\r\n\t\treturn items.join(' ');\r\n\t}\r\n}\r\n","import {StringUtil} from \"./StringUtil\";\n\nexport class JsonUtil {\n\n\tstatic reISO = /^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2}(?:\\.\\d*))(?:Z|(\\+|-)([\\d|:]*))?$/;\n\n\tstatic dateParser(key: string, value: any): any {\n\t\tif (typeof value === 'string' && JsonUtil.reISO.exec(value)) return new Date(value);\n\t\treturn value;\n\t}\n\n\tstatic parseWithDates(json?: string | null): any {\n\t\tif (StringUtil.isBlank(json)) return undefined;\n\t\treturn JSON.parse(StringUtil.getNonEmpty(json), JsonUtil.dateParser);\n\t}\n\n\tstatic parse(json?: string | null): any {\n\t\treturn JsonUtil.parseWithDates(json);\n\t}\n}\n","import {StringUtil} from \"./StringUtil\";\n\nexport class UrlUtil {\n\n\tstatic deleteParamFromUrl(url: string, paramName: string): string {\n\t\tconst urlObj = new URL(url);\n\t\turlObj.searchParams.delete(paramName);\n\t\treturn StringUtil.trimTrailingSlashes(urlObj.toString());\n\t}\n\n\tstatic extractParamFromUrl(url: string, name: string): string | null {\n\t\tconst usp = new URLSearchParams(new URL(url).search);\n\t\treturn usp.get(name);\n\t}\n\n\tstatic paramExistsInUrl(url: string, name: string): boolean {\n\t\treturn StringUtil.notBlank(UrlUtil.extractParamFromUrl(url, name));\n\t}\n\n\tstatic extractHostFromUrl(url: string): string | null {\n\t\tif (StringUtil.isBlank(url)) return null;\n\t\treturn new URL(url).host;\n\t}\n\n\tstatic extractDomainFromUrl(url: string): string | null {\n\t\tconst host = UrlUtil.extractHostFromUrl(url);\n\t\tif (StringUtil.isBlank(host)) return null;\n\t\treturn host.split('.').slice(-2).join('.');\n\t}\n}\n","import { StringUtil, PagingUtil, JsonUtil } from \"../util\";\nimport { PagingRequest } from \"../type\";\n\nexport type RequestOptions = RequestInit & {\n headers: Headers;\n};\n\nexport class RestClient {\n private baseUrl: URL;\n\n constructor(baseUrl: string) {\n if (StringUtil.isBlank(baseUrl)) {\n this.baseUrl = RestClient.baseHostUrl();\n return;\n }\n if (!baseUrl.endsWith(\"/\")) baseUrl = baseUrl + \"/\";\n this.baseUrl = baseUrl.startsWith(\"http\")\n ? new URL(baseUrl)\n : new URL(baseUrl, RestClient.baseHostUrl());\n }\n\n static baseHostUrl(): URL {\n return new URL(`${window.location.protocol}//${window.location.host}/`);\n }\n\n static pagingRequestToQueryParams(pr?: PagingRequest | null): any {\n return PagingUtil.pagingRequestToQueryParams(pr);\n }\n\n static paramsToQueryString(params?: any): string {\n if (!params) return \"\";\n const original = new URLSearchParams(params);\n const cleaned = new URLSearchParams();\n original.forEach((value, key) => {\n if (value !== \"\" && value !== undefined && value !== \"undefined\")\n cleaned.set(key, value);\n });\n const str = cleaned.toString();\n return StringUtil.isEmpty(str) ? \"\" : `?${str}`;\n }\n\n /**\n * Override this to customize http headers.\n */\n getHeaders(endpoint: string): Promise<Headers> {\n const headers = new Headers();\n headers.set(\"Content-Type\", \"application/json\");\n return Promise.resolve(headers);\n }\n\n getBaseUrl(): URL {\n return this.baseUrl;\n }\n\n getUrl(endpoint: string, params?: any): URL {\n const url = new URL(\n StringUtil.trimLeadingSlashes(endpoint),\n this.getBaseUrl(),\n );\n if (params) {\n Object.keys(params).forEach((key) => {\n const value = params[key];\n if (value !== \"\" && value !== undefined && value !== \"undefined\")\n url.searchParams.set(key, value);\n });\n }\n return url;\n }\n\n getRequestOptions(\n endpoint: string,\n method: string = \"GET\",\n data: any = null,\n ): Promise<RequestOptions> {\n return this.getHeaders(endpoint).then((headers) => {\n return {\n method: method,\n headers: headers,\n body:\n data === null\n ? null\n : (data instanceof FormData || typeof data === 'string')\n ? data\n : JSON.stringify(data),\n };\n });\n }\n\n processRequest(\n endpoint: string,\n params?: any,\n requestOptions?: RequestOptions,\n ): Promise<Response> {\n return fetch(this.getUrl(endpoint, params), requestOptions).then(\n (response) => {\n if (!response.ok) {\n const options = { cause: response.status };\n if (response.headers.get(\"Content-Type\") === \"application/json\") {\n return response.json().then(\n (json) => {\n if (json.message) {\n // @ts-ignore\n throw new Error(json.message, options);\n }\n if (json.error) {\n // @ts-ignore\n throw new Error(json.error, options);\n }\n // @ts-ignore\n throw new Error(response.statusText, options);\n },\n () => {\n // @ts-ignore\n throw new Error(response.statusText, options);\n },\n );\n } else {\n return response.text().then(\n (t) => {\n if (StringUtil.isEmpty(t)) {\n // @ts-ignore\n throw new Error(response.statusText, options);\n } else {\n // @ts-ignore\n throw new Error(t, options);\n }\n },\n () => {\n // @ts-ignore\n throw new Error(response.statusText, options);\n },\n );\n }\n }\n return response;\n },\n );\n }\n\n processRequestJson(\n endpoint: string,\n params?: any,\n requestOptions?: RequestOptions,\n ): Promise<any> {\n return this.processRequest(endpoint, params, requestOptions).then(\n (response) => {\n return response.text().then(JsonUtil.parseWithDates);\n },\n );\n }\n\n getJson(url: string, params?: any): Promise<any> {\n return this.getRequestOptions(url).then((o) =>\n this.processRequestJson(url, params, o),\n );\n }\n\n postJson(\n url: string,\n data: object | null = null,\n params?: any,\n ): Promise<any> {\n return this.getRequestOptions(url, \"POST\", data).then((o) =>\n this.processRequestJson(url, params, o),\n );\n }\n\n postForm(url: string, data: FormData, params?: any): Promise<Response> {\n return this.getRequestOptions(url, \"POST\", data).then((o) => {\n o.headers.delete(\"Content-Type\"); // content type with boundary value will be auto-generated\n return this.processRequest(url, params, o);\n });\n }\n\n postFormJson(url: string, data: FormData, params?: any): Promise<any> {\n return this.getRequestOptions(url, \"POST\", data).then((o) => {\n o.headers.delete(\"Content-Type\"); // content type with boundary value will be auto-generated\n return this.processRequestJson(url, params, o);\n });\n }\n\n putJson(url: string, data: object | null = null, params?: any): Promise<any> {\n return this.getRequestOptions(url, \"PUT\", data).then((o) =>\n this.processRequestJson(url, params, o),\n );\n }\n\n get(endpoint: string, params?: any): Promise<Response> {\n return this.getRequestOptions(endpoint).then((o) =>\n this.processRequest(endpoint, params, o),\n );\n }\n\n del(url: string, params?: any): Promise<Response> {\n return this.getRequestOptions(url, \"DELETE\").then((o) =>\n this.processRequest(url, params, o),\n );\n }\n\n post(\n url: string,\n data: any = null,\n params?: any,\n ): Promise<Response> {\n return this.getRequestOptions(url, \"POST\", data).then((o) =>\n this.processRequest(url, params, o),\n );\n }\n\n put(\n url: string,\n data: any = null,\n params?: any,\n ): Promise<Response> {\n return this.getRequestOptions(url, \"PUT\", data).then((o) =>\n this.processRequest(url, params, o),\n );\n }\n}\n","import {EntityBase} from \"../type/Entity\";\r\nimport {RestClient} from \"./RestClient\";\r\nimport {Page, PagingRequest} from \"../type\";\r\n\r\nexport class EntityClient<T extends EntityBase> {\r\n\r\n\tclient: RestClient;\r\n\r\n\tname: string;\r\n\r\n\tconstructor(client: RestClient, name: string) {\r\n\t\tthis.client = client;\r\n\t\tthis.name = name;\r\n\t}\r\n\r\n\tloadSingle(id: number): Promise<T> {\r\n\t\treturn this.client.getJson(`${this.name}/${id}`);\r\n\t}\r\n\r\n\tloadPage(pr: PagingRequest): Promise<Page<T>> {\r\n\t\treturn this.client.getJson(this.name, RestClient.pagingRequestToQueryParams(pr));\r\n\t}\r\n\r\n\tsave(d: T): Promise<T> {\r\n\t\tif (d.id) {\r\n\t\t\treturn this.client.putJson(`${this.name}/${d.id}`, d);\r\n\t\t} else {\r\n\t\t\treturn this.client.postJson(this.name, d);\r\n\t\t}\r\n\t}\r\n\r\n\tdelete(id: number): Promise<any> {\r\n\t\treturn this.client.del(`${this.name}/${id}`);\r\n\t}\r\n\r\n}\r\n","export type Func = { (arg?: any): void; }\r\nexport type FuncHandlers = Array<Func>;\r\nexport type FuncHandlersCache = Map<string, FuncHandlers>;\r\n\r\nexport class EventManager {\r\n\r\n\thandlers: FuncHandlersCache;\r\n\r\n\tconstructor() {\r\n\t\tthis.handlers = new Map<string, FuncHandlers>();\r\n\t}\r\n\r\n\taddEventListener(event: string, handler: Func) {\r\n\t\tif (!this.handlers.has(event)) this.handlers.set(event, []);\r\n\t\t// @ts-ignore\r\n\t\tthis.handlers.get(event).push(handler);\r\n\t}\r\n\r\n\tremoveEventListener(event: string, handler: Func) {\r\n\t\tconst handlers: FuncHandlers | undefined = this.handlers.get(event);\r\n\t\tif (handlers) handlers.splice(handlers.indexOf(handler), 1);\r\n\t}\r\n\r\n\ttriggerEvent(event: string, arg?: any) {\r\n\t\tif (!this.handlers.has(event)) return;\r\n\t\t// @ts-ignore\r\n\t\tthis.handlers.get(event).forEach((h: Func) => h(arg));\r\n\t}\r\n\r\n}\r\n","export enum UserAlertType {\r\n\tinfo = 'info',\r\n\twarning = 'warning',\r\n\terror = 'danger'\r\n}\r\n\r\nexport type UserAlert = {\r\n\ttime: Date;\r\n\ttype: UserAlertType;\r\n\tmessage: string;\r\n\tremainsMs?: number; //remain visible for this amount of seconds\r\n}\r\n","\nexport const PERMISSION_LEVELS = [\"read\", \"write\", \"admin\"] as const;\n\nexport type PermissionLevel = (typeof PERMISSION_LEVELS)[number];\n\nexport type TokenRequestPayloadBase = {\n\ttargetAudience: string;\n};\n\nexport type RequestAccessTokenPayload = TokenRequestPayloadBase & {\n\trefreshToken: string;\n\tscope: string;\n};\n\nexport type RenewRefreshTokenPayload = {\n\trefreshToken: string;\n};\n\nexport type RequestRefreshTokenFromLoginPayload = TokenRequestPayloadBase & {\n\tlogin: string;\n\tpassword: string;\n};\n\nexport type TokenResponsePayloadBase = {\n\ttoken: string;\n\tissuedAt: Date;\n\texpires?: Date | null;\n};\n\nexport type IdTokenPayload = TokenResponsePayloadBase & {};\n\nexport type AccessTokenPayload = TokenResponsePayloadBase & {\n\tscopes?: Array<string>;\n};\n\nexport type RefreshTokenPayload = TokenResponsePayloadBase & {};\n\nexport type JwKeyPayload = {\n\tkty: string;\n\tkid: string;\n\tn: string;\n\te: string;\n};\n\nexport type JwksPayload = {\n\tkeys: Array<JwKeyPayload>;\n};\n","import { StringUtil, ObjectUtil } from \"../util\";\nimport {PERMISSION_LEVELS, PermissionLevel, TokenResponsePayloadBase} from \"./Types\";\n\nexport class OAuthUtil {\n static isValidToken(token?: TokenResponsePayloadBase | null): boolean {\n return (\n ObjectUtil.notEmpty(token) &&\n StringUtil.notBlank(token.token) &&\n !OAuthUtil.isTokenExpired(token)\n );\n }\n\n static isTokenExpired(token?: TokenResponsePayloadBase | null): boolean {\n if (token === undefined || token === null) return false;\n if (token.expires === undefined || token.expires === null) return false;\n return token.expires < new Date();\n }\n\n static isTokenReadyForRefresh(\n token?: TokenResponsePayloadBase | null,\n ): boolean {\n if (token === undefined || token === null) return false;\n if (OAuthUtil.isTokenExpired(token)) return false;\n if (token.expires === undefined || token.expires === null) return false;\n const middle = new Date(\n (token.expires.getTime() + token.issuedAt.getTime()) / 2,\n );\n const now = new Date();\n return middle < now;\n }\n\n public static getScopeString(privilege: string, level: PermissionLevel) {\n return `${level}:${privilege}`;\n }\n\n public static extractPrivilege(scope: string): string {\n const arr = scope.split(\":\");\n if (arr.length < 2) return \"\";\n return arr[1];\n }\n\n public static isPermissionLevel(value: string): value is PermissionLevel {\n return (PERMISSION_LEVELS as readonly string[]).includes(value);\n }\n\n public static extractPermissionLevel(scope: string): PermissionLevel {\n const arr = scope.split(\":\");\n if (arr.length === 0) throw new Error(`Scope value ${scope} is invalid!`);\n const str = arr[0];\n if (!OAuthUtil.isPermissionLevel(str))\n throw new Error(`\"${str} is not valid permission level!`);\n return str;\n }\n\n public static getLevel(level: PermissionLevel): number {\n switch (level) {\n case \"admin\":\n return 3;\n case \"write\":\n return 2;\n case \"read\":\n return 1;\n default:\n return 0;\n }\n }\n\n /**\n * Returns true if given scope grants permission for specific privilege on at least required level.\n *\n * @param ownedScope Existing scope, usually owned by user in form of access token\n * @param requiredScopeOrPrivilege Required privilege name or whole scope (omit minLevel)\n * @param minLevel Required minimal permission level\n */\n public static hasPermission(\n ownedScope: string,\n requiredScopeOrPrivilege: string,\n minLevel?: PermissionLevel,\n ): boolean {\n if (minLevel === undefined) {\n try {\n minLevel = OAuthUtil.extractPermissionLevel(requiredScopeOrPrivilege);\n requiredScopeOrPrivilege = OAuthUtil.extractPrivilege(\n requiredScopeOrPrivilege,\n );\n } catch (e) {\n minLevel = \"admin\";\n }\n }\n\n const ownedLevel = OAuthUtil.extractPermissionLevel(ownedScope);\n // owned level must be at least equal to the required\n if (OAuthUtil.getLevel(ownedLevel) < OAuthUtil.getLevel(minLevel))\n return false;\n\n const ownedPrivilege = OAuthUtil.extractPrivilege(ownedScope);\n // super admin, has privilege for all resources\n if (ownedPrivilege === \"*\") return true;\n // user has exactly the required privilege\n if (ownedPrivilege === requiredScopeOrPrivilege) return true;\n // now the only possibility is that user has privilege ending with * covering the required privilege\n if (!ownedPrivilege?.endsWith(\"/*\")) return false;\n\n const ownedParent = ownedPrivilege.replace(\"/*\", \"\");\n return requiredScopeOrPrivilege?.startsWith(ownedParent) ?? false;\n }\n}\n","import { RestClient } from \"../client\";\nimport { StringUtil } from \"../util\";\nimport {\n\tAccessTokenPayload,\n\tIdTokenPayload,\n\tJwksPayload,\n\tRefreshTokenPayload,\n\tRenewRefreshTokenPayload, RequestAccessTokenPayload,\n\tRequestRefreshTokenFromLoginPayload\n} from \"./Types\";\n\n/**\n * This implements rest client for OAuth server - https://github.com/lotcz/oauth-server\n * Provide basic url, /api/oauth path prefix will be added automatically\n */\nexport class OAuthRestClient extends RestClient {\n constructor(oauthUrl: string) {\n super(`${StringUtil.trimSlashes(oauthUrl)}/api/oauth`);\n }\n\n jwks(): Promise<JwksPayload> {\n return this.getJson(\"jwks.json\");\n }\n\n verifyRefreshToken(refreshToken: string): Promise<RefreshTokenPayload> {\n return this.getJson(`refresh-tokens/verify/${refreshToken}`);\n }\n\n verifyAccessToken(accessToken: string): Promise<AccessTokenPayload> {\n return this.getJson(`access-tokens/verify/${accessToken}`);\n }\n\n verifyIdToken(idToken: string): Promise<IdTokenPayload> {\n return this.getJson(`id-tokens/verify/${idToken}`);\n }\n\n requestRefreshTokenFromLogin(\n request: RequestRefreshTokenFromLoginPayload,\n ): Promise<RefreshTokenPayload> {\n return this.postJson(\"refresh-tokens/from-login\", request);\n }\n\n renewRefreshToken(\n request: RenewRefreshTokenPayload,\n ): Promise<RefreshTokenPayload> {\n return this.postJson(\"refresh-tokens/renew\", request);\n }\n\n requestAccessToken(\n request: RequestAccessTokenPayload,\n ): Promise<AccessTokenPayload> {\n return this.postJson(\"access-tokens/from-refresh-token\", request);\n }\n}\n","import {\n\tAccessTokenPayload,\n\tIdTokenPayload,\n\tRefreshTokenPayload,\n} from \"./Types\";\nimport {OAuthRefreshTokenProvider} from \"./tokenprovider/OAuthRefreshTokenProvider\";\nimport {OAuthUtil} from \"./OAuthUtil\";\nimport {OAuthRestClient} from \"./OAuthRestClient\";\n\n/**\n * Manages refresh of id and access tokens.\n */\nexport class OAuthTokenManager implements OAuthRefreshTokenProvider {\n\toAuthServer: OAuthRestClient;\n\n\taudience: string;\n\n\trefreshToken?: RefreshTokenPayload;\n\n\tinitialRefreshTokenProvider: OAuthRefreshTokenProvider;\n\n\taccessTokens: Map<string, AccessTokenPayload>;\n\n\tconstructor(\n\t\toAuthServerBaseUrl: string,\n\t\ttargetAudience: string,\n\t\tinitialRefreshTokenProvider: OAuthRefreshTokenProvider,\n\t) {\n\t\tthis.initialRefreshTokenProvider = initialRefreshTokenProvider;\n\t\tthis.audience = targetAudience;\n\t\tthis.oAuthServer = new OAuthRestClient(oAuthServerBaseUrl);\n\t\tthis.accessTokens = new Map<string, AccessTokenPayload>();\n\t}\n\n\thasValidRefreshToken(): boolean {\n\t\treturn OAuthUtil.isValidToken(this.refreshToken);\n\t}\n\n\thasValidAccessToken(privilege: string): boolean {\n\t\treturn OAuthUtil.isValidToken(this.accessTokens.get(privilege));\n\t}\n\n\treset(): Promise<any> {\n\t\tthis.refreshToken = undefined;\n\t\tthis.accessTokens.clear();\n\t\treturn this.initialRefreshTokenProvider.reset();\n\t}\n\n\t/**\n\t * Get stored id token or ask the provider, this will trigger redirect to login screen in case of the default provider\n\t */\n\tgetRefreshTokenInternal(): Promise<RefreshTokenPayload> {\n\t\tif (this.refreshToken !== undefined && this.hasValidRefreshToken()) {\n\t\t\treturn Promise.resolve(this.refreshToken);\n\t\t}\n\t\treturn this.initialRefreshTokenProvider.getRefreshToken();\n\t}\n\n\t/**\n\t * Get id token, refresh it if needed\n\t */\n\tgetRefreshToken(): Promise<IdTokenPayload> {\n\t\treturn this.getRefreshTokenInternal().then(\n\t\t\t(t: RefreshTokenPayload) => {\n\t\t\t\tif (!OAuthUtil.isValidToken(t)) {\n\t\t\t\t\tconsole.log(\"invalid refresh token\", t);\n\t\t\t\t\treturn Promise.reject(\"Received invalid refresh token!\");\n\t\t\t\t}\n\t\t\t\tif (OAuthUtil.isTokenReadyForRefresh(t)) {\n\t\t\t\t\treturn this.oAuthServer\n\t\t\t\t\t\t.renewRefreshToken({refreshToken: t.token})\n\t\t\t\t\t\t.then((t) => {\n\t\t\t\t\t\t\tthis.setRefreshToken(t);\n\t\t\t\t\t\t\treturn t;\n\t\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis.setRefreshToken(t);\n\t\t\t\treturn Promise.resolve(t);\n\t\t\t}\n\t\t);\n\t}\n\n\tgetRefreshTokenRaw(): Promise<string> {\n\t\treturn this.getRefreshToken().then((t) => t.token);\n\t}\n\n\tsetRefreshToken(token?: RefreshTokenPayload) {\n\t\tthis.refreshToken = token;\n\t}\n\n\tverifyRefreshToken(token: string): Promise<RefreshTokenPayload> {\n\t\treturn this.oAuthServer.verifyRefreshToken(token);\n\t}\n\n\tlogin(login: string, password: string): Promise<RefreshTokenPayload> {\n\t\tthis.reset();\n\t\treturn this.oAuthServer\n\t\t\t.requestRefreshTokenFromLogin({\n\t\t\t\tlogin: login,\n\t\t\t\tpassword: password,\n\t\t\t\ttargetAudience: this.audience,\n\t\t\t})\n\t\t\t.then((t) => {\n\t\t\t\tthis.setRefreshToken(t);\n\t\t\t\treturn t;\n\t\t\t});\n\t}\n\n\tprivate storeAccessToken(scope: string, token: AccessTokenPayload) {\n\t\tthis.accessTokens.set(scope, token);\n\t}\n\n\tprivate findStoredAccessToken(scope: string): AccessTokenPayload | undefined {\n\t\tconst level = OAuthUtil.extractPermissionLevel(scope);\n\t\tconst privilege = OAuthUtil.extractPrivilege(scope);\n\t\tfor (const [s, token] of this.accessTokens) {\n\t\t\tif (OAuthUtil.hasPermission(s, privilege, level)) return token;\n\t\t}\n\t\treturn undefined;\n\t}\n\n\tprivate getAccessTokenInternal(scope: string): Promise<AccessTokenPayload> {\n\t\treturn this.getRefreshTokenRaw().then(\n\t\t\t(refreshToken: string) => this.oAuthServer\n\t\t\t\t.requestAccessToken(\n\t\t\t\t\t{\n\t\t\t\t\t\trefreshToken: refreshToken,\n\t\t\t\t\t\ttargetAudience: this.audience,\n\t\t\t\t\t\tscope: scope,\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t\t.then(\n\t\t\t\t\t(act: AccessTokenPayload) => {\n\t\t\t\t\t\tif (!OAuthUtil.isValidToken(act)) {\n\t\t\t\t\t\t\treturn Promise.reject(\"Received access token is not valid!\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (act.scopes && act.scopes.length > 0) {\n\t\t\t\t\t\t\tact.scopes.forEach((s) => this.storeAccessToken(s, act));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.storeAccessToken(scope, act);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn act;\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t);\n\t}\n\n\tgetAccessToken(scope: string): Promise<string> {\n\t\tconst existing = this.findStoredAccessToken(scope);\n\t\tif (existing === undefined || !OAuthUtil.isValidToken(existing))\n\t\t\treturn this.getAccessTokenInternal(scope).then((t) => t.token);\n\t\t// preload access token if it is going to expire soon\n\t\tif (OAuthUtil.isTokenReadyForRefresh(existing))\n\t\t\tthis.getAccessTokenInternal(scope);\n\t\treturn Promise.resolve(existing.token);\n\t}\n}\n","import {StringUtil} from \"../../util\";\n\nexport class RedirectionProvider {\n\n\tprivate redirecting?: string;\n\n\tredirectTo(url: string): Promise<any> {\n\t\tthis.redirecting = url;\n\t\tdocument.location.href = url;\n\t\treturn Promise.reject(`Redirecting to ${url}`);\n\t}\n\n\tisRedirecting(): boolean {\n\t\treturn StringUtil.notBlank(this.redirecting);\n\t}\n\n\tredirectingTo(): string {\n\t\treturn StringUtil.getNonEmpty(this.redirecting);\n\t}\n\n}\n","import {OAuthRefreshTokenProvider} from \"./OAuthRefreshTokenProvider\";\nimport {IdTokenPayload} from \"../Types\";\nimport {RedirectionProvider} from \"./RedirectionProvider\";\nimport {RestClientWithOAuth} from \"../RestClientWithOAuth\";\nimport {UrlUtil} from \"../../util\";\n\nexport class RefreshTokenProviderLogin extends RedirectionProvider implements OAuthRefreshTokenProvider {\n\n\tclient: RestClientWithOAuth;\n\n\ttokenQueryName: string;\n\n\tconstructor(client: RestClientWithOAuth, tokenQueryName?: string) {\n\t\tsuper();\n\t\tthis.client = client;\n\t\tthis.tokenQueryName = tokenQueryName || 'token';\n\t}\n\n\tredirectToLogin(): Promise<any> {\n\t\treturn this.client.getServerInfo().then(\n\t\t\t(si) => {\n\t\t\t\tconst thisUrl = UrlUtil.deleteParamFromUrl(document.location.toString(), this.tokenQueryName);\n\t\t\t\tconst location = `${si.oauthServerUrl}/login?app_name=${si.targetAudience}&redirect_url=${thisUrl}`;\n\t\t\t\treturn this.redirectTo(location);\n\t\t\t}\n\t\t).catch((err) => {\n\t\t\tconsole.error('Redirection failed: OAuth info not fetched:', err);\n\t\t\treturn Promise.reject(err);\n\t\t});\n\t}\n\n\tgetRefreshToken(): Promise<IdTokenPayload> {\n return this.redirectToLogin();\n }\n\n\treset(): Promise<any> {\n\t\treturn Promise.resolve();\n\t}\n}\n","import {OAuthRefreshTokenProvider} from \"./OAuthRefreshTokenProvider\";\nimport {RefreshTokenPayload} from \"../Types\";\nimport {RestClientWithOAuth} from \"../RestClientWithOAuth\";\nimport {StringUtil, UrlUtil} from \"../../util\";\nimport {RedirectionProvider} from \"./RedirectionProvider\";\n\nexport class RefreshTokenProviderUrl extends RedirectionProvider implements OAuthRefreshTokenProvider {\n\n\tclient: RestClientWithOAuth;\n\n\ttokenQueryName: string;\n\n\tconstructor(client: RestClientWithOAuth, tokenQueryName?: string) {\n\t\tsuper();\n\t\tthis.client = client;\n\t\tthis.tokenQueryName = tokenQueryName || 'token';\n\t}\n\n\tgetRefreshTokenFromUrl(): string | null {\n\t\treturn UrlUtil.extractParamFromUrl(document.location.toString(), this.tokenQueryName);\n\t}\n\n\tgetRefreshToken(): Promise<RefreshTokenPayload> {\n\t\tconst raw = this.getRefreshTokenFromUrl();\n\t\tif (raw === null || StringUtil.isBlank(raw)) return Promise.reject(\"No token in URL!\");\n\t\treturn this.client\n\t\t\t.getTokenManager()\n\t\t\t.then(m => m.verifyRefreshToken(raw));\n }\n\n\treset(): Promise<any> {\n\t\tconst raw = this.getRefreshTokenFromUrl();\n\t\tif (raw === null || StringUtil.isBlank(raw)) return Promise.resolve();\n\t\tconsole.log(\"Token in URL, redirecting...\");\n\t\tconst thisUrl = UrlUtil.deleteParamFromUrl(document.location.toString(), this.tokenQueryName);\n\t\treturn this.redirectTo(thisUrl);\n\t}\n}\n","import {OAuthRefreshTokenProvider} from \"./OAuthRefreshTokenProvider\";\nimport {RefreshTokenPayload} from \"../Types\";\nimport {JsonUtil} from \"../../util\";\nimport {OAuthUtil} from \"../OAuthUtil\";\n\nexport class RefreshTokenProviderStorage implements OAuthRefreshTokenProvider {\n\n\tkey: string;\n\n\tconstructor(storageKey?: string) {\n\t\tthis.key = storageKey || 'refresh-token';\n\t}\n\n\tsaveRefreshTokenToLocalStorage(token: RefreshTokenPayload | null) {\n\t\tconst raw = token ? JSON.stringify(token) : null;\n\t\tif (raw === null) {\n\t\t\tlocalStorage.removeItem(this.key);\n\t\t\treturn;\n\t\t}\n\t\tlocalStorage.setItem(this.key, raw);\n\t}\n\n\tgetRefreshTokenFromLocalStorage(): RefreshTokenPayload | null | undefined {\n\t\treturn JsonUtil.parse(localStorage.getItem(this.key));\n\t}\n\n\tgetRefreshToken(): Promise<RefreshTokenPayload> {\n const token = this.getRefreshTokenFromLocalStorage();\n\t\tif (token && OAuthUtil.isValidToken(token)) return Promise.resolve(token);\n\t\treturn Promise.reject(\"No valid token found in storage!\");\n }\n\n\treset(): Promise<any> {\n\t\tthis.saveRefreshTokenToLocalStorage(null);\n\t\treturn Promise.resolve();\n\t}\n}\n","import {OAuthRefreshTokenProvider} from \"./OAuthRefreshTokenProvider\";\nimport {IdTokenPayload} from \"../Types\";\nimport {RefreshTokenProviderLogin} from \"./RefreshTokenProviderLogin\";\nimport {RestClientWithOAuth} from \"../RestClientWithOAuth\";\nimport {RefreshTokenProviderUrl} from \"./RefreshTokenProviderUrl\";\nimport {RefreshTokenProviderStorage} from \"./RefreshTokenProviderStorage\";\n\nexport class RefreshTokenProviderDefault implements OAuthRefreshTokenProvider {\n\n\tlogin: RefreshTokenProviderLogin;\n\n\turl: RefreshTokenProviderUrl;\n\n\tstorage: RefreshTokenProviderStorage;\n\n\tconstructor(client: RestClientWithOAuth, tokenStorageKey?: string, tokenUrlName?: string) {\n\t\tthis.login = new RefreshTokenProviderLogin(client, tokenUrlName);\n\t\tthis.url = new RefreshTokenProviderUrl(client, tokenUrlName);\n\t\tthis.storage = new RefreshTokenProviderStorage(tokenStorageKey);\n\t}\n\n\tgetRefreshToken(): Promise<IdTokenPayload> {\n\t\treturn this.url\n\t\t\t.getRefreshToken()\n\t\t\t.catch(\n\t\t\t\t(err) => {\n\t\t\t\t\tconsole.log(\"No token in url, loading from storage:\", err);\n\t\t\t\t\treturn this.storage\n\t\t\t\t\t\t.getRefreshToken()\n\t\t\t\t\t\t.catch(\n\t\t\t\t\t\t\t(err) => {\n\t\t\t\t\t\t\t\tconsole.log(\"No token in storage, redirecting to login page:\", err);\n\t\t\t\t\t\t\t\treturn this.login.getRefreshToken();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t)\n\t\t\t.then(\n\t\t\t\t(t) => {\n\t\t\t\t\tconsole.log(\"Token found, saving to storage...\");\n\t\t\t\t\tthis.storage.saveRefreshTokenToLocalStorage(t);\n\t\t\t\t\t// redirect if token is in url\n\t\t\t\t\treturn this.url.reset().then(() => t);\n\t\t\t\t}\n\t\t\t);\n }\n\n\treset(): Promise<any> {\n\t\treturn this.storage.reset().then(() => this.url.reset());\n\t}\n\n}\n","import {NumberUtil} from \"../util\";\r\n\r\nexport class Vector2 {\r\n\tx: number;\r\n\ty: number;\r\n\r\n\tconstructor(x: number, y: number) {\r\n\t\tthis.x = x;\r\n\t\tthis.y = y;\r\n\t}\r\n\r\n\tdistanceTo(v: Vector2) {\r\n\t\treturn Math.sqrt(Math.pow(this.x - v.x, 2) + Math.pow(this.y - v.y, 2));\r\n\t}\r\n\r\n\tequalsTo(v: Vector2) {\r\n\t\treturn (v) ? this.x === v.x && this.y === v.y : false;\r\n\t}\r\n\r\n\tsize() {\r\n\t\treturn this.distanceTo(new Vector2(0, 0));\r\n\t}\r\n\r\n\tinSize(size: number): Vector2 {\r\n\t\tconst currentSize = this.size();\r\n\t\tif (currentSize !== 0) {\r\n\t\t\tconst ratio = size / currentSize;\r\n\t\t\treturn new Vector2(this.x * ratio, this.y * ratio);\r\n\t\t}\r\n\t\treturn this;\r\n\t}\r\n\r\n\tround(): Vector2 {\r\n\t\treturn new Vector2(Math.round(this.x), Math.round(this.y));\r\n\t}\r\n\r\n\tadd(v: Vector2): Vector2 {\r\n\t\treturn new Vector2(this.x + v.x, this.y + v.y);\r\n\t}\r\n\r\n\tmultiply(s: number): Vector2 {\r\n\t\treturn new Vector2(this.x * s, this.y * s);\r\n\t}\r\n\r\n\tsubtract(v: Vector2): Vector2 {\r\n\t\treturn new Vector2(this.x - v.x, this.y - v.y);\r\n\t}\r\n\r\n\tsub(v: Vector2): Vector2 {\r\n\t\treturn this.subtract(v);\r\n\t}\r\n\r\n\ttoArray(): number[] {\r\n\t\treturn [this.x, this.y];\r\n\t}\r\n\r\n\tstatic fromArray(arr: number[]) {\r\n\t\tif (typeof arr === 'object' && arr.length === 2) {\r\n\t\t\treturn new Vector2(arr[0], arr[1]);\r\n\t\t}\r\n\t}\r\n\r\n\tclone(): Vector2 {\r\n\t\treturn new Vector2(this.x, this.y);\r\n\t}\r\n\r\n\t/***\r\n\t * Return angle between AB and Y axis in radians\r\n\t * @param {Vector2} b\r\n\t * @returns {number}\r\n\t */\r\n\tgetAngleToYAxis(b: Vector2): number {\r\n\t\tconst diff = b.subtract(this);\r\n\t\tconst down = diff.y < 0;\r\n\t\tconst sinX = diff.x / diff.size();\r\n\t\tconst angle = Math.asin(sinX);\r\n\t\tconst result = down ?\r\n\t\t\tMath.PI - angle :\r\n\t\t\tangle;\r\n\t\treturn result || 0;\r\n\t}\r\n\r\n\tgetNeighborPositions(size = 1, includeCenter = false) {\r\n\t\tconst neighbors = [];\r\n\t\tconst maxX = this.x + size;\r\n\t\tfor (let x = this.x - size; x <= maxX; x++) {\r\n\t\t\tconst maxY = this.y + size;\r\n\t\t\tfor (let y = this.y - size; y <= maxY; y++) {\r\n\t\t\t\tconst n = new Vector2(x, y);\r\n\t\t\t\tif (includeCenter || !this.equalsTo(n)) {\r\n\t\t\t\t\tneighbors.push(n);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn neighbors;\r\n\t}\r\n\r\n\tgetClosest(positions: Vector2[]): Vector2 | null {\r\n\t\tif ((!positions) || positions.length === 0) return null;\r\n\t\tif (positions.length === 1) return positions[0];\r\n\t\tlet closest = positions[0];\r\n\t\tlet distance = this.distanceTo(closest);\r\n\t\tfor (let i = 1, max = positions.length; i < max; i++) {\r\n\t\t\tconst d = this.distanceTo(positions[i]);\r\n\t\t\tif (d < distance) {\r\n\t\t\t\tclosest = positions[i];\r\n\t\t\t\tdistance = d;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn closest;\r\n\t}\r\n\r\n\ttoString(decimals = 2) {\r\n\t\treturn `[${NumberUtil.round(this.x, decimals)},${NumberUtil.round(this.y, decimals)}]`;\r\n\t}\r\n}\r\n","import CzechBasicData from './lang/dictionary.cs.json';\r\nimport EnglishBasicData from './lang/dictionary.en.json';\r\n\r\nexport type TranslateParams = {\r\n\ttags?: Array<string>;\r\n}\r\n\r\nexport interface Dictionary {\r\n\ttranslate: (key: string, p?: TranslateParams) => string | undefined;\r\n}\r\n\r\nexport type DictionaryMemoryValue = {\r\n\ttags?: Array<string>;\r\n\tvalue: string;\r\n}\r\n\r\nexport interface DictionaryMemoryData {\r\n\t[key: string]: string | Array<DictionaryMemoryValue>;\r\n}\r\n\r\nexport class MemoryDictionary implements Dictionary {\r\n\r\n\tprivate data: DictionaryMemoryData;\r\n\r\n\tconstructor(data: DictionaryMemoryData) {\r\n\t\tthis.data = data;\r\n\t}\r\n\r\n\ttranslate(key: string, p?: TranslateParams) {\r\n\t\tconst r = this.data[key];\r\n\t\tif (r === undefined || typeof r === 'string') return r;\r\n\t\tconst def = r.find(\r\n\t\t\t(v) => (v.tags === undefined || v.tags.length === 0)\r\n\t\t);\r\n\t\tif ((p === undefined || p.tags === undefined || p.tags.length === 0) && def !== undefined) return def.value;\r\n\t\tconst cands = r.filter(\r\n\t\t\t(v) => {\r\n\t\t\t\tif (v.tags === undefined || v.tags.length === 0) return false;\r\n\t\t\t\treturn p && p.tags && p.tags.every((t) => v.tags && v.tags.includes(t));\r\n\t\t\t}\r\n\t\t);\r\n\t\tif (cands.length > 0) return cands[0].value;\r\n\t\treturn def ? def.value : undefined;\r\n\t};\r\n\r\n}\r\n\r\nexport class CzechBasicDictionary extends MemoryDictionary {\r\n\tconstructor() {\r\n\t\tsuper(CzechBasicData);\r\n\t}\r\n}\r\n\r\nexport class EnglishBasicDictionary extends MemoryDictionary {\r\n\tconstructor() {\r\n\t\tsuper(EnglishBasicData);\r\n\t}\r\n}\r\n\r\nexport class DictionaryWithFallback implements Dictionary {\r\n\r\n\tprivate primary: Dictionary;\r\n\r\n\tprivate fallback: Dictionary;\r\n\r\n\tconstructor(primary: Dictionary, fallback: Dictionary) {\r\n\t\tthis.primary = primary;\r\n\t\tthis.fallback = fallback;\r\n\t}\r\n\r\n\ttranslate(key: string, p?: TranslateParams) {\r\n\t\tconst pt = this.primary.translate(key, p);\r\n\t\tif (pt === undefined) return this.fallback.translate(key, p);\r\n\t\treturn pt;\r\n\t};\r\n}\r\n","import {CzechBasicDictionary, Dictionary, DictionaryWithFallback, EnglishBasicDictionary, TranslateParams} from \"./Dictionary\";\r\n\r\nexport class Localization implements Dictionary {\r\n\r\n\tprivate language: string | undefined;\r\n\r\n\tprivate dictionaries = new Map<string, Dictionary>;\r\n\r\n\tconstructor(language?: string) {\r\n\t\tthis.setLanguage(language);\r\n\t}\r\n\r\n\taddDictionary(language: string, dictionary: Dictionary) {\r\n\t\tconst existing = this.dictionaries.get(language);\r\n\t\tif (existing) {\r\n\t\t\tthis.dictionaries.set(language, new DictionaryWithFallback(dictionary, existing));\r\n\t\t} else {\r\n\t\t\tthis.dictionaries.set(language, dictionary);\r\n\t\t}\r\n\t}\r\n\r\n\thasDictionary(language?: string) {\r\n\t\tif (!language) return false;\r\n\t\treturn this.dictionaries.has(language);\r\n\t}\r\n\r\n\tgetLanguage(): string | undefined {\r\n\t\treturn this.language;\r\n\t}\r\n\r\n\tgetLanguages(): Array<string> {\r\n\t\treturn Array.from(this.dictionaries.keys());\r\n\t}\r\n\r\n\tsetLanguage(language?: string) {\r\n\t\tthis.language = language && this.hasDictionary(language)\r\n\t\t\t? language\r\n\t\t\t: this.hasDictionary(navigator.language) ? navigator.language : undefined\r\n\t}\r\n\r\n\ttranslate(key: string, p?: TranslateParams, language?: string) {\r\n\t\tlanguage = language ? language : this.language;\r\n\t\tif (!language) return key;\r\n\t\tconst d = this.dictionaries.get(language);\r\n\t\tif (!d) return key;\r\n\t\tconst t = d.translate(key, p);\r\n\t\tif (t === undefined) return key;\r\n\t\treturn t;\r\n\t}\r\n}\r\n\r\nexport class BasicLocalization extends Localization {\r\n\tconstructor(language?: string) {\r\n\t\tsuper();\r\n\t\tthis.addDictionary(\"cs\", new CzechBasicDictionary());\r\n\t\tthis.addDictionary(\"en\", new EnglishBasicDictionary());\r\n\t\tthis.setLanguage(language);\r\n\t}\r\n}\r\n","export class ByteUtil {\r\n\r\n\tstatic formatByteSize(size?: number | null): string {\r\n\t\tconst n = Number(size);\r\n\t\tif (n === null || Number.isNaN(n)) return '';\r\n\t\tif (n === 0) return '0';\r\n\t\tconst l = Math.floor(Math.log(n) / Math.log(1024));\r\n\t\treturn +((n / Math.pow(1024, l)).toFixed(2)) * 1 + ' ' + ['B', 'kB', 'MB', 'GB', 'TB'][l];\r\n\t}\r\n\r\n}\r\n","type CancelledWrapper = { value: boolean};\r\n\r\nexport class CancellablePromise {\r\n\r\n\tisCancelled: CancelledWrapper = { value: false };\r\n\r\n\tthrowWhenCancelled: boolean;\r\n\r\n\tpromise: Promise<any | void>;\r\n\r\n\tconstructor(promise: Promise<any | void>, throwWhenCancelled: boolean = false) {\r\n\t\tthis.throwWhenCancelled = throwWhenCancelled;\r\n\t\tthis.promise = new Promise(\r\n\t\t\t(resolve, reject) => {\r\n\t\t\t\tpromise\r\n\t\t\t\t\t.then(\r\n\t\t\t\t\t\tresult => {\r\n\t\t\t\t\t\t\tif (!this.isCancelled.value) {\r\n\t\t\t\t\t\t\t\treturn resolve(result);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t)\r\n\t\t\t\t\t.catch(\r\n\t\t\t\t\t\te => {\r\n\t\t\t\t\t\t\tif (this.throwWhenCancelled || !this.isCancelled.value) {\r\n\t\t\t\t\t\t\t\treject(e);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t);\r\n\t\t\t}\r\n\t\t);\r\n\t}\r\n\r\n\tcancel() {\r\n\t\tthis.isCancelled.value = true;\r\n\t}\r\n\r\n}\r\n","import {EntityClient} from \"./EntityClient\";\r\nimport {EntityBase} from \"../type/Entity\";\r\nimport { HashCacheAsync } from \"../cache\";\r\nimport { RestClient } from \"./RestClient\";\r\nimport {HashCacheStats} from \"../type\";\r\n\r\nexport class EntityCachedClient<T extends EntityBase> extends EntityClient<T> {\r\n\r\n\tprotected cache: HashCacheAsync<number, T>;\r\n\r\n\tconstructor(client: RestClient, name: string, maxSize?: number) {\r\n\t\tsuper(client, name);\r\n\t\tthis.cache = new HashCacheAsync<number, T>((id: number) => super.loadSingle(id), maxSize);\r\n\t}\r\n\r\n\tloadSingle(id: number): Promise<T> {\r\n\t\treturn this.cache.get(id);\r\n\t}\r\n\r\n\tsave(d: T): Promise<T> {\r\n\t\treturn super.save(d).then(\r\n\t\t\t(s: T): T => {\r\n\t\t\t\tif (s.id) this.cache.set(s.id, s);\r\n\t\t\t\treturn s;\r\n\t\t\t});\r\n\t}\r\n\r\n\tdelete(id: number): Promise<any> {\r\n\t\treturn super.delete(id).then(() => this.cache.reset(id));\r\n\t}\r\n\r\n\treset(id?: number) {\r\n\t\tthis.cache.reset(id);\r\n\t}\r\n\r\n\tgetStats(): HashCacheStats {\r\n\t\treturn this.cache.getStats();\r\n\t}\r\n}\r\n","import {EntityClient} from \"./EntityClient\";\r\nimport {EntityBase} from \"../type\";\r\n\r\nexport class EntityClientWithStub<T extends EntityBase, TStub extends EntityBase> extends EntityClient<T> {\r\n\r\n\tloadSingle(id: number): Promise<T> {\r\n\t\tthrow new Error(\"Use loadSingleStub() instead!\");\r\n\t}\r\n\r\n\tloadSingleStub(id: number): Promise<TStub> {\r\n\t\treturn this.client.getJson(`${this.name}/${id}`);\r\n\t}\r\n\r\n\tsave(d: T): Promise<T> {\r\n\t\tthrow new Error(\"Use saveStub() instead!\");\r\n\t}\r\n\r\n\tsaveStub(d: TStub): Promise<TStub> {\r\n\t\tif (d.id) {\r\n\t\t\treturn this.client.putJson(`${this.name}/${d.id}`, d);\r\n\t\t} else {\r\n\t\t\treturn this.client.postJson(this.name, d);\r\n\t\t}\r\n\t}\r\n\r\n}\r\n","export class Lazy<T> {\n\n\tprivate cache?: T;\n\n\tprivate supplier: () => T;\n\tconstructor(supplier: () => T) {\n\t\tthis.supplier = supplier;\n\t}\n\n\tget(): T {\n\t\tif (this.cache === undefined) {\n\t\t\tthis.cache = this.supplier();\n\t\t}\n\t\treturn this.cache;\n\t}\n\n\treset() {\n\t\tthis.cache = undefined;\n\t}\n\n\thasCache() {\n\t\treturn (this.cache !== undefined);\n\t}\n}\n","import {EntityClient} from \"./EntityClient\";\r\nimport {EntityBase} from \"../type/Entity\";\r\nimport { LazyAsync } from \"../cache\";\r\nimport { RestClient } from \"./RestClient\";\r\nimport {HashCacheStats} from \"../type\";\r\n\r\nexport class LookupClient<T extends EntityBase> extends EntityClient<T> {\r\n\r\n\tprotected cache: LazyAsync<Array<T>>;\r\n\r\n\tconstructor(client: RestClient, name: string) {\r\n\t\tsuper(client, name);\r\n\t\tthis.cache = new LazyAsync<Array<T>>(() => this.loadAllInternal());\r\n\t}\r\n\r\n\tprivate loadAllInternal(): Promise<Array<T>> {\r\n\t\treturn this.client.getJson(`${this.name}/all`);\r\n\t}\r\n\r\n\tloadAll(): Promise<Array<T>> {\r\n\t\treturn this.cache.get();\r\n\t}\r\n\r\n\tloadSingle(id: number): Promise<T> {\r\n\t\t// @ts-ignore\r\n\t\treturn this.loadAll().then(\r\n\t\t\t(all: Array<T>) => {\r\n\t\t\t\tconst d = all.find((l) => l.id === id);\r\n\t\t\t\tif (id === undefined) throw new Error(`${this.name} id ${id} not found!`);\r\n\t\t\t\treturn d;\r\n\t\t\t}\r\n\t\t);\r\n\t}\r\n\r\n\tsave(d: T): Promise<T> {\r\n\t\treturn super.save(d)\r\n\t\t\t.then((s) => {\r\n\t\t\t\tthis.cache.reset();\r\n\t\t\t\treturn s;\r\n\t\t\t});\r\n\t}\r\n\r\n\tdelete(id: number): Promise<any> {\r\n\t\treturn super.delete(id).then(() => this.cache.reset());\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.cache.reset();\r\n\t}\r\n\r\n\tgetStats(): HashCacheStats {\r\n\t\tconst size = this.cache.getCache()?.length;\r\n\t\treturn {\r\n\t\t\tcachedItems: size || 0,\r\n\t\t\tcapacity: size || 0\r\n\t\t}\r\n\t}\r\n}\r\n","import { OAuthTokenManager } from \"./OAuthTokenManager\";\nimport { RestClient } from \"../client\";\nimport { LazyAsync } from \"../cache\";\nimport { OAuthRefreshTokenProvider } from \"./tokenprovider/OAuthRefreshTokenProvider\";\nimport { RefreshTokenProviderDefault } from \"./tokenprovider/RefreshTokenProviderDefault\";\nimport {IdTokenPayload, RefreshTokenPayload} from \"./Types\";\n\nexport type ServerOAuthInfoPayload = {\n debugMode?: boolean;\n targetAudience: string;\n oauthServerUrl: string;\n version: string;\n};\n\nexport class RestClientWithOAuth\n extends RestClient\n implements OAuthRefreshTokenProvider\n{\n private insecureClient: RestClient;\n\n private freshIdTokenProvider: OAuthRefreshTokenProvider;\n\n private tokenManager: LazyAsync<OAuthTokenManager>;\n\n private serverInfo: LazyAsync<ServerOAuthInfoPayload>;\n\n private defaultScope: string;\n\n constructor(\n url: string,\n freshIdTokenProvider?: OAuthRefreshTokenProvider,\n defaultScope: string = \"admin:*\",\n ) {\n super(url);\n\n this.freshIdTokenProvider =\n freshIdTokenProvider || new RefreshTokenProviderDefault(this);\n this.defaultScope = defaultScope;\n\n // rest client without OAuth headers\n this.insecureClient = new RestClient(url);\n\n this.serverInfo = new LazyAsync<ServerOAuthInfoPayload>(() =>\n this.getServerInfoInternal(),\n );\n this.tokenManager = new LazyAsync<OAuthTokenManager>(() =>\n this.getTokenManagerInternal(),\n );\n }\n\n getRefreshToken(): Promise<IdTokenPayload> {\n return this.getTokenManager().then((t) => t.getRefreshToken());\n }\n\n /**\n * Attempt to get ID token from token manager\n */\n initialize(): Promise<any> {\n return this.getRefreshToken();\n }\n\n logout(): Promise<any> {\n return this.reset().then(() => this.initialize());\n }\n\n reset(): Promise<any> {\n return this.getTokenManager().then((m) => m.reset());\n }\n\n /**\n * Override this if a different privilege is needed for different endpoints\n * @param url\n */\n getScope(url: string): string {\n return this.defaultScope;\n }\n\n private getServerInfoInternal(): Promise<ServerOAuthInfoPayload> {\n return this.insecureClient.getJson(\"status/oauth/info\");\n }\n\n getServerInfo(): Promise<ServerOAuthInfoPayload> {\n return this.serverInfo.get();\n }\n\n protected getTokenManagerInternal(): Promise<OAuthTokenManager> {\n return this.getServerInfo().then(\n (info) =>\n new OAuthTokenManager(\n info.oauthServerUrl,\n info.targetAudience,\n this.freshIdTokenProvider,\n ),\n );\n }\n\n getTokenManager(): Promise<OAuthTokenManager> {\n return this.tokenManager.get();\n }\n\n login(login: string, password: string): Promise<RefreshTokenPayload> {\n return this.getTokenManager().then((m) => m.login(login, password));\n }\n\n setIdToken(token: IdTokenPayload): Promise<any> {\n return this.getTokenManager().then((m) => m.setRefreshToken(token));\n }\n\n getHeaders(endpoint: string): Promise<Headers> {\n return this.getTokenManager()\n .then((tm) => tm.getAccessToken(this.getScope(endpoint)))\n .then((accessToken) =>\n super.getHeaders(endpoint).then((headers) => {\n headers.set(\"Authorization\", `Bearer ${accessToken}`);\n return headers;\n }),\n );\n }\n}\n","import {UserAlert, UserAlertType} from \"../type\";\r\nimport {EventManager, Func} from \"./EventManager\";\r\nimport {DateUtil} from \"../util\";\r\n\r\nexport class UserAlerts {\r\n\r\n\tprivate maxAlerts: number;\r\n\r\n\tpublic maxVisibilityMs: number;\r\n\r\n\tprivate em: EventManager;\r\n\r\n\tpublic alerts: Array<UserAlert>;\r\n\r\n\tpublic visibleAlerts: Array<UserAlert>;\r\n\r\n\tconstructor(maxAlerts: number = 20, maxVisibilityMs: number = 7000) {\r\n\t\tthis.maxAlerts = maxAlerts;\r\n\t\tthis.maxVisibilityMs = maxVisibilityMs;\r\n\t\tthis.em = new EventManager();\r\n\t\tthis.alerts = [];\r\n\t\tthis.visibleAlerts = [];\r\n\t}\r\n\r\n\taddOnChangeHandler(h: Func) {\r\n\t\tthis.em.addEventListener('change', h);\r\n\t}\r\n\r\n\tremoveOnChangeHandler(h: Func) {\r\n\t\tthis.em.removeEventListener('change', h);\r\n\t}\r\n\r\n\ttriggerChange() {\r\n\t\tthis.em.triggerEvent('change');\r\n\t}\r\n\r\n\treset() {\r\n\t\tthis.alerts = [];\r\n\t\tthis.visibleAlerts = [];\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\thide(alert: UserAlert) {\r\n\t\tthis.visibleAlerts.splice(this.visibleAlerts.indexOf(alert), 1);\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\thideAll() {\r\n\t\tthis.visibleAlerts = [];\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\tupdateVisibility() {\r\n\t\tthis.visibleAlerts.forEach(\r\n\t\t\ta => {\r\n\t\t\t\tconst elapsedMs = DateUtil.getSinceDurationMs(a.time) || this.maxVisibilityMs;\r\n\t\t\t\tconst remainsMs = this.maxVisibilityMs - elapsedMs;\r\n\t\t\t\tif (remainsMs > 0) {\r\n\t\t\t\t\ta.remainsMs = remainsMs;\r\n\t\t\t\t} else {\r\n\t\t\t\t\ta.remainsMs = undefined;\r\n\t\t\t\t\tthis.hide(a);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t);\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\tremove(alert: UserAlert) {\r\n\t\tthis.alerts.splice(this.alerts.indexOf(alert), 1);\r\n\t\tthis.triggerChange();\r\n\t};\r\n\r\n\tadd(alert: UserAlert) {\r\n\t\tif (alert.remainsMs === undefined) {\r\n\t\t\talert.remainsMs = this.maxVisibilityMs;\r\n\t\t}\r\n\t\tthis.alerts.push(alert);\r\n\t\tthis.visibleAlerts.push(alert);\r\n\t\twhile (this.alerts.length > this.maxAlerts) {\r\n\t\t\tthis.alerts.shift();\r\n\t\t}\r\n\t\tthis.triggerChange();\r\n\t}\r\n\r\n\tcustom(type: UserAlertType, message: string) {\r\n\t\tthis.add({\r\n\t\t\ttime: new Date(),\r\n\t\t\ttype: type,\r\n\t\t\tmessage: message\r\n\t\t});\r\n\t}\r\n\r\n\terr(error: string | Error) {\r\n\t\tthis.custom(UserAlertType.error, typeof error === 'string' ? error : error.toString());\r\n\t}\r\n\r\n\twarn(message: string) {\r\n\t\tthis.custom(UserAlertType.warning, message);\r\n\t}\r\n\r\n\tinfo(message: string) {\r\n\t\tthis.custom(UserAlertType.info, message);\r\n\t}\r\n\r\n\tgetSummary(): Map<UserAlertType, number> {\r\n\t\tconst map= new Map<UserAlertType, number>;\r\n\t\tconst types = Object.values(UserAlertType);\r\n\t\ttypes.forEach((t, index) => {\r\n\t\t\tmap.set(t, 0);\r\n\t\t});\r\n\t\tfor (let i = 0; i < this.alerts.length; i++) {\r\n\t\t\tconst alert = this.alerts[i];\r\n\t\t\tconst n: number = map.get(alert.type) || 0;\r\n\t\t\tmap.set(alert.type, n + 1);\r\n\t\t}\r\n\t\treturn map;\r\n\t}\r\n\r\n}\r\n"],"names":["LazyAsync","constructor","supplier","this","get","undefined","cache","Promise","resolve","promise","then","v","catch","err","reject","reset","hasCache","getCache","CacheAsync","maxAgeMs","super","expires","Date","set","getTime","HashCacheAsync","maxSize","Map","obtainCache","k","c","delete","clear","getSize","size","getMaxSize","getStats","cachedItems","capacity","has","ObjectUtil","isEmpty","obj","notEmpty","clone","Error","getNestedValue","path","keys","split","current","key","HashUtil","crc32hex","str","data","TextEncoder","encode","table","Uint32Array","i","j","crc","length","toString","StringUtil","isString","s","message","isBlank","safeTrim","notBlank","substr","start","substring","replace","find","String","containsLineBreaks","safeContains","haystack","needle","caseSensitive","toLowerCase","includes","trimLeadingSlashes","trimTrailingSlashes","trimSlashes","safeTruncate","len","ellipsis","trim","safeLowercase","safeUppercase","toUpperCase","capitalizeFirstLetter","charAt","toBigInt","BigInt","getNonEmpty","args","a","getNonBlank","emptyToNull","blankToNull","randomString","Math","random","ArrayUtil","arr","remove","element","filter","e","extract","end","slice","extractStart","AsyncUtil","sleep","ms","r","setTimeout","FIRST_PAGE","page","PagingUtil","sortingFieldToString","parts","push","name","desc","nullsLast","join","sortingFieldFromString","sortingRequestToString","map","sortingRequestFromString","pagingRequestToQueryParams","pr","result","search","sorting","pagingRequestToString","pagingRequestFromString","Number","NumberUtil","n","isNaN","parseNumber","round","d","pow","portionToPercent","p","DateUtil","formatNumber","digits","padStart","parseDate","formatDateForHumans","showTime","year","getFullYear","month","getMonth","day","getDate","getHours","getMinutes","getSeconds","formatDateTimeForHumans","formatDateForInput","formatDateTimeForInput","getDurationMs","d1","d2","getSinceDurationMs","formatDuration","secs","floor","mins","hrs","days","items","JsonUtil","dateParser","value","reISO","exec","parseWithDates","json","JSON","parse","UrlUtil","deleteParamFromUrl","url","paramName","urlObj","URL","searchParams","extractParamFromUrl","URLSearchParams","paramExistsInUrl","extractHostFromUrl","host","extractDomainFromUrl","RestClient","baseUrl","baseHostUrl","endsWith","startsWith","window","location","protocol","paramsToQueryString","params","original","cleaned","forEach","getHeaders","endpoint","headers","Headers","getBaseUrl","getUrl","Object","getRequestOptions","method","body","FormData","stringify","processRequest","requestOptions","fetch","response","ok","options","cause","status","error","statusText","text","t","processRequestJson","getJson","o","postJson","postForm","postFormJson","putJson","del","post","put","EntityClient","client","loadSingle","id","loadPage","save","EventManager","handlers","addEventListener","event","handler","removeEventListener","splice","indexOf","triggerEvent","arg","h","UserAlertType","PERMISSION_LEVELS","OAuthUtil","isValidToken","token","isTokenExpired","isTokenReadyForRefresh","issuedAt","getScopeString","privilege","level","extractPrivilege","scope","isPermissionLevel","extractPermissionLevel","getLevel","hasPermission","ownedScope","requiredScopeOrPrivilege","minLevel","ownedLevel","ownedPrivilege","ownedParent","OAuthRestClient","oauthUrl","jwks","verifyRefreshToken","refreshToken","verifyAccessToken","accessToken","verifyIdToken","idToken","requestRefreshTokenFromLogin","request","renewRefreshToken","requestAccessToken","OAuthTokenManager","oAuthServerBaseUrl","targetAudience","initialRefreshTokenProvider","audience","oAuthServer","accessTokens","hasValidRefreshToken","hasValidAccessToken","getRefreshTokenInternal","getRefreshToken","setRefreshToken","console","log","getRefreshTokenRaw","login","password","storeAccessToken","findStoredAccessToken","getAccessTokenInternal","act","scopes","getAccessToken","existing","RedirectionProvider","redirectTo","redirecting","document","href","isRedirecting","redirectingTo","RefreshTokenProviderLogin","tokenQueryName","redirectToLogin","getServerInfo","si","thisUrl","oauthServerUrl","RefreshTokenProviderUrl","getRefreshTokenFromUrl","raw","getTokenManager","m","RefreshTokenProviderStorage","storageKey","saveRefreshTokenToLocalStorage","localStorage","setItem","removeItem","getRefreshTokenFromLocalStorage","getItem","RefreshTokenProviderDefault","tokenStorageKey","tokenUrlName","storage","Vector2","x","y","distanceTo","sqrt","equalsTo","inSize","currentSize","ratio","add","multiply","subtract","sub","toArray","fromArray","getAngleToYAxis","b","diff","down","sinX","angle","asin","PI","getNeighborPositions","includeCenter","neighbors","maxX","maxY","getClosest","positions","closest","distance","max","decimals","MemoryDictionary","translate","def","tags","cands","every","CzechBasicDictionary","CzechBasicData","EnglishBasicDictionary","EnglishBasicData","DictionaryWithFallback","primary","fallback","pt","Localization","language","dictionaries","setLanguage","addDictionary","dictionary","hasDictionary","getLanguage","getLanguages","Array","from","navigator","formatByteSize","l","toFixed","throwWhenCancelled","isCancelled","cancel","loadSingleStub","saveStub","loadAllInternal","loadAll","all","freshIdTokenProvider","defaultScope","insecureClient","serverInfo","getServerInfoInternal","tokenManager","getTokenManagerInternal","initialize","logout","getScope","info","setIdToken","tm","maxAlerts","maxVisibilityMs","em","alerts","visibleAlerts","addOnChangeHandler","removeOnChangeHandler","triggerChange","hide","alert","hideAll","updateVisibility","elapsedMs","time","remainsMs","shift","custom","type","warn","warning","getSummary","values","index"],"mappings":"mBAAaA,EAQZ,WAAAC,CAAYC,GACXC,KAAKD,SAAWA,CAChB,CAED,GAAAE,GACC,YAAmBC,IAAfF,KAAKG,MACDC,QAAQC,QAAQL,KAAKG,aAGRD,IAAjBF,KAAKM,UACRN,KAAKM,QAAUN,KAAKD,WAClBQ,MAAMC,IACNR,KAAKG,MAAQK,EACbR,KAAKM,aAAUJ,EACRE,QAAQC,QAAQG,MACrBC,OAAOC,IACTV,KAAKM,aAAUJ,EACRE,QAAQO,OAAOD,OAIlBV,KAAKM,QACZ,CAED,KAAAM,GACCZ,KAAKG,WAAQD,CACb,CAED,QAAAW,GACC,YAAuBX,IAAfF,KAAKG,KACb,CAED,QAAAW,GACC,OAAOd,KAAKG,KACZ,ECxCI,MAAOY,UAAsBlB,EAMlC,WAAAC,CAAYC,EAA4BiB,GACvCC,MAAMlB,GACNC,KAAKgB,SAAWA,CAChB,CAED,GAAAf,GAIC,OAHID,KAAKkB,SAAWlB,KAAKkB,QAAU,IAAIC,MACtCnB,KAAKY,QAECK,MAAMhB,KACb,CAED,GAAAmB,CAAIZ,EAAMU,GACTlB,KAAKG,MAAQK,EACbR,KAAKkB,QAAUA,EACXlB,KAAKgB,eAA6Bd,IAAjBF,KAAKkB,UACzBlB,KAAKkB,QAAU,IAAIC,MAAK,IAAIA,MAAOE,UAAYrB,KAAKgB,UAErD,QCvBWM,EAQZ,WAAAxB,CAAYC,EAAgCwB,GANpCvB,KAAKG,MAAG,IAAIqB,IAIZxB,KAAOuB,QAAW,IAGzBvB,KAAKD,SAAWA,EACZwB,IAASvB,KAAKuB,QAAUA,EAC5B,CAES,WAAAE,CAAYC,GACrB,IAAIC,EAAI3B,KAAKG,MAAMF,IAAIyB,GAKvB,OAJKC,IACJA,EAAI,IAAIZ,GAAW,IAAMf,KAAKD,SAAS2B,KACvC1B,KAAKG,MAAMiB,IAAIM,EAAGC,IAEZA,CACP,CAED,GAAA1B,CAAIyB,GACH,OAAO1B,KAAKyB,YAAYC,GAAGzB,KAC3B,CAED,GAAAmB,CAAIM,EAAMlB,EAAMU,GACflB,KAAKyB,YAAYC,GAAGN,IAAIZ,EAAGU,EAC3B,CAED,KAAAN,CAAMc,GACAA,EAGJ1B,KAAKG,MAAMyB,OAAOF,GAFlB1B,KAAKG,MAAM0B,OAIZ,CAED,OAAAC,GACC,OAAO9B,KAAKG,MAAM4B,IAClB,CAED,UAAAC,GACC,OAAOhC,KAAKuB,OACZ,CAED,QAAAU,GACC,MAAO,CACNC,YAAalC,KAAK8B,UAClBK,SAAUnC,KAAKgC,aAEhB,CAED,QAAAnB,CAASa,GACR,OAAO1B,KAAKG,MAAMiC,IAAIV,EACtB,QC1DWW,EAEZ,cAAOC,CAAQC,GACd,OAAOA,OACP,CAED,eAAOC,CAASD,GACf,OAAQF,EAAWC,QAAQC,EAC3B,CAED,YAAOE,CAASF,GACf,GAAY,OAARA,EACH,MAAM,IAAIG,MAAM,0BAEjB,GAAmB,iBAARH,EACV,MAAM,IAAIG,MAAM,oCAEjB,MAAO,IAAIH,EACX,CAED,qBAAOI,CAAeJ,EAAUK,GAC/B,IAAKL,GAAe,KAARA,EAAY,MAAO,GAE/B,MAAMM,EAAOD,EAAKE,MAAM,KAExB,IAAIC,EAAUR,EACd,IAAK,MAAMS,KAAOH,EAAM,CACvB,IAAIE,GAA8B,iBAAZA,KAAwBC,KAAOD,GAGpD,MAAO,GAFPA,EAAUA,EAAQC,EAInB,CAED,OAAOD,CACP,QCnCWE,EAEZ,eAAOC,CAASC,GAEf,MACMC,GADU,IAAIC,aACCC,OAAOH,GAGtBI,EAAQ,IAAIC,YAAY,KAC9B,IAAK,IAAIC,EAAI,EAAGA,EAAI,IAAKA,IAAK,CAC7B,IAAI9B,EAAI8B,EACR,IAAK,IAAIC,EAAI,EAAGA,EAAI,EAAGA,IACtB/B,EAAS,EAAJA,EAAU,WAAcA,IAAM,EAAOA,IAAM,EAEjD4B,EAAME,GAAK9B,IAAM,CACjB,CAED,IAAIgC,GAAM,EACV,IAAK,IAAIF,EAAI,EAAGA,EAAIL,EAAKQ,OAAQH,IAChCE,EAAOA,IAAQ,EAAKJ,EAAwB,KAAjBI,EAAMP,EAAKK,KAIvC,OAFAE,GAAOA,IAAc,EAEdA,EAAIE,SAAS,GACpB,QCrBWC,EACZ,eAAOC,CAASC,GACf,MAAoB,iBAANA,CACd,CAED,eAAOH,CAASG,GACf,OAAIF,EAAWC,SAASC,GAAWA,EAC/BF,EAAWC,SAASC,EAAEC,SAAiBD,EAAEC,QACtCD,GAAGH,cAAgB,EAC1B,CAED,cAAOvB,CAAQa,GACd,QAAId,EAAWC,QAAQa,IACD,IAAfA,EAAIS,MACX,CAED,eAAOpB,CAASW,GACf,OAAQW,EAAWxB,QAAQa,EAC3B,CAED,cAAOe,CAAQf,GACd,OAAOW,EAAWxB,QAAQwB,EAAWK,SAAShB,GAC9C,CAED,eAAOiB,CAASjB,GACf,OAAQW,EAAWI,QAAQf,EAC3B,CAED,aAAOkB,CACNlB,EACAmB,EACAV,GAEA,OAAI5D,KAAKsC,QAAQa,GAAa,GAGvBA,EAAIoB,UAAUD,EAAOV,EAC5B,CAED,cAAOY,CACNrB,EACAsB,EACAD,GAEA,OAAIxE,KAAKsC,QAAQa,IAAQnD,KAAKsC,QAAQmC,GAAc,GAC7CtB,EAAIqB,QAAQC,EAAMC,OAAOF,GAChC,CAED,yBAAOG,CAAmBxB,GACzB,OAAOW,EAAWc,aAAazB,EAAK,KACpC,CAED,mBAAOyB,CAAaC,EAAqCC,EAAmCC,GAAyB,GACpH,OAAIjB,EAAWI,QAAQW,KAAaf,EAAWI,QAAQY,KACnDC,EAAsBjB,EAAWc,aAAaC,EAASG,cAAeF,EAAOE,eAAe,GACzFH,EAASI,SAASH,GACzB,CAED,yBAAOI,CAAmB/B,GACzB,OAAInD,KAAKsC,QAAQa,GAAa,GACvBW,EAAWD,SAASV,GAAKqB,QAAQ,OAAQ,GAChD,CAED,0BAAOW,CAAoBhC,GAC1B,OAAInD,KAAKsC,QAAQa,GAAa,GACvBW,EAAWD,SAASV,GAAKqB,QAAQ,OAAQ,GAChD,CAED,kBAAOY,CAAYjC,GAClB,OAAInD,KAAKsC,QAAQa,GAAa,GACvBW,EAAWD,SAASV,GAAKqB,QAAQ,WAAY,GACpD,CAED,mBAAOa,CACNlC,EACAmC,EACAC,EAAmB,IAEnB,OAAIzB,EAAWxB,QAAQa,KAASA,EAAY,IAC5CA,EAAMW,EAAWD,SAASV,IAClBS,QAAU0B,EAAYZ,OAAOvB,GAC9BA,EAAIoB,UAAU,EAAGe,EAAMC,EAAS3B,QAAU2B,CACjD,CAED,eAAOA,CACNpC,EACAmC,EACAC,EAAmB,OAEnB,OAAOzB,EAAWuB,aAAalC,EAAKmC,EAAKC,EACzC,CAED,eAAOpB,CAAShB,GACf,OAAIW,EAAWxB,QAAQa,GAAa,GAC7BW,EAAWD,SAASV,GAAKqC,MAChC,CAED,oBAAOC,CAActC,GACpB,OAAIW,EAAWxB,QAAQa,KAASA,EAAY,GACrCW,EAAWD,SAASV,GAAK6B,aAChC,CAED,oBAAOU,CAAcvC,GACpB,OAAIW,EAAWxB,QAAQa,KAASA,EAAY,GACrCW,EAAWD,SAASV,GAAKwC,aAChC,CAED,4BAAOC,CAAsBzC,GAC5B,OAAIW,EAAWI,QAAQf,GAAa,GAEnCW,EAAW4B,cAAcvC,EAAI0C,OAAO,IACpC/B,EAAW2B,cAAc3B,EAAWO,OAAOlB,EAAK,GAEjD,CAED,eAAO2C,CAAS3C,GACf,OAAInD,KAAKsC,QAAQa,GAAa,KAGvB4C,OAAO5C,EACd,CAED,kBAAO6C,IAAeC,GACrB,OAAOA,EAAKxB,MAAMyB,GAAMpC,EAAWtB,SAAS0D,MAAO,EACnD,CAED,kBAAOC,IAAeF,GACrB,OAAOA,EAAKxB,MAAMyB,GAAMpC,EAAWM,SAAS8B,MAAO,EACnD,CAED,kBAAOE,CAAYjD,GAClB,OAAOW,EAAWxB,QAAQa,GAAO,KAAOuB,OAAOvB,EAC/C,CAED,kBAAOkD,CAAYlD,GAClB,OAAOW,EAAWI,QAAQf,GAAO,KAAOuB,OAAOvB,EAC/C,CAED,mBAAOmD,GACN,OAAOrD,EAASC,SAAS/B,OAASoF,KAAKC,SACvC,QC7IWC,EAEZ,cAAOnE,CAAQoE,GAEd,OAAOrE,EAAWC,QAAQoE,IAAuB,IAAfA,EAAI9C,MACtC,CAED,eAAOpB,CAASkE,GACf,OAAQD,EAAUnE,QAAQoE,EAC1B,CAED,aAAOC,CAAOD,EAAyBE,GACtC,OAAIH,EAAUnE,QAAQoE,GAAa,GAE5BA,GAAKG,QAAOC,GAAKA,IAAMF,GAC9B,CAED,cAAOG,CAAQL,EAAyBpC,EAAgB,EAAGV,GAC1D,IAAM8C,GAAQA,EAAI9C,QAAUU,EAAO,MAAO,GAC1C,MAAM0C,OAAiB9G,IAAX0D,OAAuB1D,EAAYoE,EAAQV,EACvD,OAAO8C,EAAIO,MAAM3C,EAAO0C,EACxB,CAED,mBAAOE,CAAaR,EAAoC9C,GACvD,OAAO6C,EAAUM,QAAQL,EAAK,EAAG9C,EACjC,QC3BWuD,GACLA,EAAKC,MAAIC,GAAe,IAAIjH,SAASkH,GAAMC,WAAWD,EAAGD,KCE1D,MAAMG,EAA4B,CAACC,KAAM,EAAG1F,KAAM,UAE5C2F,EAEZ,2BAAOC,CAAqB3D,GAC3B,IAAKA,EAAG,MAAO,GACf,MAAM4D,EAAQ,GAId,OAHAA,EAAMC,KAAK7D,EAAE8D,MACbF,EAAMC,KAAK7D,EAAE+D,KAAO,OAAS,IAC7BH,EAAMC,KAAK7D,EAAEgE,UAAY,KAAO,IACzBJ,EAAMK,KAAK,IAClB,CAED,6BAAOC,CAAuBlE,GAC7B,MAAM0C,EAAM1C,EAAElB,MAAM,KACpB,MAAO,CACNgF,KAAMpB,EAAI,GACVqB,KAAMrB,EAAI9C,OAAS,GAA0C,SAArCE,EAAW2B,cAAciB,EAAI,IACrDsB,UAAWtB,EAAI9C,OAAS,GAA0C,OAArCE,EAAW2B,cAAciB,EAAI,IAE3D,CAED,6BAAOyB,CAAuBnE,GAC7B,OAAOA,EAAEoE,KAAKpE,GAAoB0D,EAAWC,qBAAqB3D,KAAIiE,KAAK,IAC3E,CAED,+BAAOI,CAAyBrE,GAC/B,IAAKA,EAAG,MAAO,GAEf,OADYA,EAAElB,MAAM,KACTsF,KAAKpE,GAAM0D,EAAWQ,uBAAuBlE,IACxD,CAED,iCAAOsE,CAA2BC,GACjC,IAAKA,EAAI,OACT,MAAMC,EAAc,CACnBf,KAAMc,EAAGd,KACT1F,KAAMwG,EAAGxG,MAQV,OANIwG,EAAGE,SACND,EAAOC,OAASF,EAAGE,QAEhBF,EAAGG,UACNF,EAAOE,QAAUhB,EAAWS,uBAAuBI,EAAGG,UAEhDF,CACP,CAED,4BAAOG,CAAsBJ,GAC5B,IAAKA,EAAI,MAAO,GAChB,MAAM7B,EAAM,GAKZ,OAJAA,EAAImB,KAAKnD,OAAO6D,EAAGd,OACnBf,EAAImB,KAAKnD,OAAO6D,EAAGxG,OACnB2E,EAAImB,KAAK/D,EAAWK,SAASoE,EAAGE,SAChC/B,EAAImB,KAAKU,EAAGG,QAAUhB,EAAWS,uBAAuBI,EAAGG,SAAW,IAC/DhC,EAAIuB,KAAK,IAChB,CAED,8BAAOW,CAAwBL,GAC9B,IAAKA,GAAMzE,EAAWxB,QAAQiG,GAAK,MAAO,IAAIf,GAC9C,MAAMd,EAAM6B,EAAGzF,MAAM,KACrB,OAAI4D,EAAI9C,OAAS,EAAU,IAAI4D,GACxB,CACNC,KAAMoB,OAAOnC,EAAI,IACjB3E,KAAM8G,OAAOnC,EAAI,IACjB+B,OAAQ/D,OAAOgC,EAAI,IACnBgC,QAAS5E,EAAWxB,QAAQoE,EAAI,SAAMxG,EAAYwH,EAAWW,yBAAyB3B,EAAI,IAE3F,QCtEWoC,EAEZ,cAAOxG,CAAQyG,GACd,OAAOA,SAAiCF,OAAOG,MAAMD,EACrD,CAED,eAAOvG,CAASuG,GACf,OAAQD,EAAWxG,QAAQyG,EAC3B,CAED,kBAAOE,CAAY9F,GAClB,IAAKA,EAAK,OAAO,KACjB,MAAM4F,EAAIF,OAAO1F,GACjB,OAAO0F,OAAOG,MAAMD,GAAK,KAAOA,CAChC,CAED,YAAOG,CAAMH,EAAWI,GAClBA,IAAGA,EAAI,GACZ,MAAMxH,EAAI4E,KAAK6C,IAAI,GAAID,GACvB,OAAO5C,KAAK2C,MAAOH,EAAIpH,GAAKA,CAC5B,CAED,uBAAO0H,CAAiBC,EAAWH,GAClC,GAAIG,QAA+B,MAAO,GAE1C,MAAO,GADGR,EAAWI,MAAU,IAAJI,EAASH,KAEpC,QCvBWI,EAEZ,mBAAOC,CAAaT,EAAWU,EAAS,GAEvC,OADU/E,OAAOqE,GACRW,SAASD,EAAQ,IAC1B,CAED,gBAAOE,CAAUR,GAChB,GAAKA,EACL,MAAiB,iBAANA,EACH,IAAIhI,KAAKgI,GAEVA,CACP,CAED,0BAAOS,CAAoBT,EAAqCU,GAAoB,GAEnF,KADAV,EAAII,EAASI,UAAUR,IACf,MAAO,GAEf,MAAMW,EAAOX,EAAEY,cACTC,EAAQT,EAASC,aAAaL,EAAEc,WAAa,GAC7CC,EAAMX,EAASC,aAAaL,EAAEgB,WAEpC,IAAKN,EACJ,MAAO,GAAGC,KAAQE,KAASE,IAM5B,MAAO,GAAGJ,KAAQE,KAASE,KAHbX,EAASC,aAAaL,EAAEiB,eACtBb,EAASC,aAAaL,EAAEkB,iBACxBd,EAASC,aAAaL,EAAEmB,eAExC,CAED,8BAAOC,CAAwBpB,GAC9B,OAAOI,EAASK,oBAAoBT,GAAG,EACvC,CAED,yBAAOqB,CAAmBrB,EAAQU,GAAoB,GAErD,KADAV,EAAII,EAASI,UAAUR,IACf,MAAO,GACf,MAAMW,EAAOX,EAAEY,cACTC,EAAQT,EAASC,aAAaL,EAAEc,WAAa,GAC7CC,EAAMX,EAASC,aAAaL,EAAEgB,WAEpC,IAAKN,EACJ,MAAO,GAAGC,KAAQE,KAASE,IAM5B,MAAO,GAAGJ,KAAQE,KAASE,KAHbX,EAASC,aAAaL,EAAEiB,eACtBb,EAASC,aAAaL,EAAEkB,iBACxBd,EAASC,aAAaL,EAAEmB,eAExC,CAED,6BAAOG,CAAuBtB,GAC7B,OAAOI,EAASiB,mBAAmBrB,GAAG,EACtC,CAED,oBAAOuB,CAAcC,EAA2BC,GAG/C,GAFAD,EAAKpB,EAASI,UAAUgB,GACxBC,EAAKrB,EAASI,UAAUiB,GACpBvI,EAAWC,QAAQqI,IAAOtI,EAAWC,QAAQsI,GAAK,OAAO,KAC7D,IAEC,OAAOA,EAAGvJ,UAAYsJ,EAAGtJ,SACzB,CAAC,MAAOyF,GACR,OAAO,IACP,CACD,CAED,yBAAO+D,CAAmBF,GACzB,OAAOpB,EAASmB,cAAcC,EAAI,IAAIxJ,KACtC,CAED,qBAAO2J,CAAezD,GACrB,IAAKA,EACJ,MAAO,GAGR,IAAI0D,EAAOxE,KAAKyE,MAAM3D,EAAK,KAC3BA,GAAa,IAAP0D,EACN,IAAIE,EAAO1E,KAAKyE,MAAMD,EAAO,IAC7BA,GAAe,GAAPE,EACR,IAAIC,EAAM3E,KAAKyE,MAAMC,EAAO,IAC5BA,GAAc,GAANC,EACR,IAAIC,EAAO5E,KAAKyE,MAAME,EAAM,IAC5BA,GAAc,GAAPC,EAEP,MAAMC,EAAQ,GAOd,OANID,EAAO,GAAGC,EAAMvD,KAAK,GAAGsD,MACxBD,EAAM,GAAGE,EAAMvD,KAAK,GAAGqD,MACvBD,EAAO,GAAGG,EAAMvD,KAAK,GAAGoD,MACxBF,EAAO,GAAc,IAATI,GAAsB,IAARD,GAAWE,EAAMvD,KAAK,GAAGkD,MACnD1D,EAAK,GAAc,IAAT8D,GAAsB,IAARD,GAAsB,IAATD,GAAYG,EAAMvD,KAAK,GAAGiB,EAAWI,MAAM7B,EAAI,QAEjF+D,EAAMnD,KAAK,IAClB,QCjGWoD,EAIZ,iBAAOC,CAAWtI,EAAauI,GAC9B,MAAqB,iBAAVA,GAAsBF,EAASG,MAAMC,KAAKF,GAAe,IAAIpK,KAAKoK,GACtEA,CACP,CAED,qBAAOG,CAAeC,GACrB,IAAI7H,EAAWI,QAAQyH,GACvB,OAAOC,KAAKC,MAAM/H,EAAWkC,YAAY2F,GAAON,EAASC,WACzD,CAED,YAAOO,CAAMF,GACZ,OAAON,EAASK,eAAeC,EAC/B,EAdMN,EAAKG,MAAG,yFCFHM,EAEZ,yBAAOC,CAAmBC,EAAaC,GACtC,MAAMC,EAAS,IAAIC,IAAIH,GAEvB,OADAE,EAAOE,aAAaxK,OAAOqK,GACpBnI,EAAWqB,oBAAoB+G,EAAOrI,WAC7C,CAED,0BAAOwI,CAAoBL,EAAalE,GAEvC,OADY,IAAIwE,gBAAgB,IAAIH,IAAIH,GAAKvD,QAClCxI,IAAI6H,EACf,CAED,uBAAOyE,CAAiBP,EAAalE,GACpC,OAAOhE,EAAWM,SAAS0H,EAAQO,oBAAoBL,EAAKlE,GAC5D,CAED,yBAAO0E,CAAmBR,GACzB,OAAIlI,EAAWI,QAAQ8H,GAAa,KAC7B,IAAIG,IAAIH,GAAKS,IACpB,CAED,2BAAOC,CAAqBV,GAC3B,MAAMS,EAAOX,EAAQU,mBAAmBR,GACxC,OAAIlI,EAAWI,QAAQuI,GAAc,KAC9BA,EAAK3J,MAAM,KAAKmE,UAAUgB,KAAK,IACtC,QCrBW0E,EAGX,WAAA7M,CAAY8M,GACN9I,EAAWI,QAAQ0I,GACrB5M,KAAK4M,QAAUD,EAAWE,eAGvBD,EAAQE,SAAS,OAAMF,GAAoB,KAChD5M,KAAK4M,QAAUA,EAAQG,WAAW,QAC9B,IAAIZ,IAAIS,GACR,IAAIT,IAAIS,EAASD,EAAWE,eACjC,CAED,kBAAOA,GACL,OAAO,IAAIV,IAAI,GAAGa,OAAOC,SAASC,aAAaF,OAAOC,SAASR,QAChE,CAED,iCAAOnE,CAA2BC,GAChC,OAAOb,EAAWY,2BAA2BC,EAC9C,CAED,0BAAO4E,CAAoBC,GACzB,IAAKA,EAAQ,MAAO,GACpB,MAAMC,EAAW,IAAIf,gBAAgBc,GAC/BE,EAAU,IAAIhB,gBACpBe,EAASE,SAAQ,CAAChC,EAAOvI,KACT,KAAVuI,QAA0BrL,IAAVqL,GAAiC,cAAVA,GACzC+B,EAAQlM,IAAI4B,EAAKuI,EAAM,IAE3B,MAAMpI,EAAMmK,EAAQzJ,WACpB,OAAOC,EAAWxB,QAAQa,GAAO,GAAK,IAAIA,GAC3C,CAKD,UAAAqK,CAAWC,GACT,MAAMC,EAAU,IAAIC,QAEpB,OADAD,EAAQtM,IAAI,eAAgB,oBACrBhB,QAAQC,QAAQqN,EACxB,CAED,UAAAE,GACE,OAAO5N,KAAK4M,OACb,CAED,MAAAiB,CAAOJ,EAAkBL,GACvB,MAAMpB,EAAM,IAAIG,IACdrI,EAAWoB,mBAAmBuI,GAC9BzN,KAAK4N,cASP,OAPIR,GACFU,OAAOjL,KAAKuK,GAAQG,SAASvK,IAC3B,MAAMuI,EAAQ6B,EAAOpK,GACP,KAAVuI,QAA0BrL,IAAVqL,GAAiC,cAAVA,GACzCS,EAAII,aAAahL,IAAI4B,EAAKuI,EAAM,IAG/BS,CACR,CAED,iBAAA+B,CACEN,EACAO,EAAiB,MACjB5K,EAAY,MAEZ,OAAOpD,KAAKwN,WAAWC,GAAUlN,MAAMmN,IAC9B,CACLM,OAAQA,EACRN,QAASA,EACTO,KACW,OAAT7K,EACI,KACCA,aAAgB8K,UAA4B,iBAAT9K,EAClCA,EACAwI,KAAKuC,UAAU/K,MAG5B,CAED,cAAAgL,CACEX,EACAL,EACAiB,GAEA,OAAOC,MAAMtO,KAAK6N,OAAOJ,EAAUL,GAASiB,GAAgB9N,MACzDgO,IACC,IAAKA,EAASC,GAAI,CAChB,MAAMC,EAAU,CAAEC,MAAOH,EAASI,QAClC,MAA6C,qBAAzCJ,EAASb,QAAQzN,IAAI,gBAChBsO,EAAS5C,OAAOpL,MACpBoL,IACC,GAAIA,EAAK1H,QAEP,MAAM,IAAIvB,MAAMiJ,EAAK1H,QAASwK,GAEhC,GAAI9C,EAAKiD,MAEP,MAAM,IAAIlM,MAAMiJ,EAAKiD,MAAOH,GAG9B,MAAM,IAAI/L,MAAM6L,EAASM,WAAYJ,EAAQ,IAE/C,KAEE,MAAM,IAAI/L,MAAM6L,EAASM,WAAYJ,EAAQ,IAI1CF,EAASO,OAAOvO,MACpBwO,IACC,MAAIjL,EAAWxB,QAAQyM,GAEf,IAAIrM,MAAM6L,EAASM,WAAYJ,GAG/B,IAAI/L,MAAMqM,EAAGN,EACpB,IAEH,KAEE,MAAM,IAAI/L,MAAM6L,EAASM,WAAYJ,EAAQ,GAIpD,CACD,OAAOF,CAAQ,GAGpB,CAED,kBAAAS,CACEvB,EACAL,EACAiB,GAEA,OAAOrO,KAAKoO,eAAeX,EAAUL,EAAQiB,GAAgB9N,MAC1DgO,GACQA,EAASO,OAAOvO,KAAK8K,EAASK,iBAG1C,CAED,OAAAuD,CAAQjD,EAAaoB,GACnB,OAAOpN,KAAK+N,kBAAkB/B,GAAKzL,MAAM2O,GACvClP,KAAKgP,mBAAmBhD,EAAKoB,EAAQ8B,IAExC,CAED,QAAAC,CACEnD,EACA5I,EAAsB,KACtBgK,GAEA,OAAOpN,KAAK+N,kBAAkB/B,EAAK,OAAQ5I,GAAM7C,MAAM2O,GACrDlP,KAAKgP,mBAAmBhD,EAAKoB,EAAQ8B,IAExC,CAED,QAAAE,CAASpD,EAAa5I,EAAgBgK,GACpC,OAAOpN,KAAK+N,kBAAkB/B,EAAK,OAAQ5I,GAAM7C,MAAM2O,IACrDA,EAAExB,QAAQ9L,OAAO,gBACV5B,KAAKoO,eAAepC,EAAKoB,EAAQ8B,KAE3C,CAED,YAAAG,CAAarD,EAAa5I,EAAgBgK,GACxC,OAAOpN,KAAK+N,kBAAkB/B,EAAK,OAAQ5I,GAAM7C,MAAM2O,IACrDA,EAAExB,QAAQ9L,OAAO,gBACV5B,KAAKgP,mBAAmBhD,EAAKoB,EAAQ8B,KAE/C,CAED,OAAAI,CAAQtD,EAAa5I,EAAsB,KAAMgK,GAC/C,OAAOpN,KAAK+N,kBAAkB/B,EAAK,MAAO5I,GAAM7C,MAAM2O,GACpDlP,KAAKgP,mBAAmBhD,EAAKoB,EAAQ8B,IAExC,CAED,GAAAjP,CAAIwN,EAAkBL,GACpB,OAAOpN,KAAK+N,kBAAkBN,GAAUlN,MAAM2O,GAC5ClP,KAAKoO,eAAeX,EAAUL,EAAQ8B,IAEzC,CAED,GAAAK,CAAIvD,EAAaoB,GACf,OAAOpN,KAAK+N,kBAAkB/B,EAAK,UAAUzL,MAAM2O,GACjDlP,KAAKoO,eAAepC,EAAKoB,EAAQ8B,IAEpC,CAED,IAAAM,CACExD,EACA5I,EAAY,KACZgK,GAEA,OAAOpN,KAAK+N,kBAAkB/B,EAAK,OAAQ5I,GAAM7C,MAAM2O,GACrDlP,KAAKoO,eAAepC,EAAKoB,EAAQ8B,IAEpC,CAED,GAAAO,CACEzD,EACA5I,EAAY,KACZgK,GAEA,OAAOpN,KAAK+N,kBAAkB/B,EAAK,MAAO5I,GAAM7C,MAAM2O,GACpDlP,KAAKoO,eAAepC,EAAKoB,EAAQ8B,IAEpC,QCrNUQ,EAMZ,WAAA5P,CAAY6P,EAAoB7H,GAC/B9H,KAAK2P,OAASA,EACd3P,KAAK8H,KAAOA,CACZ,CAED,UAAA8H,CAAWC,GACV,OAAO7P,KAAK2P,OAAOV,QAAQ,GAAGjP,KAAK8H,QAAQ+H,IAC3C,CAED,QAAAC,CAASvH,GACR,OAAOvI,KAAK2P,OAAOV,QAAQjP,KAAK8H,KAAM6E,EAAWrE,2BAA2BC,GAC5E,CAED,IAAAwH,CAAK5G,GACJ,OAAIA,EAAE0G,GACE7P,KAAK2P,OAAOL,QAAQ,GAAGtP,KAAK8H,QAAQqB,EAAE0G,KAAM1G,GAE5CnJ,KAAK2P,OAAOR,SAASnP,KAAK8H,KAAMqB,EAExC,CAED,OAAO0G,GACN,OAAO7P,KAAK2P,OAAOJ,IAAI,GAAGvP,KAAK8H,QAAQ+H,IACvC,QC7BWG,EAIZ,WAAAlQ,GACCE,KAAKiQ,SAAW,IAAIzO,GACpB,CAED,gBAAA0O,CAAiBC,EAAeC,GAC1BpQ,KAAKiQ,SAAS7N,IAAI+N,IAAQnQ,KAAKiQ,SAAS7O,IAAI+O,EAAO,IAExDnQ,KAAKiQ,SAAShQ,IAAIkQ,GAAOtI,KAAKuI,EAC9B,CAED,mBAAAC,CAAoBF,EAAeC,GAClC,MAAMH,EAAqCjQ,KAAKiQ,SAAShQ,IAAIkQ,GACzDF,GAAUA,EAASK,OAAOL,EAASM,QAAQH,GAAU,EACzD,CAED,YAAAI,CAAaL,EAAeM,GACtBzQ,KAAKiQ,SAAS7N,IAAI+N,IAEvBnQ,KAAKiQ,SAAShQ,IAAIkQ,GAAO5C,SAASmD,GAAYA,EAAED,IAChD,EC3BF,IAAYE,EAAAA,QAIXA,mBAAA,GAJWA,EAAAA,QAAaA,gBAAbA,sBAIX,CAAA,IAHA,KAAA,OACAA,EAAA,QAAA,UACAA,EAAA,MAAA,SCFY,MAAAC,EAAoB,CAAC,OAAQ,QAAS,eCEtCC,EACX,mBAAOC,CAAaC,GAClB,OACE1O,EAAWG,SAASuO,IACpBjN,EAAWM,SAAS2M,EAAMA,SACzBF,EAAUG,eAAeD,EAE7B,CAED,qBAAOC,CAAeD,GACpB,OAAIA,eACkB7Q,IAAlB6Q,EAAM7P,SAA2C,OAAlB6P,EAAM7P,SAClC6P,EAAM7P,QAAU,IAAIC,KAC5B,CAED,6BAAO8P,CACLF,GAEA,GAAIA,QAAuC,OAAO,EAClD,GAAIF,EAAUG,eAAeD,GAAQ,OAAO,EAC5C,QAAsB7Q,IAAlB6Q,EAAM7P,SAA2C,OAAlB6P,EAAM7P,QAAkB,OAAO,EAKlE,OAJe,IAAIC,MAChB4P,EAAM7P,QAAQG,UAAY0P,EAAMG,SAAS7P,WAAa,GAE7C,IAAIF,IAEjB,CAEM,qBAAOgQ,CAAeC,EAAmBC,GAC9C,MAAO,GAAGA,KAASD,GACpB,CAEM,uBAAOE,CAAiBC,GAC7B,MAAM7K,EAAM6K,EAAMzO,MAAM,KACxB,OAAI4D,EAAI9C,OAAS,EAAU,GACpB8C,EAAI,EACZ,CAEM,wBAAO8K,CAAkBjG,GAC9B,OAAQqF,EAAwC3L,SAASsG,EAC1D,CAEM,6BAAOkG,CAAuBF,GACnC,MAAM7K,EAAM6K,EAAMzO,MAAM,KACxB,GAAmB,IAAf4D,EAAI9C,OAAc,MAAM,IAAIlB,MAAM,eAAe6O,iBACrD,MAAMpO,EAAMuD,EAAI,GAChB,IAAKmK,EAAUW,kBAAkBrO,GAC/B,MAAM,IAAIT,MAAM,IAAIS,oCACtB,OAAOA,CACR,CAEM,eAAOuO,CAASL,GACrB,OAAQA,GACN,IAAK,QACH,OAAO,EACT,IAAK,QACH,OAAO,EACT,IAAK,OACH,OAAO,EACT,QACE,OAAO,EAEZ,CASM,oBAAOM,CACZC,EACAC,EACAC,GAEA,QAAiB5R,IAAb4R,EACF,IACEA,EAAWjB,EAAUY,uBAAuBI,GAC5CA,EAA2BhB,EAAUS,iBACnCO,EAEH,CAAC,MAAO/K,GACPgL,EAAW,OACZ,CAGH,MAAMC,EAAalB,EAAUY,uBAAuBG,GAEpD,GAAIf,EAAUa,SAASK,GAAclB,EAAUa,SAASI,GACtD,OAAO,EAET,MAAME,EAAiBnB,EAAUS,iBAAiBM,GAElD,GAAuB,MAAnBI,EAAwB,OAAO,EAEnC,GAAIA,IAAmBH,EAA0B,OAAO,EAExD,IAAKG,GAAgBlF,SAAS,MAAO,OAAO,EAE5C,MAAMmF,EAAcD,EAAexN,QAAQ,KAAM,IACjD,OAAOqN,GAA0B9E,WAAWkF,KAAgB,CAC7D,EC1FG,MAAOC,UAAwBvF,EACnC,WAAA7M,CAAYqS,GACVlR,MAAM,GAAG6C,EAAWsB,YAAY+M,eACjC,CAED,IAAAC,GACE,OAAOpS,KAAKiP,QAAQ,YACrB,CAED,kBAAAoD,CAAmBC,GACjB,OAAOtS,KAAKiP,QAAQ,yBAAyBqD,IAC9C,CAED,iBAAAC,CAAkBC,GAChB,OAAOxS,KAAKiP,QAAQ,wBAAwBuD,IAC7C,CAED,aAAAC,CAAcC,GACZ,OAAO1S,KAAKiP,QAAQ,oBAAoByD,IACzC,CAED,4BAAAC,CACEC,GAEA,OAAO5S,KAAKmP,SAAS,4BAA6ByD,EACnD,CAED,iBAAAC,CACED,GAEA,OAAO5S,KAAKmP,SAAS,uBAAwByD,EAC9C,CAED,kBAAAE,CACEF,GAEA,OAAO5S,KAAKmP,SAAS,mCAAoCyD,EAC1D,QCxCUG,EAWZ,WAAAjT,CACCkT,EACAC,EACAC,GAEAlT,KAAKkT,4BAA8BA,EACnClT,KAAKmT,SAAWF,EAChBjT,KAAKoT,YAAc,IAAIlB,EAAgBc,GACvChT,KAAKqT,aAAe,IAAI7R,GACxB,CAED,oBAAA8R,GACC,OAAOzC,EAAUC,aAAa9Q,KAAKsS,aACnC,CAED,mBAAAiB,CAAoBnC,GACnB,OAAOP,EAAUC,aAAa9Q,KAAKqT,aAAapT,IAAImR,GACpD,CAED,KAAAxQ,GAGC,OAFAZ,KAAKsS,kBAAepS,EACpBF,KAAKqT,aAAaxR,QACX7B,KAAKkT,4BAA4BtS,OACxC,CAKD,uBAAA4S,GACC,YAA0BtT,IAAtBF,KAAKsS,cAA8BtS,KAAKsT,uBACpClT,QAAQC,QAAQL,KAAKsS,cAEtBtS,KAAKkT,4BAA4BO,iBACxC,CAKD,eAAAA,GACC,OAAOzT,KAAKwT,0BAA0BjT,MACpCwO,GACK8B,EAAUC,aAAa/B,GAIxB8B,EAAUI,uBAAuBlC,GAC7B/O,KAAKoT,YACVP,kBAAkB,CAACP,aAAcvD,EAAEgC,QACnCxQ,MAAMwO,IACN/O,KAAK0T,gBAAgB3E,GACdA,MAGV/O,KAAK0T,gBAAgB3E,GACd3O,QAAQC,QAAQ0O,KAZtB4E,QAAQC,IAAI,wBAAyB7E,GAC9B3O,QAAQO,OAAO,qCAczB,CAED,kBAAAkT,GACC,OAAO7T,KAAKyT,kBAAkBlT,MAAMwO,GAAMA,EAAEgC,OAC5C,CAED,eAAA2C,CAAgB3C,GACf/Q,KAAKsS,aAAevB,CACpB,CAED,kBAAAsB,CAAmBtB,GAClB,OAAO/Q,KAAKoT,YAAYf,mBAAmBtB,EAC3C,CAED,KAAA+C,CAAMA,EAAeC,GAEpB,OADA/T,KAAKY,QACEZ,KAAKoT,YACVT,6BAA6B,CAC7BmB,MAAOA,EACPC,SAAUA,EACVd,eAAgBjT,KAAKmT,WAErB5S,MAAMwO,IACN/O,KAAK0T,gBAAgB3E,GACdA,IAET,CAEO,gBAAAiF,CAAiBzC,EAAeR,GACvC/Q,KAAKqT,aAAajS,IAAImQ,EAAOR,EAC7B,CAEO,qBAAAkD,CAAsB1C,GAC7B,MAAMF,EAAQR,EAAUY,uBAAuBF,GACzCH,EAAYP,EAAUS,iBAAiBC,GAC7C,IAAK,MAAOvN,EAAG+M,KAAU/Q,KAAKqT,aAC7B,GAAIxC,EAAUc,cAAc3N,EAAGoN,EAAWC,GAAQ,OAAON,CAG1D,CAEO,sBAAAmD,CAAuB3C,GAC9B,OAAOvR,KAAK6T,qBAAqBtT,MAC/B+R,GAAyBtS,KAAKoT,YAC7BN,mBACA,CACCR,aAAcA,EACdW,eAAgBjT,KAAKmT,SACrB5B,MAAOA,IAGRhR,MACC4T,GACKtD,EAAUC,aAAaqD,IAGxBA,EAAIC,QAAUD,EAAIC,OAAOxQ,OAAS,EACrCuQ,EAAIC,OAAO7G,SAASvJ,GAAMhE,KAAKgU,iBAAiBhQ,EAAGmQ,KAEnDnU,KAAKgU,iBAAiBzC,EAAO4C,GAEvBA,GAPC/T,QAAQO,OAAO,0CAW3B,CAED,cAAA0T,CAAe9C,GACd,MAAM+C,EAAWtU,KAAKiU,sBAAsB1C,GAC5C,YAAiBrR,IAAboU,GAA2BzD,EAAUC,aAAawD,IAGlDzD,EAAUI,uBAAuBqD,IACpCtU,KAAKkU,uBAAuB3C,GACtBnR,QAAQC,QAAQiU,EAASvD,QAJxB/Q,KAAKkU,uBAAuB3C,GAAOhR,MAAMwO,GAAMA,EAAEgC,OAKzD,QCzJWwD,EAIZ,UAAAC,CAAWxI,GAGV,OAFAhM,KAAKyU,YAAczI,EACnB0I,SAASzH,SAAS0H,KAAO3I,EAClB5L,QAAQO,OAAO,kBAAkBqL,IACxC,CAED,aAAA4I,GACC,OAAO9Q,EAAWM,SAASpE,KAAKyU,YAChC,CAED,aAAAI,GACC,OAAO/Q,EAAWkC,YAAYhG,KAAKyU,YACnC,ECZI,MAAOK,UAAkCP,EAM9C,WAAAzU,CAAY6P,EAA6BoF,GACxC9T,QACAjB,KAAK2P,OAASA,EACd3P,KAAK+U,eAAiBA,GAAkB,OACxC,CAED,eAAAC,GACC,OAAOhV,KAAK2P,OAAOsF,gBAAgB1U,MACjC2U,IACA,MAAMC,EAAUrJ,EAAQC,mBAAmB2I,SAASzH,SAASpJ,WAAY7D,KAAK+U,gBACxE9H,EAAW,GAAGiI,EAAGE,iCAAiCF,EAAGjC,+BAA+BkC,IAC1F,OAAOnV,KAAKwU,WAAWvH,EAAS,IAEhCxM,OAAOC,IACRiT,QAAQ/E,MAAM,8CAA+ClO,GACtDN,QAAQO,OAAOD,KAEvB,CAED,eAAA+S,GACO,OAAOzT,KAAKgV,iBACf,CAEJ,KAAApU,GACC,OAAOR,QAAQC,SACf,EC/BI,MAAOgV,UAAgCd,EAM5C,WAAAzU,CAAY6P,EAA6BoF,GACxC9T,QACAjB,KAAK2P,OAASA,EACd3P,KAAK+U,eAAiBA,GAAkB,OACxC,CAED,sBAAAO,GACC,OAAOxJ,EAAQO,oBAAoBqI,SAASzH,SAASpJ,WAAY7D,KAAK+U,eACtE,CAED,eAAAtB,GACC,MAAM8B,EAAMvV,KAAKsV,yBACjB,OAAY,OAARC,GAAgBzR,EAAWI,QAAQqR,GAAanV,QAAQO,OAAO,oBAC5DX,KAAK2P,OACV6F,kBACAjV,MAAKkV,GAAKA,EAAEpD,mBAAmBkD,IAC9B,CAEJ,KAAA3U,GACC,MAAM2U,EAAMvV,KAAKsV,yBACjB,GAAY,OAARC,GAAgBzR,EAAWI,QAAQqR,GAAM,OAAOnV,QAAQC,UAC5DsT,QAAQC,IAAI,gCACZ,MAAMuB,EAAUrJ,EAAQC,mBAAmB2I,SAASzH,SAASpJ,WAAY7D,KAAK+U,gBAC9E,OAAO/U,KAAKwU,WAAWW,EACvB,QC/BWO,EAIZ,WAAA5V,CAAY6V,GACX3V,KAAKgD,IAAM2S,GAAc,eACzB,CAED,8BAAAC,CAA+B7E,GAC9B,MAAMwE,EAAMxE,EAAQnF,KAAKuC,UAAU4C,GAAS,KAChC,OAARwE,EAIJM,aAAaC,QAAQ9V,KAAKgD,IAAKuS,GAH9BM,aAAaE,WAAW/V,KAAKgD,IAI9B,CAED,+BAAAgT,GACC,OAAO3K,EAASQ,MAAMgK,aAAaI,QAAQjW,KAAKgD,KAChD,CAED,eAAAyQ,GACO,MAAM1C,EAAQ/Q,KAAKgW,kCACzB,OAAIjF,GAASF,EAAUC,aAAaC,GAAe3Q,QAAQC,QAAQ0Q,GAC5D3Q,QAAQO,OAAO,mCACnB,CAEJ,KAAAC,GAEC,OADAZ,KAAK4V,+BAA+B,MAC7BxV,QAAQC,SACf,QC5BW6V,EAQZ,WAAApW,CAAY6P,EAA6BwG,EAA0BC,GAClEpW,KAAK8T,MAAQ,IAAIgB,EAA0BnF,EAAQyG,GACnDpW,KAAKgM,IAAM,IAAIqJ,EAAwB1F,EAAQyG,GAC/CpW,KAAKqW,QAAU,IAAIX,EAA4BS,EAC/C,CAED,eAAA1C,GACC,OAAOzT,KAAKgM,IACVyH,kBACAhT,OACCC,IACAiT,QAAQC,IAAI,yCAA0ClT,GAC/CV,KAAKqW,QACV5C,kBACAhT,OACCC,IACAiT,QAAQC,IAAI,kDAAmDlT,GACxDV,KAAK8T,MAAML,wBAKtBlT,MACCwO,IACA4E,QAAQC,IAAI,qCACZ5T,KAAKqW,QAAQT,+BAA+B7G,GAErC/O,KAAKgM,IAAIpL,QAAQL,MAAK,IAAMwO,MAGnC,CAEJ,KAAAnO,GACC,OAAOZ,KAAKqW,QAAQzV,QAAQL,MAAK,IAAMP,KAAKgM,IAAIpL,SAChD,QC/CW0V,EAIZ,WAAAxW,CAAYyW,EAAWC,GACtBxW,KAAKuW,EAAIA,EACTvW,KAAKwW,EAAIA,CACT,CAED,UAAAC,CAAWjW,GACV,OAAO+F,KAAKmQ,KAAKnQ,KAAK6C,IAAIpJ,KAAKuW,EAAI/V,EAAE+V,EAAG,GAAKhQ,KAAK6C,IAAIpJ,KAAKwW,EAAIhW,EAAEgW,EAAG,GACpE,CAED,QAAAG,CAASnW,GACR,QAAO,IAAMR,KAAKuW,IAAM/V,EAAE+V,GAAKvW,KAAKwW,IAAMhW,EAAEgW,EAC5C,CAED,IAAAzU,GACC,OAAO/B,KAAKyW,WAAW,IAAIH,EAAQ,EAAG,GACtC,CAED,MAAAM,CAAO7U,GACN,MAAM8U,EAAc7W,KAAK+B,OACzB,GAAoB,IAAhB8U,EAAmB,CACtB,MAAMC,EAAQ/U,EAAO8U,EACrB,OAAO,IAAIP,EAAQtW,KAAKuW,EAAIO,EAAO9W,KAAKwW,EAAIM,EAC5C,CACD,OAAO9W,IACP,CAED,KAAAkJ,GACC,OAAO,IAAIoN,EAAQ/P,KAAK2C,MAAMlJ,KAAKuW,GAAIhQ,KAAK2C,MAAMlJ,KAAKwW,GACvD,CAED,GAAAO,CAAIvW,GACH,OAAO,IAAI8V,EAAQtW,KAAKuW,EAAI/V,EAAE+V,EAAGvW,KAAKwW,EAAIhW,EAAEgW,EAC5C,CAED,QAAAQ,CAAShT,GACR,OAAO,IAAIsS,EAAQtW,KAAKuW,EAAIvS,EAAGhE,KAAKwW,EAAIxS,EACxC,CAED,QAAAiT,CAASzW,GACR,OAAO,IAAI8V,EAAQtW,KAAKuW,EAAI/V,EAAE+V,EAAGvW,KAAKwW,EAAIhW,EAAEgW,EAC5C,CAED,GAAAU,CAAI1W,GACH,OAAOR,KAAKiX,SAASzW,EACrB,CAED,OAAA2W,GACC,MAAO,CAACnX,KAAKuW,EAAGvW,KAAKwW,EACrB,CAED,gBAAOY,CAAU1Q,GAChB,GAAmB,iBAARA,GAAmC,IAAfA,EAAI9C,OAClC,OAAO,IAAI0S,EAAQ5P,EAAI,GAAIA,EAAI,GAEhC,CAED,KAAAjE,GACC,OAAO,IAAI6T,EAAQtW,KAAKuW,EAAGvW,KAAKwW,EAChC,CAOD,eAAAa,CAAgBC,GACf,MAAMC,EAAOD,EAAEL,SAASjX,MAClBwX,EAAOD,EAAKf,EAAI,EAChBiB,EAAOF,EAAKhB,EAAIgB,EAAKxV,OACrB2V,EAAQnR,KAAKoR,KAAKF,GAIxB,OAHeD,EACdjR,KAAKqR,GAAKF,EACVA,IACgB,CACjB,CAED,oBAAAG,CAAqB9V,EAAO,EAAG+V,GAAgB,GAC9C,MAAMC,EAAY,GACZC,EAAOhY,KAAKuW,EAAIxU,EACtB,IAAK,IAAIwU,EAAIvW,KAAKuW,EAAIxU,EAAMwU,GAAKyB,EAAMzB,IAAK,CAC3C,MAAM0B,EAAOjY,KAAKwW,EAAIzU,EACtB,IAAK,IAAIyU,EAAIxW,KAAKwW,EAAIzU,EAAMyU,GAAKyB,EAAMzB,IAAK,CAC3C,MAAMzN,EAAI,IAAIuN,EAAQC,EAAGC,IACrBsB,GAAkB9X,KAAK2W,SAAS5N,IACnCgP,EAAUlQ,KAAKkB,EAEhB,CACD,CACD,OAAOgP,CACP,CAED,UAAAG,CAAWC,GACV,IAAMA,GAAmC,IAArBA,EAAUvU,OAAc,OAAO,KACnD,GAAyB,IAArBuU,EAAUvU,OAAc,OAAOuU,EAAU,GAC7C,IAAIC,EAAUD,EAAU,GACpBE,EAAWrY,KAAKyW,WAAW2B,GAC/B,IAAK,IAAI3U,EAAI,EAAG6U,EAAMH,EAAUvU,OAAQH,EAAI6U,EAAK7U,IAAK,CACrD,MAAM0F,EAAInJ,KAAKyW,WAAW0B,EAAU1U,IAChC0F,EAAIkP,IACPD,EAAUD,EAAU1U,GACpB4U,EAAWlP,EAEZ,CACD,OAAOiP,CACP,CAED,QAAAvU,CAAS0U,EAAW,GACnB,MAAO,IAAIzP,EAAWI,MAAMlJ,KAAKuW,EAAGgC,MAAazP,EAAWI,MAAMlJ,KAAKwW,EAAG+B,KAC1E,slBC9FWC,EAIZ,WAAA1Y,CAAYsD,GACXpD,KAAKoD,KAAOA,CACZ,CAED,SAAAqV,CAAUzV,EAAasG,GACtB,MAAMhC,EAAItH,KAAKoD,KAAKJ,GACpB,QAAU9C,IAANoH,GAAgC,iBAANA,EAAgB,OAAOA,EACrD,MAAMoR,EAAMpR,EAAE7C,MACZjE,QAAkBN,IAAXM,EAAEmY,MAAwC,IAAlBnY,EAAEmY,KAAK/U,SAExC,SAAW1D,IAANoJ,QAA8BpJ,IAAXoJ,EAAEqP,MAAwC,IAAlBrP,EAAEqP,KAAK/U,cAAyB1D,IAARwY,EAAmB,OAAOA,EAAInN,MACtG,MAAMqN,EAAQtR,EAAET,QACdrG,QACeN,IAAXM,EAAEmY,MAAwC,IAAlBnY,EAAEmY,KAAK/U,SAC5B0F,GAAKA,EAAEqP,MAAQrP,EAAEqP,KAAKE,OAAO9J,GAAMvO,EAAEmY,MAAQnY,EAAEmY,KAAK1T,SAAS8J,QAGtE,OAAI6J,EAAMhV,OAAS,EAAUgV,EAAM,GAAGrN,MAC/BmN,EAAMA,EAAInN,WAAQrL,CACzB,EAII,MAAO4Y,UAA6BN,EACzC,WAAA1Y,GACCmB,MAAM8X,EACN,EAGI,MAAOC,UAA+BR,EAC3C,WAAA1Y,GACCmB,MAAMgY,EACN,QAGWC,EAMZ,WAAApZ,CAAYqZ,EAAqBC,GAChCpZ,KAAKmZ,QAAUA,EACfnZ,KAAKoZ,SAAWA,CAChB,CAED,SAAAX,CAAUzV,EAAasG,GACtB,MAAM+P,EAAKrZ,KAAKmZ,QAAQV,UAAUzV,EAAKsG,GACvC,YAAWpJ,IAAPmZ,EAAyBrZ,KAAKoZ,SAASX,UAAUzV,EAAKsG,GACnD+P,CACP,QCxEWC,EAMZ,WAAAxZ,CAAYyZ,GAFJvZ,KAAYwZ,aAAG,IAAIhY,IAG1BxB,KAAKyZ,YAAYF,EACjB,CAED,aAAAG,CAAcH,EAAkBI,GAC/B,MAAMrF,EAAWtU,KAAKwZ,aAAavZ,IAAIsZ,GACnCjF,EACHtU,KAAKwZ,aAAapY,IAAImY,EAAU,IAAIL,EAAuBS,EAAYrF,IAEvEtU,KAAKwZ,aAAapY,IAAImY,EAAUI,EAEjC,CAED,aAAAC,CAAcL,GACb,QAAKA,GACEvZ,KAAKwZ,aAAapX,IAAImX,EAC7B,CAED,WAAAM,GACC,OAAO7Z,KAAKuZ,QACZ,CAED,YAAAO,GACC,OAAOC,MAAMC,KAAKha,KAAKwZ,aAAa3W,OACpC,CAED,WAAA4W,CAAYF,GACXvZ,KAAKuZ,SAAWA,GAAYvZ,KAAK4Z,cAAcL,GAC5CA,EACAvZ,KAAK4Z,cAAcK,UAAUV,UAAYU,UAAUV,cAAWrZ,CACjE,CAED,SAAAuY,CAAUzV,EAAasG,EAAqBiQ,GAE3C,KADAA,EAAWA,GAAsBvZ,KAAKuZ,UACvB,OAAOvW,EACtB,MAAMmG,EAAInJ,KAAKwZ,aAAavZ,IAAIsZ,GAChC,IAAKpQ,EAAG,OAAOnG,EACf,MAAM+L,EAAI5F,EAAEsP,UAAUzV,EAAKsG,GAC3B,YAAUpJ,IAAN6O,EAAwB/L,EACrB+L,CACP,oEAGI,cAAiCuK,EACtC,WAAAxZ,CAAYyZ,GACXtY,QACAjB,KAAK0Z,cAAc,KAAM,IAAIZ,GAC7B9Y,KAAK0Z,cAAc,KAAM,IAAIV,GAC7BhZ,KAAKyZ,YAAYF,EACjB,0BCvDD,qBAAOW,CAAenY,GACrB,MAAMgH,EAAIF,OAAO9G,GACjB,GAAU,OAANgH,GAAcF,OAAOG,MAAMD,GAAI,MAAO,GAC1C,GAAU,IAANA,EAAS,MAAO,IACpB,MAAMoR,EAAI5T,KAAKyE,MAAMzE,KAAKqN,IAAI7K,GAAKxC,KAAKqN,IAAI,OAC5C,OAA+C,IAArC7K,EAAIxC,KAAK6C,IAAI,KAAM+Q,IAAIC,QAAQ,GAAU,IAAM,CAAC,IAAK,KAAM,KAAM,KAAM,MAAMD,EACvF,yDCED,WAAAra,CAAYQ,EAA8B+Z,GAA8B,GANxEra,KAAAsa,YAAgC,CAAE/O,OAAO,GAOxCvL,KAAKqa,mBAAqBA,EAC1Bra,KAAKM,QAAU,IAAIF,SAClB,CAACC,EAASM,KACTL,EACEC,MACAiI,IACC,IAAKxI,KAAKsa,YAAY/O,MACrB,OAAOlL,EAAQmI,EACf,IAGF/H,OACAqG,KACK9G,KAAKqa,oBAAuBra,KAAKsa,YAAY/O,OAChD5K,EAAOmG,EACP,GAEF,GAGJ,CAED,MAAAyT,GACCva,KAAKsa,YAAY/O,OAAQ,CACzB,kJC7BI,cAAwDmE,EAI7D,WAAA5P,CAAY6P,EAAoB7H,EAAcvG,GAC7CN,MAAM0O,EAAQ7H,GACd9H,KAAKG,MAAQ,IAAImB,GAA2BuO,GAAe5O,MAAM2O,WAAWC,IAAKtO,EACjF,CAED,UAAAqO,CAAWC,GACV,OAAO7P,KAAKG,MAAMF,IAAI4P,EACtB,CAED,IAAAE,CAAK5G,GACJ,OAAOlI,MAAM8O,KAAK5G,GAAG5I,MACnByD,IACIA,EAAE6L,IAAI7P,KAAKG,MAAMiB,IAAI4C,EAAE6L,GAAI7L,GACxBA,IAET,CAED,OAAO6L,GACN,OAAO5O,MAAMW,OAAOiO,GAAItP,MAAK,IAAMP,KAAKG,MAAMS,MAAMiP,IACpD,CAED,KAAAjP,CAAMiP,GACL7P,KAAKG,MAAMS,MAAMiP,EACjB,CAED,QAAA5N,GACC,OAAOjC,KAAKG,MAAM8B,UAClB,uDClCI,cAAoFyN,EAEzF,UAAAE,CAAWC,GACV,MAAM,IAAInN,MAAM,gCAChB,CAED,cAAA8X,CAAe3K,GACd,OAAO7P,KAAK2P,OAAOV,QAAQ,GAAGjP,KAAK8H,QAAQ+H,IAC3C,CAED,IAAAE,CAAK5G,GACJ,MAAM,IAAIzG,MAAM,0BAChB,CAED,QAAA+X,CAAStR,GACR,OAAIA,EAAE0G,GACE7P,KAAK2P,OAAOL,QAAQ,GAAGtP,KAAK8H,QAAQqB,EAAE0G,KAAM1G,GAE5CnJ,KAAK2P,OAAOR,SAASnP,KAAK8H,KAAMqB,EAExC,4GClBD,WAAArJ,CAAYC,GACXC,KAAKD,SAAWA,CAChB,CAED,GAAAE,GAIC,YAHmBC,IAAfF,KAAKG,QACRH,KAAKG,MAAQH,KAAKD,YAEZC,KAAKG,KACZ,CAED,KAAAS,GACCZ,KAAKG,WAAQD,CACb,CAED,QAAAW,GACC,YAAuBX,IAAfF,KAAKG,KACb,mEChBI,cAAkDuP,EAIvD,WAAA5P,CAAY6P,EAAoB7H,GAC/B7G,MAAM0O,EAAQ7H,GACd9H,KAAKG,MAAQ,IAAIN,GAAoB,IAAMG,KAAK0a,mBAChD,CAEO,eAAAA,GACP,OAAO1a,KAAK2P,OAAOV,QAAQ,GAAGjP,KAAK8H,WACnC,CAED,OAAA6S,GACC,OAAO3a,KAAKG,MAAMF,KAClB,CAED,UAAA2P,CAAWC,GAEV,OAAO7P,KAAK2a,UAAUpa,MACpBqa,IACA,MAAMzR,EAAIyR,EAAInW,MAAM0V,GAAMA,EAAEtK,KAAOA,IACnC,QAAW3P,IAAP2P,EAAkB,MAAM,IAAInN,MAAM,GAAG1C,KAAK8H,WAAW+H,gBACzD,OAAO1G,CAAC,GAGV,CAED,IAAA4G,CAAK5G,GACJ,OAAOlI,MAAM8O,KAAK5G,GAChB5I,MAAMyD,IACNhE,KAAKG,MAAMS,QACJoD,IAET,CAED,OAAO6L,GACN,OAAO5O,MAAMW,OAAOiO,GAAItP,MAAK,IAAMP,KAAKG,MAAMS,SAC9C,CAED,KAAAA,GACCZ,KAAKG,MAAMS,OACX,CAED,QAAAqB,GACC,MAAMF,EAAO/B,KAAKG,MAAMW,YAAY8C,OACpC,MAAO,CACN1B,YAAaH,GAAQ,EACrBI,SAAUJ,GAAQ,EAEnB,oPC1CI,cACI4K,EAaR,WAAA7M,CACEkM,EACA6O,EACAC,EAAuB,WAEvB7Z,MAAM+K,GAENhM,KAAK6a,qBACHA,GAAwB,IAAI3E,EAA4BlW,MAC1DA,KAAK8a,aAAeA,EAGpB9a,KAAK+a,eAAiB,IAAIpO,EAAWX,GAErChM,KAAKgb,WAAa,IAAInb,GAAkC,IACtDG,KAAKib,0BAEPjb,KAAKkb,aAAe,IAAIrb,GAA6B,IACnDG,KAAKmb,2BAER,CAED,eAAA1H,GACE,OAAOzT,KAAKwV,kBAAkBjV,MAAMwO,GAAMA,EAAE0E,mBAC7C,CAKD,UAAA2H,GACE,OAAOpb,KAAKyT,iBACb,CAED,MAAA4H,GACE,OAAOrb,KAAKY,QAAQL,MAAK,IAAMP,KAAKob,cACrC,CAED,KAAAxa,GACE,OAAOZ,KAAKwV,kBAAkBjV,MAAMkV,GAAMA,EAAE7U,SAC7C,CAMD,QAAA0a,CAAStP,GACP,OAAOhM,KAAK8a,YACb,CAEO,qBAAAG,GACN,OAAOjb,KAAK+a,eAAe9L,QAAQ,oBACpC,CAED,aAAAgG,GACE,OAAOjV,KAAKgb,WAAW/a,KACxB,CAES,uBAAAkb,GACR,OAAOnb,KAAKiV,gBAAgB1U,MACzBgb,GACC,IAAIxI,EACFwI,EAAKnG,eACLmG,EAAKtI,eACLjT,KAAK6a,uBAGZ,CAED,eAAArF,GACE,OAAOxV,KAAKkb,aAAajb,KAC1B,CAED,KAAA6T,CAAMA,EAAeC,GACnB,OAAO/T,KAAKwV,kBAAkBjV,MAAMkV,GAAMA,EAAE3B,MAAMA,EAAOC,IAC1D,CAED,UAAAyH,CAAWzK,GACT,OAAO/Q,KAAKwV,kBAAkBjV,MAAMkV,GAAMA,EAAE/B,gBAAgB3C,IAC7D,CAED,UAAAvD,CAAWC,GACT,OAAOzN,KAAKwV,kBACTjV,MAAMkb,GAAOA,EAAGpH,eAAerU,KAAKsb,SAAS7N,MAC7ClN,MAAMiS,GACLvR,MAAMuM,WAAWC,GAAUlN,MAAMmN,IAC/BA,EAAQtM,IAAI,gBAAiB,UAAUoR,KAChC9E,MAGd,mECrGF,WAAA5N,CAAY4b,EAAoB,GAAIC,EAA0B,KAC7D3b,KAAK0b,UAAYA,EACjB1b,KAAK2b,gBAAkBA,EACvB3b,KAAK4b,GAAK,IAAI5L,EACdhQ,KAAK6b,OAAS,GACd7b,KAAK8b,cAAgB,EACrB,CAED,kBAAAC,CAAmBrL,GAClB1Q,KAAK4b,GAAG1L,iBAAiB,SAAUQ,EACnC,CAED,qBAAAsL,CAAsBtL,GACrB1Q,KAAK4b,GAAGvL,oBAAoB,SAAUK,EACtC,CAED,aAAAuL,GACCjc,KAAK4b,GAAGpL,aAAa,SACrB,CAED,KAAA5P,GACCZ,KAAK6b,OAAS,GACd7b,KAAK8b,cAAgB,GACrB9b,KAAKic,eACL,CAED,IAAAC,CAAKC,GACJnc,KAAK8b,cAAcxL,OAAOtQ,KAAK8b,cAAcvL,QAAQ4L,GAAQ,GAC7Dnc,KAAKic,eACL,CAED,OAAAG,GACCpc,KAAK8b,cAAgB,GACrB9b,KAAKic,eACL,CAED,gBAAAI,GACCrc,KAAK8b,cAAcvO,SAClBrH,IACC,MAAMoW,EAAY/S,EAASsB,mBAAmB3E,EAAEqW,OAASvc,KAAK2b,gBACxDa,EAAYxc,KAAK2b,gBAAkBW,EACrCE,EAAY,EACftW,EAAEsW,UAAYA,GAEdtW,EAAEsW,eAAYtc,EACdF,KAAKkc,KAAKhW,GACV,IAGHlG,KAAKic,eACL,CAED,MAAAtV,CAAOwV,GACNnc,KAAK6b,OAAOvL,OAAOtQ,KAAK6b,OAAOtL,QAAQ4L,GAAQ,GAC/Cnc,KAAKic,eACL,CAED,GAAAlF,CAAIoF,GAMH,SALwBjc,IAApBic,EAAMK,YACTL,EAAMK,UAAYxc,KAAK2b,iBAExB3b,KAAK6b,OAAOhU,KAAKsU,GACjBnc,KAAK8b,cAAcjU,KAAKsU,GACjBnc,KAAK6b,OAAOjY,OAAS5D,KAAK0b,WAChC1b,KAAK6b,OAAOY,QAEbzc,KAAKic,eACL,CAED,MAAAS,CAAOC,EAAqB1Y,GAC3BjE,KAAK+W,IAAI,CACRwF,KAAM,IAAIpb,KACVwb,KAAMA,EACN1Y,QAASA,GAEV,CAED,GAAAvD,CAAIkO,GACH5O,KAAK0c,OAAO/L,sBAAc/B,MAAwB,iBAAVA,EAAqBA,EAAQA,EAAM/K,WAC3E,CAED,IAAA+Y,CAAK3Y,GACJjE,KAAK0c,OAAO/L,QAAAA,cAAckM,QAAS5Y,EACnC,CAED,IAAAsX,CAAKtX,GACJjE,KAAK0c,OAAO/L,QAAAA,cAAc4K,KAAMtX,EAChC,CAED,UAAA6Y,GACC,MAAM1U,EAAK,IAAI5G,IACDsM,OAAOiP,OAAOpM,QAAaA,eACnCpD,SAAQ,CAACwB,EAAGiO,KACjB5U,EAAIhH,IAAI2N,EAAG,EAAE,IAEd,IAAK,IAAItL,EAAI,EAAGA,EAAIzD,KAAK6b,OAAOjY,OAAQH,IAAK,CAC5C,MAAM0Y,EAAQnc,KAAK6b,OAAOpY,GACpBsF,EAAYX,EAAInI,IAAIkc,EAAMQ,OAAS,EACzCvU,EAAIhH,IAAI+a,EAAMQ,KAAM5T,EAAI,EACxB,CACD,OAAOX,CACP"}
|
|
@@ -1,39 +1,5 @@
|
|
|
1
1
|
import { RestClient } from "../client";
|
|
2
|
-
|
|
3
|
-
export type PermissionLevel = (typeof PERMISSION_LEVELS)[number];
|
|
4
|
-
export type TokenRequestPayloadBase = {
|
|
5
|
-
targetAudience: string;
|
|
6
|
-
};
|
|
7
|
-
export type RequestAccessTokenPayload = TokenRequestPayloadBase & {
|
|
8
|
-
refreshToken: string;
|
|
9
|
-
scope: string;
|
|
10
|
-
};
|
|
11
|
-
export type RenewRefreshTokenPayload = {
|
|
12
|
-
refreshToken: string;
|
|
13
|
-
};
|
|
14
|
-
export type RequestRefreshTokenFromLoginPayload = TokenRequestPayloadBase & {
|
|
15
|
-
login: string;
|
|
16
|
-
password: string;
|
|
17
|
-
};
|
|
18
|
-
export type TokenResponsePayloadBase = {
|
|
19
|
-
token: string;
|
|
20
|
-
issuedAt: Date;
|
|
21
|
-
expires?: Date | null;
|
|
22
|
-
};
|
|
23
|
-
export type IdTokenPayload = TokenResponsePayloadBase & {};
|
|
24
|
-
export type AccessTokenPayload = TokenResponsePayloadBase & {
|
|
25
|
-
scopes?: Array<string>;
|
|
26
|
-
};
|
|
27
|
-
export type RefreshTokenPayload = TokenResponsePayloadBase & {};
|
|
28
|
-
export type JwKeyPayload = {
|
|
29
|
-
kty: string;
|
|
30
|
-
kid: string;
|
|
31
|
-
n: string;
|
|
32
|
-
e: string;
|
|
33
|
-
};
|
|
34
|
-
export type JwksPayload = {
|
|
35
|
-
keys: Array<JwKeyPayload>;
|
|
36
|
-
};
|
|
2
|
+
import { AccessTokenPayload, IdTokenPayload, JwksPayload, RefreshTokenPayload, RenewRefreshTokenPayload, RequestAccessTokenPayload, RequestRefreshTokenFromLoginPayload } from "./Types";
|
|
37
3
|
/**
|
|
38
4
|
* This implements rest client for OAuth server - https://github.com/lotcz/oauth-server
|
|
39
5
|
* Provide basic url, /api/oauth path prefix will be added automatically
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { AccessTokenPayload, IdTokenPayload,
|
|
1
|
+
import { AccessTokenPayload, IdTokenPayload, RefreshTokenPayload } from "./Types";
|
|
2
2
|
import { OAuthRefreshTokenProvider } from "./tokenprovider/OAuthRefreshTokenProvider";
|
|
3
|
+
import { OAuthRestClient } from "./OAuthRestClient";
|
|
3
4
|
/**
|
|
4
5
|
* Manages refresh of id and access tokens.
|
|
5
6
|
*/
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { PermissionLevel, TokenResponsePayloadBase } from "./Types";
|
|
2
|
+
export declare class OAuthUtil {
|
|
3
|
+
static isValidToken(token?: TokenResponsePayloadBase | null): boolean;
|
|
4
|
+
static isTokenExpired(token?: TokenResponsePayloadBase | null): boolean;
|
|
5
|
+
static isTokenReadyForRefresh(token?: TokenResponsePayloadBase | null): boolean;
|
|
6
|
+
static getScopeString(privilege: string, level: PermissionLevel): string;
|
|
7
|
+
static extractPrivilege(scope: string): string;
|
|
8
|
+
static isPermissionLevel(value: string): value is PermissionLevel;
|
|
9
|
+
static extractPermissionLevel(scope: string): PermissionLevel;
|
|
10
|
+
static getLevel(level: PermissionLevel): number;
|
|
11
|
+
/**
|
|
12
|
+
* Returns true if given scope grants permission for specific privilege on at least required level.
|
|
13
|
+
*
|
|
14
|
+
* @param ownedScope Existing scope, usually owned by user in form of access token
|
|
15
|
+
* @param requiredScopeOrPrivilege Required privilege name or whole scope (omit minLevel)
|
|
16
|
+
* @param minLevel Required minimal permission level
|
|
17
|
+
*/
|
|
18
|
+
static hasPermission(ownedScope: string, requiredScopeOrPrivilege: string, minLevel?: PermissionLevel): boolean;
|
|
19
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { OAuthTokenManager } from "./OAuthTokenManager";
|
|
2
2
|
import { RestClient } from "../client";
|
|
3
|
-
import { IdTokenPayload, RefreshTokenPayload } from "./OAuthRestClient";
|
|
4
3
|
import { OAuthRefreshTokenProvider } from "./tokenprovider/OAuthRefreshTokenProvider";
|
|
4
|
+
import { IdTokenPayload, RefreshTokenPayload } from "./Types";
|
|
5
5
|
export type ServerOAuthInfoPayload = {
|
|
6
6
|
debugMode?: boolean;
|
|
7
7
|
targetAudience: string;
|