sp-combo
Version:
# Angular sp-combo - Multiselect, Multiline and Autocomplete
1,700 lines (1,688 loc) • 110 kB
JavaScript
import { ɵɵdefineInjectable, Injectable, EventEmitter, Component, forwardRef, Input, Output, ChangeDetectionStrategy, ViewEncapsulation, Renderer2, NgZone, ElementRef, Optional, Inject, ViewChild, HostListener, Directive, TemplateRef, InjectionToken, Attribute, ChangeDetectorRef, HostBinding, ContentChild, ContentChildren, NgModule, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';
import { DOCUMENT, CommonModule } from '@angular/common';
import { animationFrameScheduler, asapScheduler, Subject, fromEvent, merge } from 'rxjs';
import { takeUntil, auditTime, startWith, tap, debounceTime, filter, map } from 'rxjs/operators';
class SpComboService {
constructor() { }
}
SpComboService.ɵprov = ɵɵdefineInjectable({ factory: function SpComboService_Factory() { return new SpComboService(); }, token: SpComboService, providedIn: "root" });
SpComboService.decorators = [
{ type: Injectable, args: [{
providedIn: 'root'
},] }
];
SpComboService.ctorParameters = () => [];
const noop = () => { };
const ɵ0 = noop;
class SpComboComponent {
constructor() {
this.isDisabled = false;
this.isMultiSelect = false;
this.isLoading = false;
this.closeOnSelect = true;
this.isSelectByGroup = false;
this.isSelectByGroupAsModel = false;
this.selectedRow = new EventEmitter();
this.changeFn = new EventEmitter();
this.blurFn = new EventEmitter();
this.focusFn = new EventEmitter();
this.extraLbl = [];
this.extraVal = [];
this.searchFild = [];
//The internal data model
this.innerValue = "";
//Placeholders for the callbacks which are later provided
//by the Control Value Accessor
this.onTouchedCallback = noop;
this.onChangeCallback = noop;
}
//get accessor
get value() { return this.innerValue; }
//set accessor including call the onchange callback
set value(v) {
if (v !== this.innerValue) {
this.innerValue = v;
this.onChangeCallback(v);
}
}
//Set touched on blur
onBlur() {
this.onTouchedCallback();
if (this.blurFn != null)
this.blurFn.emit();
}
//From ControlValueAccessor interface
writeValue(value) {
if (value !== this.innerValue) {
this.innerValue = value;
}
}
//From ControlValueAccessor interface
registerOnChange(fn) {
this.onChangeCallback = fn;
}
//From ControlValueAccessor interface
registerOnTouched(fn) {
this.onTouchedCallback = fn;
}
onChange($event) {
// this.selectedRow.emit($event);
this.selectedRow.emit($event);
if (this.changeFn != null)
this.changeFn.emit();
}
findExtra(term, lst) {
this.searchFild.forEach(itm => {
return lst[itm].toLowerCase().indexOf(term) > -1;
});
}
onSearch(trm, lst, a) {
// var term = trm.term.toLowerCase();
// return (
// this.displayList[this.displayField].toLowerCase().indexOf(term) > -1 ||
// this.findExtra(term)
// );
// this.ab = this.searchFild[0];
// return this.displayList[this.displayField].toLowerCase().indexOf(term) > -1 || this.displayList[this.ab].toLowerCase().indexOf(term) > -1 ;
// var ac = this.displayList[this.displayField];
// var vd = this.displayList[this.ab];
// return this.displayList[this.displayField].toLowerCase().indexOf(term) > -1 ;
// return this.displayList[this.ab].toLowerCase().indexOf(term) > -1 ;
// this.displayList.forEach(lst => {
// var m = lst[this.ab].toLowerCase().indexOf(term);
// return lst[this.ab].toLowerCase().indexOf(term) > -1;
// });
var term = trm.toLowerCase();
// return ( lst[this.displayField].toLowerCase().indexOf(term) > -1 || this.findExtra(term, lst) );
// return (
// lst[this.displayField].toLowerCase().indexOf(term) > -1 ||
// lst[this.searchFields].toLowerCase().indexOf(term) > -1
// );
}
onFocus(fn) {
if (this.focusFn != null)
this.focusFn.emit();
}
selectAll() {
this.value = this.displayList.map(x => x[this.selectedValue]);
}
unselectAll() {
this.value = [];
}
ngOnInit() {
if (this.extraValues)
this.extraVal = this.extraValues.split(",");
if (this.extraLables)
this.extraLbl = this.extraLables.split(",");
}
ngOnChanges(changes) {
if (!this.placeHolder)
this.placeHolder = "";
if (this.extraValues)
this.extraVal = this.extraValues.split(",");
if (this.extraLables)
this.extraLbl = this.extraLables.split(",");
}
getExtraValue(item, idx) {
if (this.extraVal.length > idx) {
var ef = this.extraVal[idx].split(".");
var val = item;
var id = 0;
for (var a of ef) {
val = val[a];
id += 1;
if (id == ef.length) {
return val;
}
}
}
else {
return item;
}
}
}
SpComboComponent.decorators = [
{ type: Component, args: [{
selector: 'sp-combo',
template: "<sp-select [placeholder]=\"placeHolder\" [items]=\"displayList\" [bindLabel]=\"displayField\" [bindValue]=\"selectedValue\"\r\n [(ngModel)]=\"value\" (change)=\"onChange($event)\" (blur)=\"onBlur()\" [multiple]=\"isMultiSelect\" [loading]=\"isLoading\"\r\n [groupBy]=\"groupBy\" [closeOnSelect]=\"closeOnSelect\" [selectableGroup]=\"isSelectByGroup\" [disabled]=\"isDisabled\"\r\n [selectableGroupAsModel]=\"isSelectByGroupAsModel\" (focus)=\"onFocus($event)\">\r\n\r\n <ng-template ng-optgroup-tmp let-item=\"item\" *ngIf=\"groupBy!=null && groupBy!=undefined\">\r\n {{item[groupBy] | uppercase}}\r\n <!-- {{item[groupBy] }} -->\r\n </ng-template>\r\n\r\n <ng-template ng-option-tmp let-item=\"item\">\r\n {{item[displayField]}} <br />\r\n\r\n <small *ngFor=\"let lbl of extraLbl; let i = index; let last = last;\">\r\n\r\n {{lbl}} :{{ getExtraValue(item,i) }}\r\n\r\n <span *ngIf=\"!last\">, </span>\r\n </small>\r\n\r\n <ng-template ng-header-tmp *ngIf=\"isMultiSelect==true\">\r\n <button (click)=\"selectAll()\" class=\"btn btn-sm btn-secondary\">Select all</button>\r\n <button (click)=\"unselectAll()\" class=\"btn btn-sm btn-secondary\">Unselect all</button>\r\n </ng-template>\r\n\r\n <ng-template ng-footer-tmp *ngIf=\"isMultiSelect && value!=undefined\">\r\n Selected Count: {{value.length}}\r\n </ng-template>\r\n\r\n </ng-template>\r\n\r\n</sp-select>\r\n\r\n",
providers: [
{
provide: NG_VALUE_ACCESSOR,
useExisting: forwardRef(() => SpComboComponent),
multi: true
}
]
},] }
];
SpComboComponent.ctorParameters = () => [];
SpComboComponent.propDecorators = {
placeHolder: [{ type: Input }],
displayList: [{ type: Input }],
displayField: [{ type: Input }],
selectedValue: [{ type: Input }],
extraLables: [{ type: Input }],
extraValues: [{ type: Input }],
isDisabled: [{ type: Input }],
isMultiSelect: [{ type: Input }],
isLoading: [{ type: Input }],
groupBy: [{ type: Input }],
closeOnSelect: [{ type: Input }],
isSelectByGroup: [{ type: Input }],
isSelectByGroupAsModel: [{ type: Input }],
selectedRow: [{ type: Output }],
changeFn: [{ type: Output }],
blurFn: [{ type: Output }],
focusFn: [{ type: Output }]
};
class NgDropdownPanelService {
constructor() {
this._dimensions = {
itemHeight: 0,
panelHeight: 0,
itemsPerViewport: 0
};
}
get dimensions() {
return this._dimensions;
}
calculateItems(scrollPos, itemsLength, buffer) {
const d = this._dimensions;
const scrollHeight = d.itemHeight * itemsLength;
const scrollTop = Math.max(0, scrollPos);
const indexByScrollTop = scrollTop / scrollHeight * itemsLength;
let end = Math.min(itemsLength, Math.ceil(indexByScrollTop) + (d.itemsPerViewport + 1));
const maxStartEnd = end;
const maxStart = Math.max(0, maxStartEnd - d.itemsPerViewport);
let start = Math.min(maxStart, Math.floor(indexByScrollTop));
let topPadding = d.itemHeight * Math.ceil(start) - (d.itemHeight * Math.min(start, buffer));
topPadding = !isNaN(topPadding) ? topPadding : 0;
start = !isNaN(start) ? start : -1;
end = !isNaN(end) ? end : -1;
start -= buffer;
start = Math.max(0, start);
end += buffer;
end = Math.min(itemsLength, end);
return {
topPadding,
scrollHeight,
start,
end
};
}
setDimensions(itemHeight, panelHeight) {
const itemsPerViewport = Math.max(1, Math.floor(panelHeight / itemHeight));
this._dimensions = {
itemHeight,
panelHeight,
itemsPerViewport
};
}
getScrollTo(itemTop, itemHeight, lastScroll) {
const { panelHeight } = this.dimensions;
const itemBottom = itemTop + itemHeight;
const top = lastScroll;
const bottom = top + panelHeight;
if (panelHeight >= itemBottom && lastScroll === itemTop) {
return null;
}
if (itemBottom > bottom) {
return top + itemBottom - bottom;
}
else if (itemTop <= top) {
return itemTop;
}
return null;
}
}
NgDropdownPanelService.decorators = [
{ type: Injectable }
];
const unescapedHTMLExp = /[&<>"']/g;
const hasUnescapedHTMLExp = RegExp(unescapedHTMLExp.source);
const htmlEscapes = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
'\'': '''
};
function escapeHTML(string) {
return (string && hasUnescapedHTMLExp.test(string)) ?
string.replace(unescapedHTMLExp, chr => htmlEscapes[chr]) :
string;
}
function isDefined(value) {
return value !== undefined && value !== null;
}
function isObject(value) {
return typeof value === 'object' && isDefined(value);
}
function isPromise(value) {
return value instanceof Promise;
}
function isFunction(value) {
return value instanceof Function;
}
const TOP_CSS_CLASS = 'ng-select-top';
const BOTTOM_CSS_CLASS = 'ng-select-bottom';
const SCROLL_SCHEDULER = typeof requestAnimationFrame !== 'undefined' ? animationFrameScheduler : asapScheduler;
class NgDropdownPanelComponent {
constructor(_renderer, _zone, _panelService, _elementRef, _document) {
this._renderer = _renderer;
this._zone = _zone;
this._panelService = _panelService;
this._document = _document;
this.items = [];
this.position = 'auto';
this.virtualScroll = false;
this.filterValue = null;
this.update = new EventEmitter();
this.scroll = new EventEmitter();
this.scrollToEnd = new EventEmitter();
this.outsideClick = new EventEmitter();
this._destroy$ = new Subject();
this._scrollToEndFired = false;
this._updateScrollHeight = false;
this._lastScrollPosition = 0;
this._dropdown = _elementRef.nativeElement;
}
get currentPosition() {
return this._currentPosition;
}
get itemsLength() {
return this._itemsLength;
}
set itemsLength(value) {
if (value !== this._itemsLength) {
this._itemsLength = value;
this._onItemsLengthChanged();
}
}
get _startOffset() {
if (this.markedItem) {
const { itemHeight, panelHeight } = this._panelService.dimensions;
const offset = this.markedItem.index * itemHeight;
return panelHeight > offset ? 0 : offset;
}
return 0;
}
handleMousedown($event) {
const target = $event.target;
if (target.tagName === 'INPUT') {
return;
}
$event.preventDefault();
}
ngOnInit() {
this._select = this._dropdown.parentElement;
this._virtualPadding = this.paddingElementRef.nativeElement;
this._scrollablePanel = this.scrollElementRef.nativeElement;
this._contentPanel = this.contentElementRef.nativeElement;
this._handleScroll();
this._handleOutsideClick();
this._appendDropdown();
}
ngOnChanges(changes) {
if (changes.items) {
const change = changes.items;
this._onItemsChange(change.currentValue, change.firstChange);
}
}
ngOnDestroy() {
this._destroy$.next();
this._destroy$.complete();
this._destroy$.unsubscribe();
if (this.appendTo) {
this._renderer.removeChild(this._dropdown.parentNode, this._dropdown);
}
}
scrollTo(option, startFromOption = false) {
if (!option) {
return;
}
const index = this.items.indexOf(option);
if (index < 0 || index >= this.itemsLength) {
return;
}
let scrollTo;
if (this.virtualScroll) {
const itemHeight = this._panelService.dimensions.itemHeight;
scrollTo = this._panelService.getScrollTo(index * itemHeight, itemHeight, this._lastScrollPosition);
}
else {
const item = this._dropdown.querySelector(`#${option.htmlId}`);
const lastScroll = startFromOption ? item.offsetTop : this._lastScrollPosition;
scrollTo = this._panelService.getScrollTo(item.offsetTop, item.clientHeight, lastScroll);
}
if (isDefined(scrollTo)) {
this._scrollablePanel.scrollTop = scrollTo;
}
}
scrollToTag() {
const panel = this._scrollablePanel;
panel.scrollTop = panel.scrollHeight - panel.clientHeight;
}
adjustPosition() {
const parent = this._parent.getBoundingClientRect();
const select = this._select.getBoundingClientRect();
this._setOffset(parent, select);
}
_handleDropdownPosition() {
this._currentPosition = this._calculateCurrentPosition(this._dropdown);
if (this._currentPosition === 'top') {
this._renderer.addClass(this._dropdown, TOP_CSS_CLASS);
this._renderer.removeClass(this._dropdown, BOTTOM_CSS_CLASS);
this._renderer.addClass(this._select, TOP_CSS_CLASS);
this._renderer.removeClass(this._select, BOTTOM_CSS_CLASS);
}
else {
this._renderer.addClass(this._dropdown, BOTTOM_CSS_CLASS);
this._renderer.removeClass(this._dropdown, TOP_CSS_CLASS);
this._renderer.addClass(this._select, BOTTOM_CSS_CLASS);
this._renderer.removeClass(this._select, TOP_CSS_CLASS);
}
if (this.appendTo) {
this._updatePosition();
}
this._dropdown.style.opacity = '1';
}
_handleScroll() {
this._zone.runOutsideAngular(() => {
fromEvent(this.scrollElementRef.nativeElement, 'scroll')
.pipe(takeUntil(this._destroy$), auditTime(0, SCROLL_SCHEDULER))
.subscribe((e) => this._onContentScrolled(e.target.scrollTop));
});
}
_handleOutsideClick() {
if (!this._document) {
return;
}
this._zone.runOutsideAngular(() => {
merge(fromEvent(this._document, 'touchstart', { capture: true }), fromEvent(this._document, 'mousedown', { capture: true })).pipe(takeUntil(this._destroy$))
.subscribe($event => this._checkToClose($event));
});
}
_checkToClose($event) {
if (this._select.contains($event.target) || this._dropdown.contains($event.target)) {
return;
}
const path = $event.path || ($event.composedPath && $event.composedPath());
if ($event.target && $event.target.shadowRoot && path && path[0] && this._select.contains(path[0])) {
return;
}
this._zone.run(() => this.outsideClick.emit());
}
_onItemsChange(items, firstChange) {
this.items = items || [];
this._scrollToEndFired = false;
this.itemsLength = items.length;
if (this.virtualScroll) {
this._updateItemsRange(firstChange);
}
else {
this._updateItems(firstChange);
}
}
_updateItems(firstChange) {
this.update.emit(this.items);
if (firstChange === false) {
return;
}
this._zone.runOutsideAngular(() => {
Promise.resolve().then(() => {
const panelHeight = this._scrollablePanel.clientHeight;
this._panelService.setDimensions(0, panelHeight);
this._handleDropdownPosition();
this.scrollTo(this.markedItem, firstChange);
});
});
}
_updateItemsRange(firstChange) {
this._zone.runOutsideAngular(() => {
this._measureDimensions().then(() => {
if (firstChange) {
this._renderItemsRange(this._startOffset);
this._handleDropdownPosition();
}
else {
this._renderItemsRange();
}
});
});
}
_onContentScrolled(scrollTop) {
if (this.virtualScroll) {
this._renderItemsRange(scrollTop);
}
this._lastScrollPosition = scrollTop;
this._fireScrollToEnd(scrollTop);
}
_updateVirtualHeight(height) {
if (this._updateScrollHeight) {
this._virtualPadding.style.height = `${height}px`;
this._updateScrollHeight = false;
}
}
_onItemsLengthChanged() {
this._updateScrollHeight = true;
}
_renderItemsRange(scrollTop = null) {
if (scrollTop && this._lastScrollPosition === scrollTop) {
return;
}
scrollTop = scrollTop || this._scrollablePanel.scrollTop;
const range = this._panelService.calculateItems(scrollTop, this.itemsLength, this.bufferAmount);
this._updateVirtualHeight(range.scrollHeight);
this._contentPanel.style.transform = `translateY(${range.topPadding}px)`;
this._zone.run(() => {
this.update.emit(this.items.slice(range.start, range.end));
this.scroll.emit({ start: range.start, end: range.end });
});
if (isDefined(scrollTop) && this._lastScrollPosition === 0) {
this._scrollablePanel.scrollTop = scrollTop;
this._lastScrollPosition = scrollTop;
}
}
_measureDimensions() {
if (this._panelService.dimensions.itemHeight > 0 || this.itemsLength === 0) {
return Promise.resolve(this._panelService.dimensions);
}
const [first] = this.items;
this.update.emit([first]);
return Promise.resolve().then(() => {
const option = this._dropdown.querySelector(`#${first.htmlId}`);
const optionHeight = option.clientHeight;
this._virtualPadding.style.height = `${optionHeight * this.itemsLength}px`;
const panelHeight = this._scrollablePanel.clientHeight;
this._panelService.setDimensions(optionHeight, panelHeight);
return this._panelService.dimensions;
});
}
_fireScrollToEnd(scrollTop) {
if (this._scrollToEndFired || scrollTop === 0) {
return;
}
const padding = this.virtualScroll ?
this._virtualPadding :
this._contentPanel;
if (scrollTop + this._dropdown.clientHeight >= padding.clientHeight) {
this._zone.run(() => this.scrollToEnd.emit());
this._scrollToEndFired = true;
}
}
_calculateCurrentPosition(dropdownEl) {
if (this.position !== 'auto') {
return this.position;
}
const selectRect = this._select.getBoundingClientRect();
const scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
const offsetTop = selectRect.top + window.pageYOffset;
const height = selectRect.height;
const dropdownHeight = dropdownEl.getBoundingClientRect().height;
if (offsetTop + height + dropdownHeight > scrollTop + document.documentElement.clientHeight) {
return 'top';
}
else {
return 'bottom';
}
}
_appendDropdown() {
if (!this.appendTo) {
return;
}
this._parent = document.querySelector(this.appendTo);
if (!parent) {
throw new Error(`appendTo selector ${this.appendTo} did not found any parent element`);
}
this._parent.appendChild(this._dropdown);
}
_updatePosition() {
const select = this._select.getBoundingClientRect();
const parent = this._parent.getBoundingClientRect();
const offsetLeft = select.left - parent.left;
this._setOffset(parent, select);
this._dropdown.style.left = offsetLeft + 'px';
this._dropdown.style.width = select.width + 'px';
this._dropdown.style.minWidth = select.width + 'px';
}
_setOffset(parent, select) {
const delta = select.height;
if (this._currentPosition === 'top') {
const offsetBottom = parent.bottom - select.bottom;
this._dropdown.style.bottom = offsetBottom + delta + 'px';
this._dropdown.style.top = 'auto';
}
else if (this._currentPosition === 'bottom') {
const offsetTop = select.top - parent.top;
this._dropdown.style.top = offsetTop + delta + 'px';
this._dropdown.style.bottom = 'auto';
}
}
}
NgDropdownPanelComponent.decorators = [
{ type: Component, args: [{
changeDetection: ChangeDetectionStrategy.OnPush,
encapsulation: ViewEncapsulation.None,
selector: 'ng-dropdown-panel',
template: `
<div *ngIf="headerTemplate" class="ng-dropdown-header">
<ng-container [ngTemplateOutlet]="headerTemplate" [ngTemplateOutletContext]="{ searchTerm: filterValue }"></ng-container>
</div>
<div #scroll class="ng-dropdown-panel-items scroll-host">
<div #padding [class.total-padding]="virtualScroll"></div>
<div #content [class.scrollable-content]="virtualScroll && items.length">
<ng-content></ng-content>
</div>
</div>
<div *ngIf="footerTemplate" class="ng-dropdown-footer">
<ng-container [ngTemplateOutlet]="footerTemplate" [ngTemplateOutletContext]="{ searchTerm: filterValue }"></ng-container>
</div>
`
},] }
];
NgDropdownPanelComponent.ctorParameters = () => [
{ type: Renderer2 },
{ type: NgZone },
{ type: NgDropdownPanelService },
{ type: ElementRef },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] }
];
NgDropdownPanelComponent.propDecorators = {
items: [{ type: Input }],
markedItem: [{ type: Input }],
position: [{ type: Input }],
appendTo: [{ type: Input }],
bufferAmount: [{ type: Input }],
virtualScroll: [{ type: Input }],
headerTemplate: [{ type: Input }],
footerTemplate: [{ type: Input }],
filterValue: [{ type: Input }],
update: [{ type: Output }],
scroll: [{ type: Output }],
scrollToEnd: [{ type: Output }],
outsideClick: [{ type: Output }],
contentElementRef: [{ type: ViewChild, args: ['content', { read: ElementRef, static: true },] }],
scrollElementRef: [{ type: ViewChild, args: ['scroll', { read: ElementRef, static: true },] }],
paddingElementRef: [{ type: ViewChild, args: ['padding', { read: ElementRef, static: true },] }],
handleMousedown: [{ type: HostListener, args: ['mousedown', ['$event'],] }]
};
class NgOptionComponent {
constructor(elementRef) {
this.elementRef = elementRef;
this.stateChange$ = new Subject();
this._disabled = false;
}
get disabled() { return this._disabled; }
set disabled(value) { this._disabled = this._isDisabled(value); }
get label() {
return (this.elementRef.nativeElement.textContent || '').trim();
}
ngOnChanges(changes) {
if (changes.disabled) {
this.stateChange$.next({
value: this.value,
disabled: this._disabled
});
}
}
ngAfterViewChecked() {
if (this.label !== this._previousLabel) {
this._previousLabel = this.label;
this.stateChange$.next({
value: this.value,
disabled: this._disabled,
label: this.elementRef.nativeElement.innerHTML
});
}
}
ngOnDestroy() {
this.stateChange$.complete();
}
_isDisabled(value) {
return value != null && `${value}` !== 'false';
}
}
NgOptionComponent.decorators = [
{ type: Component, args: [{
selector: 'ng-option',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `<ng-content></ng-content>`
},] }
];
NgOptionComponent.ctorParameters = () => [
{ type: ElementRef }
];
NgOptionComponent.propDecorators = {
value: [{ type: Input }],
disabled: [{ type: Input }]
};
class NgItemLabelDirective {
constructor(element) {
this.element = element;
this.escape = true;
}
ngOnChanges(changes) {
this.element.nativeElement.innerHTML = this.escape ?
escapeHTML(this.ngItemLabel) :
this.ngItemLabel;
}
}
NgItemLabelDirective.decorators = [
{ type: Directive, args: [{ selector: '[ngItemLabel]' },] }
];
NgItemLabelDirective.ctorParameters = () => [
{ type: ElementRef }
];
NgItemLabelDirective.propDecorators = {
ngItemLabel: [{ type: Input }],
escape: [{ type: Input }]
};
class NgOptionTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgOptionTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-option-tmp]' },] }
];
NgOptionTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgOptgroupTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgOptgroupTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-optgroup-tmp]' },] }
];
NgOptgroupTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgLabelTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgLabelTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-label-tmp]' },] }
];
NgLabelTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgMultiLabelTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgMultiLabelTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-multi-label-tmp]' },] }
];
NgMultiLabelTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgHeaderTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgHeaderTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-header-tmp]' },] }
];
NgHeaderTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgFooterTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgFooterTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-footer-tmp]' },] }
];
NgFooterTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgNotFoundTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgNotFoundTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-notfound-tmp]' },] }
];
NgNotFoundTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgTypeToSearchTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgTypeToSearchTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-typetosearch-tmp]' },] }
];
NgTypeToSearchTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgLoadingTextTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgLoadingTextTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-loadingtext-tmp]' },] }
];
NgLoadingTextTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgTagTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgTagTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-tag-tmp]' },] }
];
NgTagTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
class NgLoadingSpinnerTemplateDirective {
constructor(template) {
this.template = template;
}
}
NgLoadingSpinnerTemplateDirective.decorators = [
{ type: Directive, args: [{ selector: '[ng-loadingspinner-tmp]' },] }
];
NgLoadingSpinnerTemplateDirective.ctorParameters = () => [
{ type: TemplateRef }
];
function DefaultSelectionModelFactory() {
return new DefaultSelectionModel();
}
class DefaultSelectionModel {
constructor() {
this._selected = [];
}
get value() {
return this._selected;
}
select(item, multiple, groupAsModel) {
item.selected = true;
if (!item.children || (!multiple && groupAsModel)) {
this._selected.push(item);
}
if (multiple) {
if (item.parent) {
const childrenCount = item.parent.children.length;
const selectedCount = item.parent.children.filter(x => x.selected).length;
item.parent.selected = childrenCount === selectedCount;
}
else if (item.children) {
this._setChildrenSelectedState(item.children, true);
this._removeChildren(item);
if (groupAsModel && this._activeChildren(item)) {
this._selected = [...this._selected.filter(x => x.parent !== item), item];
}
else {
this._selected = [...this._selected, ...item.children.filter(x => !x.disabled)];
}
}
}
}
unselect(item, multiple) {
this._selected = this._selected.filter(x => x !== item);
item.selected = false;
if (multiple) {
if (item.parent && item.parent.selected) {
const children = item.parent.children;
this._removeParent(item.parent);
this._removeChildren(item.parent);
this._selected.push(...children.filter(x => x !== item && !x.disabled));
item.parent.selected = false;
}
else if (item.children) {
this._setChildrenSelectedState(item.children, false);
this._removeChildren(item);
}
}
}
clear(keepDisabled) {
this._selected = keepDisabled ? this._selected.filter(x => x.disabled) : [];
}
_setChildrenSelectedState(children, selected) {
for (const child of children) {
if (child.disabled) {
continue;
}
child.selected = selected;
}
;
}
_removeChildren(parent) {
this._selected = [
...this._selected.filter(x => x.parent !== parent),
...parent.children.filter(x => x.parent === parent && x.disabled && x.selected)
];
}
_removeParent(parent) {
this._selected = this._selected.filter(x => x !== parent);
}
_activeChildren(item) {
return item.children.every(x => !x.disabled || x.selected);
}
}
class ConsoleService {
warn(message) {
console.warn(message);
}
}
ConsoleService.ɵprov = ɵɵdefineInjectable({ factory: function ConsoleService_Factory() { return new ConsoleService(); }, token: ConsoleService, providedIn: "root" });
ConsoleService.decorators = [
{ type: Injectable, args: [{ providedIn: 'root' },] }
];
function newId() {
// First character is an 'a', it's good practice to tag id to begin with a letter
return 'axxxxxxxxxxx'.replace(/[x]/g, function (_) {
// tslint:disable-next-line:no-bitwise
const val = Math.random() * 16 | 0;
return val.toString(16);
});
}
const diacritics = {
'\u24B6': 'A',
'\uFF21': 'A',
'\u00C0': 'A',
'\u00C1': 'A',
'\u00C2': 'A',
'\u1EA6': 'A',
'\u1EA4': 'A',
'\u1EAA': 'A',
'\u1EA8': 'A',
'\u00C3': 'A',
'\u0100': 'A',
'\u0102': 'A',
'\u1EB0': 'A',
'\u1EAE': 'A',
'\u1EB4': 'A',
'\u1EB2': 'A',
'\u0226': 'A',
'\u01E0': 'A',
'\u00C4': 'A',
'\u01DE': 'A',
'\u1EA2': 'A',
'\u00C5': 'A',
'\u01FA': 'A',
'\u01CD': 'A',
'\u0200': 'A',
'\u0202': 'A',
'\u1EA0': 'A',
'\u1EAC': 'A',
'\u1EB6': 'A',
'\u1E00': 'A',
'\u0104': 'A',
'\u023A': 'A',
'\u2C6F': 'A',
'\uA732': 'AA',
'\u00C6': 'AE',
'\u01FC': 'AE',
'\u01E2': 'AE',
'\uA734': 'AO',
'\uA736': 'AU',
'\uA738': 'AV',
'\uA73A': 'AV',
'\uA73C': 'AY',
'\u24B7': 'B',
'\uFF22': 'B',
'\u1E02': 'B',
'\u1E04': 'B',
'\u1E06': 'B',
'\u0243': 'B',
'\u0182': 'B',
'\u0181': 'B',
'\u24B8': 'C',
'\uFF23': 'C',
'\u0106': 'C',
'\u0108': 'C',
'\u010A': 'C',
'\u010C': 'C',
'\u00C7': 'C',
'\u1E08': 'C',
'\u0187': 'C',
'\u023B': 'C',
'\uA73E': 'C',
'\u24B9': 'D',
'\uFF24': 'D',
'\u1E0A': 'D',
'\u010E': 'D',
'\u1E0C': 'D',
'\u1E10': 'D',
'\u1E12': 'D',
'\u1E0E': 'D',
'\u0110': 'D',
'\u018B': 'D',
'\u018A': 'D',
'\u0189': 'D',
'\uA779': 'D',
'\u01F1': 'DZ',
'\u01C4': 'DZ',
'\u01F2': 'Dz',
'\u01C5': 'Dz',
'\u24BA': 'E',
'\uFF25': 'E',
'\u00C8': 'E',
'\u00C9': 'E',
'\u00CA': 'E',
'\u1EC0': 'E',
'\u1EBE': 'E',
'\u1EC4': 'E',
'\u1EC2': 'E',
'\u1EBC': 'E',
'\u0112': 'E',
'\u1E14': 'E',
'\u1E16': 'E',
'\u0114': 'E',
'\u0116': 'E',
'\u00CB': 'E',
'\u1EBA': 'E',
'\u011A': 'E',
'\u0204': 'E',
'\u0206': 'E',
'\u1EB8': 'E',
'\u1EC6': 'E',
'\u0228': 'E',
'\u1E1C': 'E',
'\u0118': 'E',
'\u1E18': 'E',
'\u1E1A': 'E',
'\u0190': 'E',
'\u018E': 'E',
'\u24BB': 'F',
'\uFF26': 'F',
'\u1E1E': 'F',
'\u0191': 'F',
'\uA77B': 'F',
'\u24BC': 'G',
'\uFF27': 'G',
'\u01F4': 'G',
'\u011C': 'G',
'\u1E20': 'G',
'\u011E': 'G',
'\u0120': 'G',
'\u01E6': 'G',
'\u0122': 'G',
'\u01E4': 'G',
'\u0193': 'G',
'\uA7A0': 'G',
'\uA77D': 'G',
'\uA77E': 'G',
'\u24BD': 'H',
'\uFF28': 'H',
'\u0124': 'H',
'\u1E22': 'H',
'\u1E26': 'H',
'\u021E': 'H',
'\u1E24': 'H',
'\u1E28': 'H',
'\u1E2A': 'H',
'\u0126': 'H',
'\u2C67': 'H',
'\u2C75': 'H',
'\uA78D': 'H',
'\u24BE': 'I',
'\uFF29': 'I',
'\u00CC': 'I',
'\u00CD': 'I',
'\u00CE': 'I',
'\u0128': 'I',
'\u012A': 'I',
'\u012C': 'I',
'\u0130': 'I',
'\u00CF': 'I',
'\u1E2E': 'I',
'\u1EC8': 'I',
'\u01CF': 'I',
'\u0208': 'I',
'\u020A': 'I',
'\u1ECA': 'I',
'\u012E': 'I',
'\u1E2C': 'I',
'\u0197': 'I',
'\u24BF': 'J',
'\uFF2A': 'J',
'\u0134': 'J',
'\u0248': 'J',
'\u24C0': 'K',
'\uFF2B': 'K',
'\u1E30': 'K',
'\u01E8': 'K',
'\u1E32': 'K',
'\u0136': 'K',
'\u1E34': 'K',
'\u0198': 'K',
'\u2C69': 'K',
'\uA740': 'K',
'\uA742': 'K',
'\uA744': 'K',
'\uA7A2': 'K',
'\u24C1': 'L',
'\uFF2C': 'L',
'\u013F': 'L',
'\u0139': 'L',
'\u013D': 'L',
'\u1E36': 'L',
'\u1E38': 'L',
'\u013B': 'L',
'\u1E3C': 'L',
'\u1E3A': 'L',
'\u0141': 'L',
'\u023D': 'L',
'\u2C62': 'L',
'\u2C60': 'L',
'\uA748': 'L',
'\uA746': 'L',
'\uA780': 'L',
'\u01C7': 'LJ',
'\u01C8': 'Lj',
'\u24C2': 'M',
'\uFF2D': 'M',
'\u1E3E': 'M',
'\u1E40': 'M',
'\u1E42': 'M',
'\u2C6E': 'M',
'\u019C': 'M',
'\u24C3': 'N',
'\uFF2E': 'N',
'\u01F8': 'N',
'\u0143': 'N',
'\u00D1': 'N',
'\u1E44': 'N',
'\u0147': 'N',
'\u1E46': 'N',
'\u0145': 'N',
'\u1E4A': 'N',
'\u1E48': 'N',
'\u0220': 'N',
'\u019D': 'N',
'\uA790': 'N',
'\uA7A4': 'N',
'\u01CA': 'NJ',
'\u01CB': 'Nj',
'\u24C4': 'O',
'\uFF2F': 'O',
'\u00D2': 'O',
'\u00D3': 'O',
'\u00D4': 'O',
'\u1ED2': 'O',
'\u1ED0': 'O',
'\u1ED6': 'O',
'\u1ED4': 'O',
'\u00D5': 'O',
'\u1E4C': 'O',
'\u022C': 'O',
'\u1E4E': 'O',
'\u014C': 'O',
'\u1E50': 'O',
'\u1E52': 'O',
'\u014E': 'O',
'\u022E': 'O',
'\u0230': 'O',
'\u00D6': 'O',
'\u022A': 'O',
'\u1ECE': 'O',
'\u0150': 'O',
'\u01D1': 'O',
'\u020C': 'O',
'\u020E': 'O',
'\u01A0': 'O',
'\u1EDC': 'O',
'\u1EDA': 'O',
'\u1EE0': 'O',
'\u1EDE': 'O',
'\u1EE2': 'O',
'\u1ECC': 'O',
'\u1ED8': 'O',
'\u01EA': 'O',
'\u01EC': 'O',
'\u00D8': 'O',
'\u01FE': 'O',
'\u0186': 'O',
'\u019F': 'O',
'\uA74A': 'O',
'\uA74C': 'O',
'\u01A2': 'OI',
'\uA74E': 'OO',
'\u0222': 'OU',
'\u24C5': 'P',
'\uFF30': 'P',
'\u1E54': 'P',
'\u1E56': 'P',
'\u01A4': 'P',
'\u2C63': 'P',
'\uA750': 'P',
'\uA752': 'P',
'\uA754': 'P',
'\u24C6': 'Q',
'\uFF31': 'Q',
'\uA756': 'Q',
'\uA758': 'Q',
'\u024A': 'Q',
'\u24C7': 'R',
'\uFF32': 'R',
'\u0154': 'R',
'\u1E58': 'R',
'\u0158': 'R',
'\u0210': 'R',
'\u0212': 'R',
'\u1E5A': 'R',
'\u1E5C': 'R',
'\u0156': 'R',
'\u1E5E': 'R',
'\u024C': 'R',
'\u2C64': 'R',
'\uA75A': 'R',
'\uA7A6': 'R',
'\uA782': 'R',
'\u24C8': 'S',
'\uFF33': 'S',
'\u1E9E': 'S',
'\u015A': 'S',
'\u1E64': 'S',
'\u015C': 'S',
'\u1E60': 'S',
'\u0160': 'S',
'\u1E66': 'S',
'\u1E62': 'S',
'\u1E68': 'S',
'\u0218': 'S',
'\u015E': 'S',
'\u2C7E': 'S',
'\uA7A8': 'S',
'\uA784': 'S',
'\u24C9': 'T',
'\uFF34': 'T',
'\u1E6A': 'T',
'\u0164': 'T',
'\u1E6C': 'T',
'\u021A': 'T',
'\u0162': 'T',
'\u1E70': 'T',
'\u1E6E': 'T',
'\u0166': 'T',
'\u01AC': 'T',
'\u01AE': 'T',
'\u023E': 'T',
'\uA786': 'T',
'\uA728': 'TZ',
'\u24CA': 'U',
'\uFF35': 'U',
'\u00D9': 'U',
'\u00DA': 'U',
'\u00DB': 'U',
'\u0168': 'U',
'\u1E78': 'U',
'\u016A': 'U',
'\u1E7A': 'U',
'\u016C': 'U',
'\u00DC': 'U',
'\u01DB': 'U',
'\u01D7': 'U',
'\u01D5': 'U',
'\u01D9': 'U',
'\u1EE6': 'U',
'\u016E': 'U',
'\u0170': 'U',
'\u01D3': 'U',
'\u0214': 'U',
'\u0216': 'U',
'\u01AF': 'U',
'\u1EEA': 'U',
'\u1EE8': 'U',
'\u1EEE': 'U',
'\u1EEC': 'U',
'\u1EF0': 'U',
'\u1EE4': 'U',
'\u1E72': 'U',
'\u0172': 'U',
'\u1E76': 'U',
'\u1E74': 'U',
'\u0244': 'U',
'\u24CB': 'V',
'\uFF36': 'V',
'\u1E7C': 'V',
'\u1E7E': 'V',
'\u01B2': 'V',
'\uA75E': 'V',
'\u0245': 'V',
'\uA760': 'VY',
'\u24CC': 'W',
'\uFF37': 'W',
'\u1E80': 'W',
'\u1E82': 'W',
'\u0174': 'W',
'\u1E86': 'W',
'\u1E84': 'W',
'\u1E88': 'W',
'\u2C72': 'W',
'\u24CD': 'X',
'\uFF38': 'X',
'\u1E8A': 'X',
'\u1E8C': 'X',
'\u24CE': 'Y',
'\uFF39': 'Y',
'\u1EF2': 'Y',
'\u00DD': 'Y',
'\u0176': 'Y',
'\u1EF8': 'Y',
'\u0232': 'Y',
'\u1E8E': 'Y',
'\u0178': 'Y',
'\u1EF6': 'Y',
'\u1EF4': 'Y',
'\u01B3': 'Y',
'\u024E': 'Y',
'\u1EFE': 'Y',
'\u24CF': 'Z',
'\uFF3A': 'Z',
'\u0179': 'Z',
'\u1E90': 'Z',
'\u017B': 'Z',
'\u017D': 'Z',
'\u1E92': 'Z',
'\u1E94': 'Z',
'\u01B5': 'Z',
'\u0224': 'Z',
'\u2C7F': 'Z',
'\u2C6B': 'Z',
'\uA762': 'Z',
'\u24D0': 'a',
'\uFF41': 'a',
'\u1E9A': 'a',
'\u00E0': 'a',
'\u00E1': 'a',
'\u00E2': 'a',
'\u1EA7': 'a',
'\u1EA5': 'a',
'\u1EAB': 'a',
'\u1EA9': 'a',
'\u00E3': 'a',
'\u0101': 'a',
'\u0103': 'a',
'\u1EB1': 'a',
'\u1EAF': 'a',
'\u1EB5': 'a',
'\u1EB3': 'a',
'\u0227': 'a',
'\u01E1': 'a',
'\u00E4': 'a',
'\u01DF': 'a',
'\u1EA3': 'a',
'\u00E5': 'a',
'\u01FB': 'a',
'\u01CE': 'a',
'\u0201': 'a',
'\u0203': 'a',
'\u1EA1': 'a',
'\u1EAD': 'a',
'\u1EB7': 'a',
'\u1E01': 'a',
'\u0105': 'a',
'\u2C65': 'a',
'\u0250': 'a',
'\uA733': 'aa',
'\u00E6': 'ae',
'\u01FD': 'ae',
'\u01E3': 'ae',
'\uA735': 'ao',
'\uA737': 'au',
'\uA739': 'av',
'\uA73B': 'av',
'\uA73D': 'ay',
'\u24D1': 'b',
'\uFF42': 'b',
'\u1E03': 'b',
'\u1E05': 'b',
'\u1E07': 'b',
'\u0180': 'b',
'\u0183': 'b',
'\u0253': 'b',
'\u24D2': 'c',
'\uFF43': 'c',
'\u0107': 'c',
'\u0109': 'c',
'\u010B': 'c',
'\u010D': 'c',
'\u00E7': 'c',
'\u1E09': 'c',
'\u0188': 'c',
'\u023C': 'c',
'\uA73F': 'c',
'\u2184': 'c',
'\u24D3': 'd',
'\uFF44': 'd',
'\u1E0B': 'd',
'\u010F': 'd',
'\u1E0D': 'd',
'\u1E11': 'd',
'\u1E13': 'd',
'\u1E0F': 'd',
'\u0111': 'd',
'\u018C': 'd',
'\u0256': 'd',
'\u0257': 'd',
'\uA77A': 'd',
'\u01F3': 'dz',
'\u01C6': 'dz',
'\u24D4': 'e',
'\uFF45': 'e',
'\u00E8': 'e',
'\u00E9': 'e',
'\u00EA': 'e',
'\u1EC1': 'e',
'\u1EBF': 'e',
'\u1EC5': 'e',
'\u1EC3': 'e',
'\u1EBD': 'e',
'\u0113': 'e',
'\u1E15': 'e',
'\u1E17': 'e',
'\u0115': 'e',
'\u0117': 'e',
'\u00EB': 'e',
'\u1EBB': 'e',
'\u011B': 'e',
'\u0205': 'e',
'\u0207': 'e',
'\u1EB9': 'e',
'\u1EC7': 'e',
'\u0229': 'e',
'\u1E1D': 'e',
'\u0119': 'e',
'\u1E19': 'e',
'\u1E1B': 'e',
'\u0247': 'e',
'\u025B': 'e',
'\u01DD': 'e',
'\u24D5': 'f',
'\uFF46': 'f',
'\u1E1F': 'f',
'\u0192': 'f',
'\uA77C': 'f',
'\u24D6': 'g',
'\uFF47': 'g',
'\u01F5': 'g',
'\u011D': 'g',
'\u1E21': 'g',
'\u011F': 'g',
'\u0121': 'g',
'\u01E7': 'g',
'\u0123': 'g',
'\u01E5': 'g',
'\u0260': 'g',
'\uA7A1': 'g',
'\u1D79': 'g',
'\uA77F': 'g',
'\u24D7': 'h',
'\uFF48': 'h',
'\u0125': 'h',
'\u1E23': 'h',
'\u1E27': 'h',
'\u021F': 'h',
'\u1E25': 'h',
'\u1E29': 'h',
'\u1E2B': 'h',
'\u1E96': 'h',
'\u0127': 'h',
'\u2C68': 'h',
'\u2C76': 'h',
'\u0265': 'h',
'\u0195': 'hv',
'\u24D8': 'i',
'\uFF49': 'i',
'\u00EC': 'i',
'\u00ED': 'i',
'\u00EE': 'i',
'\u0129': 'i',
'\u012B': 'i',
'\u012D': 'i',
'\u00EF': 'i',
'\u1E2F': 'i',
'\u1EC9': 'i',
'\u01D0': 'i',
'\u0209': 'i',
'\u020B': 'i',
'\u1ECB': 'i',
'\u012F': 'i',
'\u1E2D': 'i',
'\u0268': 'i',
'\u0131': 'i',
'\u24D9': 'j',
'\uFF4A': 'j',
'\u0135': 'j',
'\u01F0': 'j',
'\u0249': 'j',
'\u24DA': 'k',
'\uFF4B': 'k',
'\u1E31': 'k',
'\u01E9': 'k',
'\u1E33': 'k',
'\u0137': 'k',
'\u1E35': 'k',
'\u0199': 'k',
'\u2C6A': 'k',
'\uA741': 'k',
'\uA743': 'k',
'\uA745': 'k',
'\uA7A3': 'k',
'\u24DB': 'l',
'\uFF4C': 'l',
'\u0140': 'l',
'\u013A': 'l',
'\u013E': 'l',
'\u1E37': 'l',
'\u1E39': 'l',
'\u013C': 'l',
'\u1E3D': 'l',
'\u1E3B': 'l',
'\u017F': 'l',
'\u0142': 'l',
'\u019A': 'l',
'\u026B': 'l',
'\u2C61': 'l',
'\uA749': 'l',
'\uA781': 'l',
'\uA747': 'l',
'\u01C9': 'lj',
'\u24DC': 'm',
'\uFF4D': 'm',
'\u1E3F': 'm',
'\u1E41': 'm',
'\u1E43': 'm',
'\u0271': 'm',
'\u026F': 'm',
'\u24DD': 'n',
'\uFF4E': 'n',
'\u01F9': 'n',
'\u0144': 'n',
'\u00F1': 'n',
'\u1E45': 'n',
'\u0148': 'n',
'\u1E47': 'n',
'\u0146': 'n',
'\u1E4B': 'n',
'\u1E49': 'n',
'\u019E': 'n',
'\u0272': 'n',
'\u0149': 'n',
'\uA791': 'n',
'\uA7A5': 'n',
'\u01CC': 'nj',
'\u24DE': 'o',
'\uFF4F': 'o',
'\u00F2': 'o',
'\u00F3': 'o',
'\u00F4': 'o',
'\u1ED3': 'o',
'\u1ED1': 'o',
'\u1ED7': 'o',
'\u1ED5': 'o',
'\u00F5': 'o',
'\u1E4D': 'o',
'\u022D': 'o',
'\u1E4F': 'o',
'\u014D': 'o',
'\u1E51': 'o',
'\u1E53': 'o',
'\u014F': 'o',
'\u022F': 'o',
'\u0231': 'o',
'\u00F6': 'o',
'\u022B': 'o',
'\u1ECF': 'o',
'\u0151': 'o',
'\u01D2': 'o',
'\u020D': 'o',
'\u020F': 'o',
'\u01A1': 'o',
'\u1EDD': 'o',
'\u1EDB': 'o',
'\u1EE1': 'o',
'\u1EDF': 'o',
'\u1EE3': 'o',
'\u1ECD': 'o',
'\u1ED9': 'o',
'\u01EB': 'o',
'\u01ED': 'o',
'\u00F8': 'o',
'\u01FF': 'o',
'\u0254': 'o',
'\uA74B': 'o',
'\uA74D': 'o',
'\u0275': 'o',
'\u01A3': 'oi',
'\u0223': 'ou',
'\uA74F': 'oo',
'\u24DF': 'p',
'\uFF50': 'p',
'\u1E55': 'p',
'\u1E57': 'p',
'\u01A5': 'p',
'\u1D7D': 'p',
'\uA751': 'p',
'\uA753': 'p',
'\uA755': 'p',
'\u24E0': 'q',
'\uFF51': 'q',
'\u024B': 'q',
'\uA757': 'q',
'\uA759': 'q',
'\u24E1': 'r',
'\uFF52': 'r',
'\u0155': 'r',
'\u1E59': 'r',
'\u0159': 'r',
'\u0211': 'r',
'\u0213': 'r',
'\u1E5B': 'r',
'\u1E5D': 'r',
'\u0157': 'r',
'\u1E5F': 'r',
'\u024D': 'r',
'\u027D': 'r',
'\uA75B': 'r',
'\uA7A7': 'r',
'\uA783': 'r',
'\u24E2': 's',
'\uFF53': 's',
'\u00DF': 's',
'\u015B': 's',
'\u1E65': 's',
'\u015D': 's',
'\u1E61': 's',
'\u0161': 's',
'\u1E67': 's',
'\u1E63': 's',
'\u1E69': 's',
'\u0219': 's',
'\u015F': 's',
'\u023F': 's',
'\uA7A9': 's',
'\uA785': 's',
'\u1E9B': 's',
'\u24E3': 't',
'\uFF54': 't',
'\u1E6B': 't',
'\u1E97': 't',
'\u0165': 't',
'\u1E6D': 't',
'\u021B': 't',
'\u0163': 't',
'\u1E71': 't',
'\u1E6F': 't',
'\u0167': 't',
'\u01AD': 't',
'\u0288': 't',
'\u2C66': 't',
'\uA787': 't',
'\uA729': 'tz',
'\u24E4': 'u',
'\uFF55': 'u',
'\u00F9': 'u',
'\u00FA': 'u',
'\u00FB': 'u',
'\u0169': 'u',
'\u1E79': 'u',
'\u016B': 'u',
'\u1E7B': 'u',
'\u016D': 'u',
'\u00FC': 'u',
'\u01DC': 'u',
'\u01D8': 'u',
'\u01D6': 'u',
'\u01DA': 'u',
'\u1EE7': 'u',
'\u016F': 'u',
'\u0171': 'u',
'\u01D4': 'u',
'\u0215': 'u',
'\u0217': 'u',
'\u01B0': 'u',
'\u1EEB': 'u',
'\u1EE9': 'u',
'\u1EEF': 'u',
'\u1EED': 'u',
'\u1EF1': 'u',
'\u1EE5': 'u',
'\u1E73': 'u',
'\u0173': 'u',
'\u1E77': 'u',
'\u1E75': 'u',
'\u0289': 'u',
'\u24E5': 'v',
'\uFF56': 'v',
'\u1E7D': 'v',
'\u1E7F': 'v',
'\u028B': 'v',
'\uA75F': 'v',
'\u028C': 'v',
'\uA761': 'vy',
'\u24E6': 'w',
'\uFF57': 'w',
'\u1E81': 'w',
'\u1E83': 'w',
'\u0175': 'w',
'\u1E87': 'w',
'\u1E85': 'w',
'\u1E98': 'w',
'\u1E89': 'w',
'\u2C73': 'w',
'\u24E7': 'x',
'\uFF58': 'x',
'\u1E8B': 'x',
'\u1E8D': 'x',
'\u24E8': 'y',
'\uFF59': 'y',
'\u1EF3': 'y',
'\u00FD': 'y',