@factory-utils/tools
Version:
Set of genericised angular2+ components used in most of Advanced SCHEMA - Factory's projects.
1 lines • 502 kB
Source Map (JSON)
{"version":3,"file":"factory-utils-tools.mjs","sources":["../../../projects/tools/src/lib/utils/string/string.util.ts","../../../projects/tools/src/lib/utils/object/object.util.ts","../../../projects/tools/src/lib/utils/array/array.util.ts","../../../projects/tools/src/lib/utils/all-type/all-type.util.ts","../../../projects/tools/src/lib/utils/changes/changes.util.ts","../../../projects/tools/src/lib/utils/date/date.util.ts","../../../projects/tools/src/lib/utils/text-parser/text-parser.util.ts","../../../projects/tools/src/lib/services/number-format/number-format.service.ts","../../../projects/tools/src/lib/services/locale/locale.service.ts","../../../projects/tools/src/lib/components/calendar/calendar.component.html","../../../projects/tools/src/lib/components/calendar/calendar.component.ts","../../../projects/tools/src/lib/components/checkbox/checkbox.component.html","../../../projects/tools/src/lib/components/checkbox/checkbox.component.ts","../../../projects/tools/src/lib/components/confirm/confirm.component.html","../../../projects/tools/src/lib/components/confirm/confirm.component.ts","../../../projects/tools/src/lib/components/counter/counter.component.html","../../../projects/tools/src/lib/components/counter/counter.component.ts","../../../projects/tools/src/lib/directives/mouseup-outside/mouseup-outside.directive.ts","../../../projects/tools/src/lib/components/slider/slider.component.html","../../../projects/tools/src/lib/components/slider/slider.component.ts","../../../projects/tools/src/lib/components/date-slider/date-slider.component.ts","../../../projects/tools/src/lib/models/lazy-perfect-scrollbar.model.ts","../../../projects/tools/src/lib/services/instance-id/instance-id.service.ts","../../../projects/tools/src/lib/components/dropdown/dropdown.component.html","../../../projects/tools/src/lib/components/dropdown/dropdown.component.ts","../../../projects/tools/src/lib/directives/click-outside/click-outside.directive.ts","../../../projects/tools/src/lib/components/element-list/element-list.component.html","../../../projects/tools/src/lib/components/element-list/element-list.component.ts","../../../projects/tools/src/lib/utils/error/error.util.ts","../../../projects/tools/src/lib/services/excel-generator/excel-generator.service.ts","../../../projects/tools/src/lib/components/excel-button/excel-button.component.html","../../../projects/tools/src/lib/components/excel-button/excel-button.component.ts","../../../projects/tools/src/lib/components/tooltip/tooltip.component.ts","../../../projects/tools/src/lib/components/tooltip/tooltip.component.html","../../../projects/tools/src/lib/components/generator-container/generator-container.component.ts","../../../projects/tools/src/lib/components/generator-container/generator-container.component.html","../../../projects/tools/src/lib/components/input-date/input-date.component.html","../../../projects/tools/src/lib/components/input-date/input-date.component.ts","../../../projects/tools/src/lib/components/input-number/input-number.component.html","../../../projects/tools/src/lib/components/input-number/input-number.component.ts","../../../projects/tools/src/lib/components/menu/menu.component.ts","../../../projects/tools/src/lib/components/menu/menu.component.html","../../../projects/tools/src/lib/components/text-base/text-base.component.ts","../../../projects/tools/src/lib/components/rich-text/rich-text.component.html","../../../projects/tools/src/lib/components/rich-text/rich-text.component.ts","../../../projects/tools/src/lib/components/search/search.component.ts","../../../projects/tools/src/lib/components/search/search.component.html","../../../projects/tools/src/lib/components/simple-text/simple-text.component.ts","../../../projects/tools/src/lib/components/simple-text/simple-text.component.html","../../../projects/tools/src/lib/components/switch/switch.component.html","../../../projects/tools/src/lib/components/switch/switch.component.ts","../../../projects/tools/src/lib/directives/value-validator/value-validator.directive.ts","../../../projects/tools/src/lib/tools.module.ts","../../../projects/tools/src/public_api.ts","../../../projects/tools/src/factory-utils-tools.ts"],"sourcesContent":["import { Injectable } from '@angular/core';\n\n@Injectable()\nexport class StringUtil {\n\n static equals(arg1: string, arg2: string): boolean {\n return (StringUtil.compare(arg1, arg2) === 0);\n }\n\n static compare(arg1: string, arg2: string, ignoreSpecialChars: boolean = false, ignoreCase: boolean = false): number {\n if (ignoreCase) {\n arg1 = arg1.toLocaleLowerCase();\n arg2 = arg2.toLocaleLowerCase();\n }\n if (ignoreSpecialChars) {\n arg1 = StringUtil.removeSpecialChars(arg1);\n arg2 = StringUtil.removeSpecialChars(arg2);\n }\n\n return arg1 === arg2 ? 0 : arg1 > arg2 ? 1 : -1;\n }\n\n static removeSpecialChars(arg1: string): string {\n return arg1.normalize('NFD').replace(/([\\u0300-\\u036f]|[^0-9a-zA-Z])/g, '');\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Injectable } from '@angular/core';\nimport { ArrayUtil } from '../array/array.util';\nimport { AllTypeUtil } from '../all-type/all-type.util';\nimport { StringUtil } from '../string/string.util';\n\n@Injectable()\nexport class ObjectUtil {\n\n /**\n * Return true if arg is an Object\n *\n */\n static isObject(arg: any): boolean {\n try {\n if (arg !== null && typeof arg === 'object' && arg.constructor.toString().indexOf('Array') < 0) {\n return true;\n }\n return false;\n } catch ( e ) {\n // IE8,9 Will throw exceptions on certain host objects #9897\n return false;\n }\n }\n\n /**\n * Return true when obj given in parameter is empty.\n * Return false otherwise.\n *\n */\n static isEmpty(obj: Object): boolean {\n return Object.keys(obj).length === 0;\n }\n\n /**\n * Return number attributes.\n *\n */\n static size(obj: Object, ignoredValue?: Array<any>): number {\n let size: number = 0;\n for (const key in obj) {\n if (obj.hasOwnProperty(key)\n && (typeof ignoredValue === 'undefined'\n || !ArrayUtil.contains(ignoredValue, key))) {\n size++;\n }\n }\n return size;\n }\n\n /**\n * Return a copy of an object.\n */\n static copy(obj: Object): Object {\n const out: Object | Array<any> = Array.isArray(obj) ? [] : {};\n for (const key in obj) {\n const v: unknown = obj[key];\n out[key] = (typeof v === 'object') ? ObjectUtil.copy(v) : v;\n }\n return out;\n }\n\n /**\n * Return a copy of an object.\n */\n static deepCopy(block: any): any {\n let out: any = null;\n\n if (Array.isArray(block)) {\n out = [];\n for (const elem of block) {\n const subArray: any = elem;\n out.push((typeof subArray === 'object') ? ObjectUtil.deepCopy(subArray) : subArray);\n }\n } else {\n out = {};\n for (const key in block) {\n const subObject: any = block[key];\n out[key] = (typeof subObject === 'object') ? ObjectUtil.deepCopy(subObject) : subObject;\n }\n }\n return out;\n }\n\n /**\n * Compare an object with the current object.\n * Return true if the two elements are identical.\n * Otherwise return false.\n *\n */\n static equals(obj1: any, obj2: any): boolean {\n return (ObjectUtil.compare(obj1, obj2) === 0);\n }\n\n static compare(obj1: Object, obj2: any): number {\n const size1: number = ObjectUtil.size(obj1);\n const size2: number = ObjectUtil.size(obj2);\n\n if (size1 !== size2) {\n return size1 - size2;\n }\n for (const key in obj1) {\n const value1: any = obj1[key];\n const value2: any = obj2[key];\n\n if (!AllTypeUtil.equals(value1, value2)) {\n return AllTypeUtil.compare(value1, value2);\n }\n }\n return 0;\n }\n\n /**\n * Returns all entries matching searchedValue in obj and all its children\n *\n */\n static deepSearch(obj: Object, hierarchicalField: string, searchedField: string, searchedValue: any, skipChildren: boolean = true, skipReferences: boolean = true, ignoreSpecialChars: boolean = false, ignoreCase: boolean = false, multipleSearchedValues: boolean = false): Object[] {\n let currValue: string | number = obj[searchedField];\n let cleanedObj: Object[] = [];\n function subSearch(searchedValue: any, currValue: string | number) {\n let subCleanedObj: Object[] = [];\n if (typeof currValue === 'string') {\n if (ignoreCase) {\n currValue = currValue.toLocaleLowerCase();\n searchedValue = searchedValue.toLocaleLowerCase();\n }\n if (ignoreSpecialChars) {\n currValue = StringUtil.removeSpecialChars(currValue);\n searchedValue = StringUtil.removeSpecialChars(searchedValue);\n }\n if (currValue.indexOf(searchedValue) > -1) {\n if (skipReferences) {\n subCleanedObj.push(ObjectUtil.deepCopy(obj));\n } else {\n subCleanedObj.push(obj);\n }\n if (skipChildren) {\n delete subCleanedObj[0][hierarchicalField];\n }\n } else if (obj[hierarchicalField] && obj[hierarchicalField].length) {\n let deepRes: Object[] = ArrayUtil.deepSearch(obj[hierarchicalField], hierarchicalField, searchedField, searchedValue, skipChildren, skipReferences, ignoreSpecialChars, ignoreCase, multipleSearchedValues);\n\n return deepRes;\n }\n } else if (obj[searchedField] === searchedValue) {\n if (skipReferences) {\n subCleanedObj.push(ObjectUtil.deepCopy(obj));\n } else {\n subCleanedObj.push(obj);\n }\n if (skipChildren) {\n delete subCleanedObj[0][hierarchicalField];\n }\n } else if (obj[hierarchicalField] && obj[hierarchicalField].length) {\n let deepRes: Object[] = ArrayUtil.deepSearch(obj[hierarchicalField], hierarchicalField, searchedField, searchedValue, skipChildren, skipReferences, ignoreSpecialChars, ignoreCase, multipleSearchedValues);\n\n return deepRes;\n }\n return subCleanedObj;\n }\n if (multipleSearchedValues && typeof searchedValue === 'string') {\n const searchedValues: string[] = searchedValue.replace(/(\\s|\\t)+/g, ' ').split(' ');\n for (let searchedValue of searchedValues) {\n let res: Object[] = subSearch(searchedValue, currValue);\n for (let element of res) {\n if (cleanedObj.findIndex((objElement: Object) => element[searchedField] === objElement[searchedField]) === -1) {\n cleanedObj.push(element);\n }\n }\n }\n } else {\n cleanedObj = subSearch(searchedValue, currValue);\n }\n\n return cleanedObj;\n }\n\n /**\n * Fills an object with the given object, without changing its reference.\n *\n */\n static fill(target: Object, source: Object): void {\n for (const elemIndex in source) {\n if (target[elemIndex] && ObjectUtil.isObject(target[elemIndex])) {\n ObjectUtil.fill(target[elemIndex], source[elemIndex]);\n } else {\n target[elemIndex] = source[elemIndex];\n }\n }\n }\n\n /**\n * Get the key of an object with specific value.\n *\n */\n static getKeyByValue(obj: Object, value: any): string | undefined {\n for (const key in obj) {\n if (obj.hasOwnProperty(key) && obj[key] === value) {\n return key;\n }\n }\n }\n\n /**\n * Clear an object\n *\n */\n static clear(obj: Object, ignoredValue?: Array<any>): void {\n for (const key in obj) {\n if (obj.hasOwnProperty(key)\n && (typeof ignoredValue === 'undefined'\n || !ArrayUtil.contains(ignoredValue, key))) {\n delete obj[key];\n }\n }\n }\n\n /**\n * Copy all obj1 values in obj2 and keep obj2 reference\n *\n */\n static applyDiff(obj1: Object, obj2: Object): void {\n const typesAllowCopy: Array<string> = ['string', 'number'];\n for (const key2 in obj2) {\n if (key2 in obj1) {\n if (((ObjectUtil.isObject(obj1[key2]) && ObjectUtil.isObject(obj2[key2]))\n || (ArrayUtil.isArray(obj1[key2]) && ArrayUtil.isArray(obj2[key2])))\n && !ObjectUtil.equals(obj1[key2], obj2[key2])) {\n ObjectUtil.applyDiff(obj1[key2], obj2[key2]);\n } else if (typesAllowCopy.indexOf(typeof obj1[key2]) !== -1 &&\n typesAllowCopy.indexOf(typeof obj2[key2]) !== -1 &&\n obj1[key2] !== obj2[key2]) {\n obj2[key2] = obj1[key2];\n }\n } else if (!(key2 in obj1)) {\n delete obj2[key2];\n }\n }\n for (const key1 in obj1) {\n if (!(key1 in obj2)) {\n obj2[key1] = obj1[key1];\n }\n }\n }\n}\n","import { Injectable } from '@angular/core';\nimport { ObjectUtil } from '../object/object.util';\nimport { AllTypeUtil } from '../all-type/all-type.util';\n\n@Injectable()\nexport class ArrayUtil {\n\n /**\n * Return true if arg is an Array\n *\n */\n static isArray(arg: unknown): boolean {\n return Object.prototype.toString.call(arg) === '[object Array]';\n }\n\n /**\n * Return the first occurrence.\n *\n */\n static front(array: unknown[]): unknown {\n return array[0];\n }\n\n /**\n * Return the last occurrence.\n *\n */\n static back(array: unknown[]): unknown {\n return array[array.length - 1];\n }\n\n /**\n * Return a copy of an array.\n *\n */\n static copy(array: unknown[]): unknown[] {\n return (JSON.parse(JSON.stringify(array)));\n }\n\n static equals(array1: unknown[], array2: unknown[]): boolean {\n return (ArrayUtil.compare(array1, array2) === 0);\n }\n\n static compare(array1: unknown[], array2: unknown[]): number {\n if (array1.length !== array2.length) {\n return array1.length - array2.length;\n }\n\n array1.sort();\n array2.sort();\n array1.forEach(function(value: unknown, index: number): number {\n const value2: unknown = array2[index];\n\n if (!AllTypeUtil.equals(value, value2)) {\n return AllTypeUtil.compare(value, value2);\n }\n });\n return 0;\n }\n\n /**\n * Fills an array with the given array, without changing its reference.\n *\n */\n static fill(target: unknown[], source: unknown[]): void {\n target.length = 0;\n for (const elem of source) {\n target.push(elem);\n }\n }\n\n /**\n * Check if an element exist.\n * Return true is element is found.\n * Otherwise return false.\n *\n */\n static contains(array: unknown[], elem: unknown): boolean {\n for (const el of array) {\n if (el === elem) {\n return true;\n }\n }\n return false;\n }\n\n /**\n * Returns all entries matching searchedValue in array and all its children\n *\n */\n static deepSearch(arr: unknown[], hierarchicalField: string, searchedField: string, searchedValue: unknown, skipChildren: boolean = true, skipReferences: boolean = true, ignoreSpecialChars: boolean = false, ignoreCase: boolean = false, multipleSearchedValues: boolean = false): Object[] {\n let res: Object[] = [];\n\n for (const child of arr) {\n if (child) {\n let objRes: Object[] = ObjectUtil.deepSearch(child, hierarchicalField, searchedField, searchedValue, skipChildren, skipReferences, ignoreSpecialChars, ignoreCase, multipleSearchedValues);\n\n if (objRes && objRes.length) {\n res.push(...objRes);\n }\n }\n }\n return res;\n }\n\n /**\n * Clear an array\n *\n */\n static clear(array?: unknown[]): void {\n while (array.length > 0) {\n array.pop();\n }\n }\n\n /**\n * Initialize a new array\n * if defaultItem is set, it pushes size (default 0) defaultItem items in the array\n *\n */\n static init(defaultItem?: unknown[], size?: number): Array<Object> {\n const newArray: unknown[] = [];\n\n if (typeof defaultItem !== 'undefined') {\n if (typeof size === 'undefined') {\n size = 0;\n }\n for (let i: number = 0; i < size; ++i) {\n if (ArrayUtil.isArray(defaultItem)) {\n newArray.push(ArrayUtil.copy(defaultItem));\n } else if (ObjectUtil.isObject(defaultItem)) {\n newArray.push(ObjectUtil.copy(defaultItem));\n } else {\n newArray.push(defaultItem);\n }\n }\n }\n return newArray;\n }\n\n /**\n * Find an element in Array\n * If array given in parameter is an object's array, you can specify a key\n *\n */\n static find(array: unknown[], value: unknown, key?: string | number): unknown {\n for (const el of array) {\n if (typeof key === 'undefined' && el === value) {\n return el;\n } else if (typeof key !== 'undefined'\n && ObjectUtil.isObject(el)\n && el[key] === value) {\n return el;\n }\n }\n return null;\n }\n\n /**\n * Find all elements in Array\n * If array given in parameter is an object's array, you can specify a key\n *\n */\n static findAll(array: unknown[], value: unknown, key?: string | number): unknown[] {\n const res: unknown[] = [];\n\n for (const el of array) {\n if (typeof key === 'undefined' && el === value) {\n res.push(el);\n } else if (typeof key !== 'undefined'\n && ObjectUtil.isObject(el)\n && el[key] === value) {\n res.push(el);\n }\n }\n return res;\n }\n\n /**\n * Find index of the given value\n *\n */\n static findIndex(array: unknown[], value: unknown): number {\n for (let i: number = 0; i < array.length; i++) {\n if (array[i] === value) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Find object of the given object\n *\n */\n static findObject(array: unknown[], obj: Object): Object | null {\n for (const entry of array) {\n if (ObjectUtil.equals(entry, obj)) {\n return entry;\n }\n }\n return null;\n }\n\n /**\n * Find an element in Array\n * If array given in parameter is an object's array, you can specify a key\n *\n */\n static findObjIndex(array: unknown[], value: unknown, key?: string | number): number {\n for (let i: number = 0; i < array.length; i++) {\n if (typeof key === 'undefined' && array[i] === value) {\n return i;\n } else if (typeof key !== 'undefined'\n && ObjectUtil.isObject(array[i])\n && array[i][key] === value) {\n return i;\n }\n }\n return -1;\n }\n\n /**\n * Insert value at the specified index\n *\n */\n static insert(array: unknown[], index: number, value: unknown): void {\n array.splice(index, 0, value);\n }\n\n /**\n * Remove specific index\n *\n */\n static removeIndex(array: unknown[], index: number): void {\n array.splice(index, 1);\n }\n}\n","import { Injectable } from '@angular/core';\nimport { ArrayUtil } from '../array/array.util';\nimport { ObjectUtil } from '../object/object.util';\nimport { StringUtil } from '../string/string.util';\n\n@Injectable()\nexport class AllTypeUtil {\n\n static equals(arg1: unknown, arg2: unknown): boolean {\n return (AllTypeUtil.compare(arg1, arg2) === 0);\n }\n\n static compare(arg1: unknown, arg2: unknown): number {\n const typeofArg1: string = typeof arg1;\n const typeofArg2: string = typeof arg2;\n\n if (typeofArg1 !== typeofArg2) {\n return -1;\n }\n if (typeofArg1 === 'string') {\n return StringUtil.compare(arg1 as string, arg2 as string);\n } else if (ArrayUtil.isArray(arg1)) {\n return ArrayUtil.compare(arg1 as unknown[], arg2 as unknown[]);\n } else if (ObjectUtil.isObject(arg1)) {\n return ObjectUtil.compare(arg1, arg2);\n } else {\n return (arg1 as number) - (arg2 as number);\n }\n }\n}\n","import { Injectable, SimpleChanges } from '@angular/core';\n\nimport { AllTypeUtil } from '../all-type/all-type.util';\nimport { DefaultValues } from '../../typings';\n\n@Injectable()\nexport class ChangesUtil {\n\n static hasChanged(changes: SimpleChanges, property?: string, member?: string): boolean {\n if (typeof property === 'undefined') {\n let somethingHasChanged: boolean = false;\n\n for (const attrKey in changes) {\n if (ChangesUtil.hasChanged(changes, attrKey)) {\n somethingHasChanged = true;\n }\n }\n return somethingHasChanged;\n } else if (changes[property]) {\n let member1: unknown = changes[property].previousValue;\n let member2: unknown = changes[property].currentValue;\n\n if (!member1) {\n return true;\n }\n if (member) {\n member1 = changes[property].previousValue[member];\n member2 = changes[property].currentValue[member];\n }\n return !AllTypeUtil.equals(member1, member2);\n }\n return false;\n }\n\n static resetWrongInputs(changes: SimpleChanges, defaultValues: DefaultValues, component: unknown): void {\n for (const key in defaultValues) {\n if (changes[key] && (typeof component[key] === 'undefined' || component[key] === null)) {\n component[key] = defaultValues[key];\n changes[key].currentValue = defaultValues[key];\n }\n }\n }\n}\n","export interface MonthFormat {\n shortLabel: string;\n longLabel: string;\n}\n\nexport class DateUtil {\n\n static quarterLabels: MonthFormat[] = [\n {\n shortLabel: 'Q1',\n longLabel: '1st quarter'\n },\n {\n shortLabel: 'Q2',\n longLabel: '2nd quarter'\n },\n {\n shortLabel: 'Q3',\n longLabel: '3rd quarter'\n },\n {\n shortLabel: 'Q4',\n longLabel: '4th quarter'\n }\n ];\n\n static monthLabels: MonthFormat[] = [\n {\n shortLabel: 'jan',\n longLabel: 'january'\n },\n {\n shortLabel: 'feb',\n longLabel: 'february'\n },\n {\n shortLabel: 'mar',\n longLabel: 'march'\n },\n {\n shortLabel: 'apr',\n longLabel: 'april'\n },\n {\n shortLabel: 'may',\n longLabel: 'may'\n },\n {\n shortLabel: 'jun',\n longLabel: 'june'\n },\n {\n shortLabel: 'jul',\n longLabel: 'july'\n },\n {\n shortLabel: 'aug',\n longLabel: 'august'\n },\n {\n shortLabel: 'sep',\n longLabel: 'september'\n },\n {\n shortLabel: 'oct',\n longLabel: 'october'\n },\n {\n shortLabel: 'nov',\n longLabel: 'november'\n },\n {\n shortLabel: 'dec',\n longLabel: 'december'\n }\n ];\n\n static dayDiff(d1: Date, d2: Date): number {\n const timeDiff: number = Math.abs(d2.getTime() - d1.getTime());\n const diffDays: number = timeDiff / (1000 * 3600 * 24);\n\n return Math.floor(diffDays);\n }\n\n static monthDiff(d1: Date, d2: Date): number {\n const year1: number = d1.getFullYear();\n const year2: number = d2.getFullYear();\n let month1: number = d1.getMonth();\n let month2: number = d2.getMonth();\n\n if (month1 === 0) {\n month1++;\n month2++;\n }\n return (year2 - year1) * 12 + (month2 - month1);\n }\n\n static quarterDiff(d1: Date, d2: Date): number {\n const quarterDiff: number = DateUtil.monthDiff(d1, d2) / 3;\n const sign: number = quarterDiff < 0 ? -1 : 1;\n\n return Math.floor(Math.abs(quarterDiff)) * sign;\n }\n\n static yearDiff(d1: Date, d2: Date): number {\n const year1: number = d1.getFullYear();\n const year2: number = d2.getFullYear();\n\n return (year2 - year1);\n }\n\n static dayFirstDate(date: Date): Date {\n const year: number = date.getFullYear();\n const month: number = date.getMonth();\n const day: number = date.getDate();\n\n return new Date(year, month, day, 0);\n }\n\n static dayLastDate(date: Date): Date {\n const year: number = date.getFullYear();\n const month: number = date.getMonth();\n const day: number = date.getDate();\n\n return new Date(year, month, day, 23, 59, 59);\n }\n\n static monthFirstDate(date: Date): Date {\n const year: number = date.getFullYear();\n const month: number = date.getMonth();\n\n return new Date(year, month, 1);\n }\n\n static monthLastDate(date: Date): Date {\n const year: number = date.getFullYear();\n const month: number = date.getMonth();\n\n return new Date(year, month + 1, 0);\n }\n\n static quarterFirstDate(date: Date): Date {\n const year: number = date.getFullYear();\n const month: number = date.getMonth();\n const quarter: number = Math.floor(month / 3);\n\n return new Date(year, quarter * 3, 1);\n }\n\n static quarterLastDate(date: Date): Date {\n const year: number = date.getFullYear();\n const month: number = date.getMonth();\n const quarter: number = Math.ceil(month / 3);\n\n return new Date(year, quarter * 3, 0);\n }\n\n static yearFirstDate(date: Date): Date {\n const year: number = date.getFullYear();\n\n return new Date(year.toString());\n }\n\n static yearLastDate(date: Date): Date {\n const year: number = date.getFullYear();\n\n return new Date(year, 11, 31);\n }\n\n static incrementDay(date: Date): Date {\n const newDate: Date = new Date(date);\n\n newDate.setDate(date.getDate() + 1);\n return newDate;\n }\n\n static incrementMonth(date: Date): Date {\n const newDate: Date = new Date(date);\n\n newDate.setMonth(date.getMonth() + 1);\n return newDate;\n }\n\n static incrementQuarter(date: Date): Date {\n const newDate: Date = new Date(date);\n\n newDate.setMonth(date.getMonth() + 3);\n return newDate;\n }\n\n static incrementYear(date: Date): Date {\n const newDate: Date = new Date(date);\n\n newDate.setFullYear(date.getFullYear() + 1);\n return newDate;\n }\n\n /* eslint-disable @typescript-eslint/no-explicit-any */\n static displayDate(date: number): string;\n static displayDate(date: Date): string;\n static displayDate(date: any): string {\n let display: string;\n\n if (typeof date === 'number') {\n date = new Date(date);\n }\n display = `${DateUtil.displayDay(date)} ${DateUtil.displayMonth(date)} ${DateUtil.displayYear(date)}`;\n return display;\n }\n\n static displayDay(date: number): string;\n static displayDay(date: Date): string;\n static displayDay(date: any): string {\n let display: string;\n\n if (typeof date === 'number') {\n date = new Date(date);\n }\n display = date.getDate().toString();\n return display;\n }\n\n static displayMonth(date: number): string;\n static displayMonth(date: Date): string;\n static displayMonth(date: any): string {\n let display: string;\n\n if (typeof date === 'number') {\n date = new Date(date);\n }\n display = DateUtil.monthLabels[date.getMonth()].shortLabel;\n return display;\n }\n\n static displayQuarter(date: number): string;\n static displayQuarter(date: Date): string;\n static displayQuarter(date: any): string {\n let quarter: number;\n let display: string;\n\n if (typeof date === 'number') {\n date = new Date(date);\n }\n quarter = Math.floor(date.getMonth() / 3);\n display = DateUtil.quarterLabels[quarter].shortLabel;\n return display;\n }\n\n static displayYear(date: number): string;\n static displayYear(date: Date): string;\n static displayYear(date: any): string {\n let display: string;\n\n if (typeof date === 'number') {\n date = new Date(date);\n }\n display = date.getFullYear().toString();\n return display;\n }\n /* eslint-enable */\n}\n","import { marked } from 'marked';\nimport TurndownService from 'turndown';\n\nexport class TextParserUtil {\n\n static htmlToMarkdown(input: string): string {\n input = input\n .replace(/<span class=\"ql-cursor\">.*?<\\/span>/, '') // remove quill cursor\n .replace(/<(\\w*?)[\\s]*[^>]*?(?:class=\"([\\w-]*)\"[\\s]*)?[^>]*?(?:style=\"color: rgb\\(([\\d, ]*?)\\);\"[\\s]*)?[^>]*?(?:class=\"([\\w-]*)\"[\\s]*)?[^>]*?>(.*?)(<\\/\\1>)/gi,\n (match, p1, p2, p3, p4, p5) => {\n let r: string = p5;\n r = (p3 ? '¦S' + p3.replace(/ /g, '') + '¸' + r + '¦' : r); // quill style color\n r = (p2 ? '¦C' + p2.replace(/ql-size-(.).*/, '$1') + '¸' + r + '¦' : r); // quill size class\n r = (p4 ? '¦C' + p4.replace(/ql-size-(.).*/, '$1') + '¸' + r + '¦' : r); // quill size class\n r = (p1 !== 'span' ? '<' + p1 + '>' + r + '</' + p1 + '>' : r); // don't output empty span\n return r;\n }\n ) // replace style and class\n .replace(/<ol>/gi, '¦#') // markdown doesn't handle well lists\n .replace(/<\\/ol>/gi, '·')\n .replace(/<ul>/gi, '¦°') // markdown doesn't handle well lists\n .replace(/<\\/ul>/gi, '·')\n .replace(/<li>/gi, '¦¯') // markdown doesn't handle well lists\n .replace(/<\\/li>/gi, '·')\n .replace(/<u>/gi, '¦_') // markdown doesn't handle underline\n .replace(/<\\/u>/gi, '¸')\n .replace(/<s>/gi, '¦-') // mardown doesn't handle crossed-word\n .replace(/<\\/s>/gi, '¸')\n .replace(/<p><br><\\/p>/gi, '¦BR');\n\n return new TurndownService().turndown(input);\n }\n\n static markdownToHtml(input: string): string {\n let md: typeof marked = marked.setOptions({});\n\n input = input\n .replace(/¦\\#(.*?·)·/gi, '<ol>$1</ol>')\n .replace(/¦\\°(.*?·)·/gi, '<ul>$1</ul>')\n .replace(/¦¯¦C(ql-indent.*?)¸/gi, (m, p1) => {\n return `<li class=\"${p1}\">`;\n })\n .replace(/¦¯(.*?)·/gi, '<li>$1</li>')\n .replace(/¦C(.*?)¸/gi, (m, p1) => {\n if (m === '¦Cl¸') {\n p1 = p1.replace(/l/, 'ql-size-large');\n } else if (m === '¦Cs¸') {\n p1 = p1.replace(/s/, 'ql-size-small');\n }\n return `<span class=\"${p1}\">`;\n })\n .replace(/¦S(.*?)¸/gi, '<span style=\"color: rgb($1);\">')\n .replace(/¦_(.*?)¸/gi, '<u>$1</u>')\n .replace(/¦-(.*?)¸/gi, '<s>$1</s>')\n .replace(/¦BR/gi, '<p><br></p>')\n .replace(/¦·/gi, '</li>')\n .replace(/¦/gi, '</span>')\n .replace(/\\*\\*\\*\\*/g, '**‌**') // bug in marked lib: '**bold1****bold2**' gives '<p><strong>bold1**</strong>bold2**</p>' ‌ is Zero-width non-joiner\n .replace(/\\_\\_/g, '_‌_'); // bug in marked lib: '_italic1__italic2_' gives '<p><em>italic1__italic2<em></p>' ‌ is Zero-width non-joiner\n\n return md.parse(input) as string;\n }\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport { Injectable } from '@angular/core';\n\nimport numeral from 'numeral';\n\n@Injectable()\nexport class NumberFormatService {\n private _numeral: any = numeral;\n\n constructor() {\n this._registerFrenchLocale();\n }\n\n get numeral(): any {\n return this._numeral;\n }\n\n private _registerFrenchLocale(): void {\n if (typeof numeral.locales['fr'] !== 'undefined') {\n return;\n }\n numeral.register('locale', 'fr', {\n delimiters: {\n thousands: ' ',\n decimal: ','\n },\n abbreviations: {\n thousand: 'k',\n million: 'm',\n billion: 'b',\n trillion: 't'\n },\n ordinal : value => (value === 1 ? 'er' : 'ème'),\n currency: {\n symbol: '€'\n }\n });\n }\n}\n","import { Injectable, NgModule } from '@angular/core';\n\nimport { TranslateService, TranslateModule } from '@ngx-translate/core';\nimport moment from 'moment/moment';\n\nimport { NumberFormatService } from '../number-format/number-format.service';\n\n\n@NgModule({\n imports: [\n TranslateModule.forRoot()\n ],\n exports: [\n TranslateModule\n ]\n})\nexport class TranslateTestingModule {\n\n}\n\n@Injectable()\nexport class LocaleService {\n private _currentLanguage: string;\n private _moment: typeof moment;\n\n constructor(\n private _numberFormatService: NumberFormatService,\n private _translateService: TranslateService\n ) {\n this._moment = moment;\n if (this._translateService) {\n this.currentLanguage = this._translateService.currentLang;\n } else {\n this.currentLanguage = navigator.language;\n }\n }\n\n get currentLanguage(): string { return this._currentLanguage; }\n get moment(): typeof moment { return this._moment; }\n\n set currentLanguage(currentLanguage: string) {\n this._currentLanguage = currentLanguage;\n this.moment.locale(currentLanguage);\n if (this._numberFormatService && this._numberFormatService.numeral) {\n this._numberFormatService.numeral.locale(currentLanguage);\n }\n if (this._translateService) {\n this._translateService.use(currentLanguage);\n }\n }\n\n public getMoment(): typeof moment {\n return this._moment;\n }\n\n public setLanguage(language: string): void {\n this.currentLanguage = language;\n }\n\n public addLanguage(language: string, lang: Object): void {\n if (this._translateService) {\n this._translateService.setTranslation(language, lang, true);\n }\n }\n\n public setDefaultLanguage(language: string): void {\n this.moment.locale(language);\n if (this._numberFormatService && this._numberFormatService.numeral) {\n this._numberFormatService.numeral.locale(language);\n }\n if (this._translateService) {\n this._translateService.setDefaultLang(language);\n this._translateService.use(language);\n }\n }\n}\n","<div\nclass=\"fut-calendar\"\n[class.disabled]=\"isDisabled()\">\n <div class=\"date-header\">\n <div\n class=\"selected-year theme-bg theme-bg-hover\"\n [class.hidden]=\"editedSection === 'year' || (editedSection === 'day' && isOneLineHeader())\">\n <span\n class=\"prev-year arrow-left theme-bg theme-hover futi-dropdown-left\"\n [class.disabled]=\"prevYearDisabled\"\n (click)=\"prevYear($event)\"></span>\n <span\n class=\"selected-label theme-bg theme-hover\"\n (click)=\"switchToYear()\">{{displayedDate.getFullYear()}}</span>\n <span\n class=\"next-year arrow-right theme-bg theme-hover futi-dropdown-right\"\n [class.disabled]=\"nextYearDisabled\"\n (click)=\"nextYear($event)\"></span>\n </div>\n <div\n class=\"selected-month\"\n [class.hidden]=\"editedSection !== 'week' && editedSection !== 'day'\">\n <span\n class=\"prev-month arrow-left theme-hover futi-dropdown-left\"\n [class.disabled]=\"prevMonthDisabled\"\n (click)=\"prevMonth($event)\"></span>\n <span\n class=\"selected-label theme-hover\"\n (click)=\"switchToMonth()\"\n *ngIf=\"!isOneLineHeader()\">{{localeService.moment(displayedDate).format('MMMM')}}</span>\n <span\n class=\"selected-label theme-hover\"\n (click)=\"switchToMonth()\"\n *ngIf=\"isOneLineHeader()\">{{localeService.moment(displayedDate).format('MMMM')}} {{localeService.moment(displayedDate).format('YYYY')}}</span>\n <span\n class=\"next-month arrow-right theme-hover futi-dropdown-right\"\n [class.disabled]=\"nextMonthDisabled\"\n (click)=\"nextMonth($event)\"></span>\n </div>\n </div>\n <div class=\"date-container\">\n <div\n class=\"year-selection\"\n [class.hidden]=\"editedSection !== 'year'\">\n <div class=\"year-interval\">\n <span\n class=\"arrow-left futi-dropdown-left prev-year-page theme-hover\"\n [class.disabled]=\"prevYearPageDisabled\"\n (click)=\"constructInterval(years[0], false)\"></span>\n <div class=\"interval-label\">{{years[0]}} - {{years[11]}}</div>\n <span\n class=\"arrow-right futi-dropdown-right next-year-page theme-hover\"\n [class.disabled]=\"nextYearPageDisabled\"\n (click)=\"constructInterval(years[10], true)\"></span>\n </div>\n <div class=\"years\">\n <div\n class=\"year-item theme-bg-hover\"\n [class.today]=\"isYearToday(i)\"\n [class.theme-bg.theme-bg-hover]=\"isYearSelected(i)\"\n [class.disabled]=\"year < startDateYear || year > endDateYear\"\n (click)=\"selectYear(i)\"\n *ngFor=\"let year of years; let i=index\">\n <span>{{year}}</span>\n </div>\n </div>\n </div>\n <div\n class=\"month-selection\"\n [class.hidden]=\"editedSection !== 'month' && editedSection !== 'quarter'\">\n <div\n class=\"months\"\n [class.disabled]=\"editedSection === 'quarter'\">\n <div\n class=\"month-item theme-bg-hover\"\n [class.today]=\"isMonthToday(monthIndex)\"\n [class.theme-bg.theme-bg-hover]=\"isMonthSelected(monthIndex) || isMonthRanged(monthIndex)\"\n [class.range-start]=\"isRanged() && isMonthSelected(monthIndex)\"\n [class.range-end]=\"isRanged() && isMonthRanged(monthIndex)\"\n [class.theme-highlight]=\"isMonthInRange(monthIndex)\"\n [class.disabled]=\"isItemDisabled(displayedDate.getFullYear(), monthIndex)\"\n (mouseover)=\"hoverMonth(monthIndex)\"\n (mouseout)=\"outMonth()\"\n (click)=\"selectMonth(monthIndex)\"\n *ngFor=\"let month of localeService.moment.monthsShort(); let monthIndex = index\">\n <span>{{month}}</span>\n </div>\n </div>\n <div\n class=\"quarters\"\n [class.disabled]=\"editedSection === 'month'\"\n *ngIf=\"isQuarterDisplayed()\">\n <div\n class=\"quarter-item theme-bg-hover\"\n [class.theme-bg.theme-bg-hover]=\"isCurrentYearDisplayed && quarterIndex === getSelectedQuarter()\"\n [class.disabled]=\"isItemDisabled(displayedDate.getFullYear(), (quarterIndex-1)*3)\"\n (click)=\"selectMonth((quarterIndex-1)*3)\"\n *ngFor=\"let quarterIndex of quarters\">\n <span>Q{{quarterIndex}}</span>\n </div>\n </div>\n </div>\n <div\n class=\"week-selection\"\n [class.hidden]=\"editedSection !== 'week'\">\n <div class=\"days\">\n <div\n class=\"day-label\"\n *ngFor=\"let weekDay of weekDays\">\n <span>{{localeService.moment.weekdaysShort(weekDay)}}</span>\n </div>\n </div>\n <div class=\"days\">\n <div\n class=\"day-label\"\n *ngFor=\"let foo of dummyDays\">\n <span></span>\n </div>\n <div\n class=\"day-item theme-bg-hover\"\n [class.today]=\"isDayToday(dayIndex)\"\n [class.theme-bg.theme-bg-hover]=\"isDaySelected(dayIndex) || isDayRanged(dayIndex)\"\n [class.range-start]=\"isRanged() && isDaySelected(dayIndex)\"\n [class.range-end]=\"isRanged() && isDayRanged(dayIndex)\"\n [class.theme-hover-highlight]=\"hoverWeek(dayIndex)\"\n [class.theme-highlight]=\"isDayInRange(dayIndex)\"\n [class.disabled]=\"isItemDisabled(displayedDate.getFullYear(), displayedDate.getMonth(), dayIndex)\"\n (mouseover)=\"hoverDay(dayIndex, true)\"\n (mouseout)=\"outDay()\"\n (click)=\"selectWeek(dayIndex)\"\n *ngFor=\"let dayIndex of daysInMonth\">\n <span>{{dayIndex}}</span>\n </div>\n </div>\n </div>\n <div\n class=\"day-selection\"\n [class.hidden]=\"editedSection !== 'day'\">\n <div class=\"days\">\n <div\n class=\"day-label\"\n *ngFor=\"let weekDay of weekDays\">\n <span>{{localeService.moment.weekdaysShort(weekDay)}}</span>\n </div>\n </div>\n <div class=\"days\">\n <div\n class=\"day-label\"\n *ngFor=\"let foo of dummyDays\">\n <span></span>\n </div>\n <div\n class=\"day-item theme-bg-hover\"\n [class.today]=\"isDayToday(dayIndex)\"\n [class.theme-bg.theme-bg-hover]=\"isDaySelected(dayIndex) || isDayRanged(dayIndex)\"\n [class.range-start]=\"isRanged() && isDaySelected(dayIndex)\"\n [class.range-end]=\"isRanged() && isDayRanged(dayIndex)\"\n [class.theme-highlight]=\"isDayInRange(dayIndex)\"\n [class.disabled]=\"isItemDisabled(displayedDate.getFullYear(), displayedDate.getMonth(), dayIndex)\"\n (mouseover)=\"hoverDay(dayIndex)\"\n (mouseout)=\"outDay()\"\n (click)=\"selectDay(dayIndex)\"\n *ngFor=\"let dayIndex of daysInMonth\">\n <span>{{dayIndex}}</span>\n </div>\n </div>\n </div>\n </div>\n</div>\n","import { Component, Input, Output, EventEmitter, SimpleChanges, ChangeDetectorRef, AfterViewInit, OnChanges } from '@angular/core';\n\nimport { ChangesUtil } from '../../utils/changes/changes.util';\nimport { LocaleService } from '../../services/locale/locale.service';\nimport { DefaultValues, HtmlInput } from '../../typings';\n\n/* eslint-disable @typescript-eslint/naming-convention */\nexport enum DateFormat {\n YEAR = 'year',\n QUARTER = 'quarter',\n MONTH = 'month',\n WEEK = 'week',\n DAY = 'day'\n}\n/* eslint-enable */\n\nexport interface MonthFormat {\n shortLabel: string;\n longLabel: string;\n}\n\n@Component({\n selector: 'fut-calendar',\n templateUrl: './calendar.component.html',\n styleUrls: ['./calendar.component.scss']\n})\nexport class CalendarComponent implements AfterViewInit, OnChanges {\n /* Angular inputs\n =================*/\n @Input() currentDate: Date;\n @Input() rangedDate: Date;\n @Input() dateFormat: DateFormat = DateFormat.MONTH;\n @Input() emitFormat: string;\n @Input() endDate: Date = new Date(9999, 11, 31, 0, 0, 0, 0);\n @Input() startDate: Date = new Date(1970, 0, 1, 0, 0, 0, 0);\n\n /* HTML inputs\n =================*/\n @Input() disabled: HtmlInput;\n @Input() displayQuarters: HtmlInput;\n @Input() emptyByDefault: HtmlInput;\n @Input() oneLineHeader: HtmlInput;\n @Input() ranged: HtmlInput;\n @Input() highlightToday: HtmlInput;\n\n @Output() currentDateChange: EventEmitter<Date> = new EventEmitter();\n @Output() rangedDateChange: EventEmitter<Date> = new EventEmitter();\n @Output() displayedDateChange: EventEmitter<Date> = new EventEmitter();\n @Output() formattedDateChange: EventEmitter<string> = new EventEmitter();\n\n public isRangedSelectionActive: boolean = false;\n\n public editedSection: DateFormat = DateFormat.MONTH;\n\n public years: number[] = [];\n public weekDays: number[] = [1, 2, 3, 4, 5, 6, 7];\n\n public today: Date = new Date();\n public displayedDate: Date = new Date();\n public firstDayOfMonth: Date;\n public quarters: number[] = [1, 2, 3, 4];\n public daysInMonth: number[];\n public dummyDays: unknown[];\n public startDateYear: number;\n public endDateYear: number;\n public isCurrentYearDisplayed: boolean;\n public isCurrentMonthDisplayed: boolean;\n public prevYearPageDisabled: boolean = true;\n public nextYearPageDisabled: boolean = true;\n public prevYearDisabled: boolean = true;\n public nextYearDisabled: boolean = true;\n public prevMonthDisabled: boolean = true;\n public nextMonthDisabled: boolean = true;\n\n public hoveredDate: Date;\n\n protected _emptyByDefault: boolean = false;\n\n private _defaultValues: DefaultValues = {\n currentDate: new Date(),\n dateFormat: DateFormat.MONTH,\n endDate: new Date(9999, 11, 31, 0, 0, 0, 0),\n startDate: new Date(1970, 0, 1, 0, 0, 0, 0)\n };\n\n constructor(\n public localeService: LocaleService,\n protected _changeDetector: ChangeDetectorRef\n ) {\n const date: Date = new Date();\n this.firstDayOfMonth = new Date(date.getFullYear(), date.getMonth(), 1);\n }\n\n ngOnInit(): void {\n ChangesUtil.resetWrongInputs({}, this._defaultValues, this);\n }\n\n ngAfterViewInit(): void {\n if (!this.isEmptyByDefault && !this.currentDate) {\n this.currentDate = new Date();\n }\n if (!this.isEmptyByDefault && !this.rangedDate) {\n this.rangedDate = new Date();\n }\n if (this.currentDate) {\n const currYear: number = this.currentDate.getFullYear();\n const beginIntervalle: number = currYear - (currYear % 10);\n this.constructInterval(beginIntervalle, true);\n }\n this._changeDetector.detectChanges();\n }\n\n ngOnChanges(changes: SimpleChanges): void {\n ChangesUtil.resetWrongInputs(changes, this._defaultValues, this);\n if (changes.dateFormat) {\n this.editedSection = this.dateFormat;\n }\n if (changes.currentDate) {\n this.displayedDate = new Date(this.currentDate.getTime());\n this.editedSection = this.dateFormat;\n }\n if (changes.startDate && changes.startDate.currentValue) {\n this.startDateYear = this.startDate.getFullYear();\n }\n if (changes.endDate && changes.endDate.currentValue) {\n this.endDateYear = this.endDate.getFullYear();\n }\n if (changes.currentDate || changes.startDate || changes.endDate) {\n const currYear: number = this.currentDate.getFullYear();\n const beginIntervalle: number = currYear - (currYear % 10);\n this.constructInterval(