UNPKG

ngx-avatars

Version:

A universal avatar component for Angular applications that fetches / generates avatar based on the information you have about the user.

862 lines (838 loc) 28.9 kB
import * as i0 from '@angular/core'; import { InjectionToken, inject, Injectable, EventEmitter, SecurityContext, Output, Input, Component, NgModule } from '@angular/core'; import * as i1 from '@angular/common'; import { CommonModule, NgOptimizedImage } from '@angular/common'; import { Md5 } from 'ts-md5'; import { HttpClient } from '@angular/common/http'; import { takeWhile, map } from 'rxjs/operators'; import { DomSanitizer } from '@angular/platform-browser'; /** * Contract of all async sources. * Every async source must implement the processResponse method that extracts the avatar url from the data */ class AsyncSource { constructor(sourceId) { this.sourceId = sourceId; } } var AvatarSource; (function (AvatarSource) { AvatarSource["FACEBOOK"] = "facebook"; AvatarSource["GOOGLE"] = "google"; AvatarSource["TWITTER"] = "twitter"; AvatarSource["INSTAGRAM"] = "instagram"; AvatarSource["VKONTAKTE"] = "vkontakte"; AvatarSource["SKYPE"] = "skype"; AvatarSource["GRAVATAR"] = "gravatar"; AvatarSource["GITHUB"] = "github"; AvatarSource["CUSTOM"] = "custom"; AvatarSource["INITIALS"] = "initials"; AvatarSource["VALUE"] = "value"; })(AvatarSource || (AvatarSource = {})); /** * Facebook source implementation. * Fetch avatar source based on facebook identifier * and image size */ class Facebook { constructor(sourceId) { this.sourceId = sourceId; this.sourceType = AvatarSource.FACEBOOK; } getAvatar(size) { return ('https://graph.facebook.com/' + `${this.sourceId}/picture?width=${size}&height=${size}`); } } /** * Twitter source implementation. * Fetch avatar source based on google identifier * and image size */ class Twitter { constructor(sourceId) { this.sourceId = sourceId; this.sourceType = AvatarSource.TWITTER; } getAvatar(size) { const twitterImgSize = this.getImageSize(size); return `https://twitter.com/${this.sourceId}/profile_image?size=${twitterImgSize}`; } getImageSize(size) { if (size <= 24) { return 'mini'; } if (size <= 48) { return 'normal'; } if (size <= 73) { return 'bigger'; } return 'original'; } } /** * Google source implementation. * Fetch avatar source based on google identifier * and image size */ class Google extends AsyncSource { constructor(sourceId) { super(sourceId); this.sourceType = AvatarSource.GOOGLE; } getAvatar() { return `https://picasaweb.google.com/data/entry/api/user/${this.sourceId}?alt=json`; } /** * Extract google avatar from json data */ processResponse(data, size) { const avatarSrc = data.entry.gphoto$thumbnail.$t; if (avatarSrc) { return avatarSrc.replace('s64', 's' + size); } return null; } } /** * Instagram source implementation. * Fetch avatar source based on instagram identifier */ class Instagram extends AsyncSource { constructor(sourceId) { super(sourceId); this.sourceType = AvatarSource.INSTAGRAM; } getAvatar() { return `https://www.instagram.com/${this.sourceId}/?__a=1`; } /** * extract instagram avatar from json data */ processResponse(data, size) { return `${data.graphql.user.profile_pic_url_hd}&s=${size}`; } } /** * Custom source implementation. * return custom image as an avatar * */ class Custom { constructor(sourceId) { this.sourceId = sourceId; this.sourceType = AvatarSource.CUSTOM; } getAvatar() { return this.sourceId; } } /** * Initials source implementation. * return the initials of the given value */ class Initials { constructor(sourceId) { this.sourceId = sourceId; this.sourceType = AvatarSource.INITIALS; } getAvatar(size) { return this.getInitials(this.sourceId, size); } /** * Returns the initial letters of a name in a string. */ getInitials(name, size) { name = name.trim(); if (!name) { return ''; } const initials = name.split(' '); if (size && size < initials.length) { return this.constructInitials(initials.slice(0, size)); } else { return this.constructInitials(initials); } } /** * Iterates a person's name string to get the initials of each word in uppercase. */ constructInitials(elements) { if (!elements || !elements.length) { return ''; } return elements .filter(element => element && element.length > 0) .map(element => element[0].toUpperCase()) .join(''); } } function isRetina() { if (typeof window !== 'undefined' && window !== null) { if (window.devicePixelRatio > 1.25) { return true; } const mediaQuery = '(-webkit-min-device-pixel-ratio: 1.25), (min--moz-device-pixel-ratio: 1.25), (-o-min-device-pixel-ratio: 5/4), (min-resolution: 1.25dppx)'; if (window.matchMedia && window.matchMedia(mediaQuery).matches) { return true; } } return false; } /** * Gravatar source implementation. * Fetch avatar source based on gravatar email */ class Gravatar { constructor(value) { this.value = value; this.sourceType = AvatarSource.GRAVATAR; this.sourceId = value.match('^[a-f0-9]{32}$') ? value : Md5.hashStr(value).toString(); } getAvatar(size) { const avatarSize = isRetina() ? size * 2 : size; return `https://secure.gravatar.com/avatar/${this.sourceId}?s=${avatarSize}&d=404`; } } /** * Skype source implementation. * Fetch avatar source based on skype identifier */ class Skype { constructor(sourceId) { this.sourceId = sourceId; this.sourceType = AvatarSource.SKYPE; } getAvatar() { return `https://api.skype.com/users/${this.sourceId}/profile/avatar`; } } /** * Value source implementation. * return the value as avatar */ class Value { constructor(sourceId) { this.sourceId = sourceId; this.sourceType = AvatarSource.VALUE; } getAvatar() { return this.sourceId; } } /** * Vkontakte source implementation. * Fetch avatar source based on vkontakte identifier * and image size */ const apiVersion = 5.8; class Vkontakte extends AsyncSource { constructor(sourceId) { super(sourceId); this.sourceType = AvatarSource.VKONTAKTE; } getAvatar(size) { const imgSize = this.getImageSize(size); return `https://api.vk.com/method/users.get?user_id=${this.sourceId}&v=${apiVersion}&fields=${imgSize}`; } /** * extract vkontakte avatar from json data */ processResponse(data) { // avatar key property is the size used to generate avatar url // size property is always the last key in the response object const sizeProperty = Object.keys(data['response'][0]).pop(); if (!sizeProperty) { return null; } // return avatar src return data['response'][0][sizeProperty] || null; } /** * Returns image size related to vkontakte API */ getImageSize(size) { if (size <= 50) { return 'photo_50'; } if (size <= 100) { return 'photo_100'; } if (size <= 200) { return 'photo_200'; } return 'photo_max'; } } /** * GitHub source implementation. * Fetch avatar source based on github identifier */ class Github extends AsyncSource { constructor(sourceId) { super(sourceId); this.sourceType = AvatarSource.GITHUB; } getAvatar() { return `https://api.github.com/users/${this.sourceId}`; } /** * extract github avatar from json data */ processResponse(data, size) { if (size) { return `${data.avatar_url}&s=${size}`; } return data.avatar_url; } } /** * Token used to inject the AvatarConfig object */ const AVATAR_CONFIG = new InjectionToken('avatar.config'); class AvatarConfigService { constructor() { this.userConfig = inject(AVATAR_CONFIG, { optional: true }); } getAvatarSources(defaultSources) { if (this.userConfig && this.userConfig.sourcePriorityOrder && this.userConfig.sourcePriorityOrder.length) { const uniqueSources = [...new Set(this.userConfig.sourcePriorityOrder)]; const validSources = uniqueSources.filter(source => defaultSources.includes(source)); return [ ...validSources, ...defaultSources.filter(source => !validSources.includes(source)) ]; } return defaultSources; } getAvatarColors(defaultColors) { return ((this.userConfig && this.userConfig.colors && this.userConfig.colors.length && this.userConfig.colors) || defaultColors); } getDisableSrcCache(defaultDisableSrcCache) { if (this.userConfig == null || this.userConfig.disableSrcCache == null) { return defaultDisableSrcCache; } else { return this.userConfig.disableSrcCache; } } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarConfigService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarConfigService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarConfigService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); /** * list of Supported avatar sources */ const defaultSources = [ AvatarSource.FACEBOOK, AvatarSource.GOOGLE, AvatarSource.TWITTER, AvatarSource.INSTAGRAM, AvatarSource.VKONTAKTE, AvatarSource.SKYPE, AvatarSource.GRAVATAR, AvatarSource.GITHUB, AvatarSource.CUSTOM, AvatarSource.INITIALS, AvatarSource.VALUE ]; /** * list of default colors */ const defaultColors = [ '#1abc9c', '#3498db', '#f1c40f', '#8e44ad', '#e74c3c', '#d35400', '#2c3e50', '#7f8c8d' ]; /** * Default disable custom source cache settings */ const defaultDisableSrcCache = false; /** * Provides utilities methods related to Avatar component */ class AvatarService { constructor() { this.http = inject(HttpClient); this.avatarConfigService = inject(AvatarConfigService); this.avatarSources = defaultSources; this.avatarColors = defaultColors; this.failedSources = new Map(); this.overrideAvatarSources(); this.overrideAvatarColors(); } fetchAvatar(avatarUrl) { return this.http.get(avatarUrl); } getRandomColor(avatarText) { if (!avatarText) { return 'transparent'; } const asciiCodeSum = this.calculateAsciiCode(avatarText); return this.avatarColors[asciiCodeSum % this.avatarColors.length]; } compareSources(sourceType1, sourceType2) { return (this.getSourcePriority(sourceType1) - this.getSourcePriority(sourceType2)); } isSource(source) { return this.avatarSources.includes(source); } isTextAvatar(sourceType) { return [AvatarSource.INITIALS, AvatarSource.VALUE].includes(sourceType); } buildSourceKey(source) { return source.sourceType + '-' + source.sourceId; } sourceHasFailedBefore(source) { return this.failedSources.has(this.buildSourceKey(source)); } markSourceAsFailed(source) { this.failedSources.set(this.buildSourceKey(source), source); } overrideAvatarSources() { this.avatarSources = this.avatarConfigService.getAvatarSources(defaultSources); } overrideAvatarColors() { this.avatarColors = this.avatarConfigService.getAvatarColors(defaultColors); } calculateAsciiCode(value) { return value .split('') .map(letter => letter.charCodeAt(0)) .reduce((previous, current) => previous + current); } getSourcePriority(sourceType) { return this.avatarSources.indexOf(sourceType); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarService, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarService, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); /** * Custom source implementation (with no cache). * return custom image as an avatar * */ class CustomNoCache { constructor(sourceId) { this.sourceId = sourceId; this.sourceType = AvatarSource.CUSTOM; } getAvatar() { const urlSuffix = Math.random(); return `${this.sourceId}${this.sourceId.indexOf('?') > -1 ? '&' : '?'}_=${urlSuffix}`; } } /** * Factory class that implements factory method pattern. * Used to create Source implementation class based * on the source Type */ class SourceFactory { constructor() { this.sources = {}; const avatarConfigService = inject(AvatarConfigService); const disableSrcCache = avatarConfigService.getDisableSrcCache(defaultDisableSrcCache); this.sources[AvatarSource.FACEBOOK] = Facebook; this.sources[AvatarSource.TWITTER] = Twitter; this.sources[AvatarSource.GOOGLE] = Google; this.sources[AvatarSource.INSTAGRAM] = Instagram; this.sources[AvatarSource.SKYPE] = Skype; this.sources[AvatarSource.GRAVATAR] = Gravatar; this.sources[AvatarSource.CUSTOM] = disableSrcCache ? CustomNoCache : Custom; this.sources[AvatarSource.INITIALS] = Initials; this.sources[AvatarSource.VALUE] = Value; this.sources[AvatarSource.VKONTAKTE] = Vkontakte; this.sources[AvatarSource.GITHUB] = Github; } newInstance(sourceType, sourceValue) { return new this.sources[sourceType](sourceValue); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SourceFactory, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); } static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SourceFactory, providedIn: 'root' }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: SourceFactory, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [] }); /** * Universal avatar component that * generates avatar from different sources * * export * class AvatarComponent * implements {OnChanges} */ class AvatarComponent { constructor() { this.sourceFactory = inject(SourceFactory); this.avatarService = inject(AvatarService); this.sanitizer = inject(DomSanitizer); this.round = true; this.size = 50; this.textSizeRatio = 3; this.fgColor = '#FFF'; this.style = {}; this.cornerRadius = 0; this.initialsSize = 0; this.clickOnAvatar = new EventEmitter(); this.isAlive = true; this.avatarSrc = null; this.avatarAlt = null; this.avatarText = null; this.avatarStyle = {}; this.hostStyle = {}; this.currentIndex = -1; this.sources = []; } onAvatarClicked() { this.clickOnAvatar.emit(this.sources[this.currentIndex]); } /** * Detect inputs change * * param {{ [propKey: string]: SimpleChange }} changes * * memberof AvatarComponent */ ngOnChanges(changes) { for (const propName in changes) { if (this.avatarService.isSource(propName)) { const sourceType = AvatarSource[propName.toUpperCase()]; const currentValue = changes[propName].currentValue; if (currentValue && typeof currentValue === 'string') { this.addSource(sourceType, currentValue); } else { const sanitized = this.sanitizer.sanitize(SecurityContext.URL, currentValue); if (sanitized) { this.addSource(sourceType, sanitized); } else { this.removeSource(sourceType); } } } } // reinitialize the avatar component when a source property value has changed // the fallback system must be re-invoked with the new values. this.initializeAvatar(); } /** * Fetch avatar source * * memberOf AvatarComponent */ fetchAvatarSource() { const previousSource = this.sources[this.currentIndex]; if (previousSource) { this.avatarService.markSourceAsFailed(previousSource); } const source = this.findNextSource(); if (!source) { return; } if (this.avatarService.isTextAvatar(source.sourceType)) { this.buildTextAvatar(source); this.avatarSrc = null; } else { this.buildImageAvatar(source); } } findNextSource() { while (++this.currentIndex < this.sources.length) { const source = this.sources[this.currentIndex]; if (source && !this.avatarService.sourceHasFailedBefore(source)) { return source; } } return null; } ngOnDestroy() { this.isAlive = false; } /** * Initialize the avatar component and its fallback system */ initializeAvatar() { this.currentIndex = -1; if (this.sources.length > 0) { this.sortAvatarSources(); this.fetchAvatarSource(); this.hostStyle = { width: this.size + 'px', height: this.size + 'px' }; } } sortAvatarSources() { this.sources.sort((source1, source2) => this.avatarService.compareSources(source1.sourceType, source2.sourceType)); } buildTextAvatar(avatarSource) { this.avatarText = avatarSource.getAvatar(+this.initialsSize); this.avatarStyle = this.getInitialsStyle(avatarSource.sourceId); } buildImageAvatar(avatarSource) { this.avatarStyle = this.getImageStyle(); if (avatarSource instanceof AsyncSource) { this.fetchAndProcessAsyncAvatar(avatarSource); } else { this.avatarSrc = this.sanitizer.bypassSecurityTrustUrl(avatarSource.getAvatar(+this.size)); this.avatarAlt = avatarSource.getAvatar(+this.size); } } /** * * returns initials style * * memberOf AvatarComponent */ getInitialsStyle(avatarValue) { return { textAlign: 'center', borderRadius: this.round ? '100%' : this.cornerRadius + 'px', border: this.borderColor ? '1px solid ' + this.borderColor : '', textTransform: 'uppercase', color: this.fgColor, backgroundColor: this.bgColor ? this.bgColor : this.avatarService.getRandomColor(avatarValue), font: Math.floor(+this.size / this.textSizeRatio) + 'px Helvetica, Arial, sans-serif', lineHeight: this.size + 'px', ...this.style }; } /** * * returns image style * * memberOf AvatarComponent */ getImageStyle() { return { maxWidth: '100%', borderRadius: this.round ? '50%' : this.cornerRadius + 'px', border: this.borderColor ? '1px solid ' + this.borderColor : '', width: this.size + 'px', height: this.size + 'px', ...this.style, }; } /** * Fetch avatar image asynchronously. * * param {Source} source represents avatar source * memberof AvatarComponent */ fetchAndProcessAsyncAvatar(source) { if (this.avatarService.sourceHasFailedBefore(source)) { return; } this.avatarService .fetchAvatar(source.getAvatar(+this.size)) .pipe(takeWhile(() => this.isAlive), map(response => source.processResponse(response, +this.size))) .subscribe({ next: avatarSrc => (this.avatarSrc = avatarSrc), error: () => { this.fetchAvatarSource(); } }); } /** * Add avatar source * * param sourceType avatar source type e.g facebook,twitter, etc. * param sourceValue source value e.g facebookId value, etc. */ addSource(sourceType, sourceValue) { const source = this.sources.find(s => s.sourceType === sourceType); if (source) { source.sourceId = sourceValue; } else { this.sources.push(this.sourceFactory.newInstance(sourceType, sourceValue)); } } /** * Remove avatar source * * param sourceType avatar source type e.g facebook,twitter, etc. */ removeSource(sourceType) { this.sources = this.sources.filter(source => source.sourceType !== sourceType); } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); } static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.1.2", type: AvatarComponent, isStandalone: true, selector: "ngx-avatars", inputs: { round: "round", size: "size", textSizeRatio: "textSizeRatio", bgColor: "bgColor", fgColor: "fgColor", borderColor: "borderColor", style: "style", cornerRadius: "cornerRadius", facebook: ["facebookId", "facebook"], twitter: ["twitterId", "twitter"], google: ["googleId", "google"], instagram: ["instagramId", "instagram"], vkontakte: ["vkontakteId", "vkontakte"], skype: ["skypeId", "skype"], gravatar: ["gravatarId", "gravatar"], github: ["githubId", "github"], custom: ["src", "custom"], customAlt: ["alt", "customAlt"], initials: ["name", "initials"], value: "value", referrerpolicy: "referrerpolicy", placeholder: "placeholder", initialsSize: "initialsSize" }, outputs: { clickOnAvatar: "clickOnAvatar" }, usesOnChanges: true, ngImport: i0, template: ` <div (click)="onAvatarClicked()" class="avatar-container" [ngStyle]="hostStyle" > @if (avatarSrc; as src) { <img [ngSrc]="src" [alt]="customAlt ? customAlt : avatarAlt" [width]="size" [height]="size" [ngStyle]="avatarStyle" [attr.referrerPolicy]="referrerpolicy" (error)="fetchAvatarSource()" class="avatar-content" loading="lazy" /> } @else { @if (avatarText) { <div class="avatar-content" [ngStyle]="avatarStyle"> {{ avatarText }} </div> } } </div> `, isInline: true, styles: [":host{border-radius:50%}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: NgOptimizedImage, selector: "img[ngSrc]", inputs: ["ngSrc", "ngSrcset", "sizes", "width", "height", "decoding", "loading", "priority", "loaderParams", "disableOptimizedSrcset", "fill", "placeholder", "placeholderConfig", "src", "srcset"] }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-avatars', template: ` <div (click)="onAvatarClicked()" class="avatar-container" [ngStyle]="hostStyle" > @if (avatarSrc; as src) { <img [ngSrc]="src" [alt]="customAlt ? customAlt : avatarAlt" [width]="size" [height]="size" [ngStyle]="avatarStyle" [attr.referrerPolicy]="referrerpolicy" (error)="fetchAvatarSource()" class="avatar-content" loading="lazy" /> } @else { @if (avatarText) { <div class="avatar-content" [ngStyle]="avatarStyle"> {{ avatarText }} </div> } } </div> `, imports: [ CommonModule, NgOptimizedImage ], standalone: true, styles: [":host{border-radius:50%}\n"] }] }], ctorParameters: () => [], propDecorators: { round: [{ type: Input }], size: [{ type: Input }], textSizeRatio: [{ type: Input }], bgColor: [{ type: Input }], fgColor: [{ type: Input }], borderColor: [{ type: Input }], style: [{ type: Input }], cornerRadius: [{ type: Input }], facebook: [{ type: Input, args: ['facebookId'] }], twitter: [{ type: Input, args: ['twitterId'] }], google: [{ type: Input, args: ['googleId'] }], instagram: [{ type: Input, args: ['instagramId'] }], vkontakte: [{ type: Input, args: ['vkontakteId'] }], skype: [{ type: Input, args: ['skypeId'] }], gravatar: [{ type: Input, args: ['gravatarId'] }], github: [{ type: Input, args: ['githubId'] }], custom: [{ type: Input, args: ['src'] }], customAlt: [{ type: Input, args: ['alt'] }], initials: [{ type: Input, args: ['name'] }], value: [{ type: Input }], referrerpolicy: [{ type: Input }], placeholder: [{ type: Input }], initialsSize: [{ type: Input }], clickOnAvatar: [{ type: Output }] } }); class AvatarModule { static forRoot(avatarConfig) { return { ngModule: AvatarModule, providers: [ { provide: AVATAR_CONFIG, useValue: avatarConfig ? avatarConfig : {} } ] }; } static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); } static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.1.2", ngImport: i0, type: AvatarModule, imports: [CommonModule, AvatarComponent], exports: [AvatarComponent] }); } static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarModule, providers: [SourceFactory, AvatarService, AvatarConfigService], imports: [CommonModule, AvatarComponent] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.1.2", ngImport: i0, type: AvatarModule, decorators: [{ type: NgModule, args: [{ imports: [CommonModule, AvatarComponent], declarations: [], providers: [SourceFactory, AvatarService, AvatarConfigService], exports: [AvatarComponent] }] }] }); /* * Public API Surface of ngx-avatars */ /** * Generated bundle index. Do not edit. */ export { AvatarComponent, AvatarModule, AvatarService, AvatarSource, defaultColors, defaultDisableSrcCache, defaultSources }; //# sourceMappingURL=ngx-avatars.mjs.map