UNPKG

@ngodings/ngx-image-tagger

Version:

Simple Image Tagger like instagram, easy to put stuff/item information in x/y position from image, easy configuration in Angular

211 lines 46.7 kB
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core'; import { fromEvent } from 'rxjs'; import * as i0 from "@angular/core"; import * as i1 from "@angular/common"; import * as i2 from "@angular/forms"; import * as i3 from "@ngodings/ngx-currency"; export class NgxImageTaggerComponent { constructor() { this.heightElement = 0; this.widthElement = 0; this.isAllowCreate = false; this.isShowThumbnail = true; this.imageClassList = ""; this.placeholderName = 'Name'; this.placeholderPrice = 'Price'; this.isShowPrice = true; this.placeholderLink = 'Link'; this.isShowLink = true; this.borderColor = "#007ac1"; this.backgroundColor = "#03a9f4"; this.textColor = "#ffffff"; this.inputClassList = ""; this.placeholderCreateTitle = 'Tag your product!'; this.buttonCancelTitle = "Cancel"; this.buttonCreateTitle = "Create"; this.isShowShop = false; this.titleShop = "Go to shop"; this.onShowTagMode = "Hover"; this.tagger = { idParent: 'image-parent', id: 'image', style: '', urlShop: '', isOffsideX: false, isOffsideY: false, x: 0, y: 0, url: '', tags: [] }; this.taggerChange = new EventEmitter(); this.isShowForm = false; this.isShowView = true; fromEvent(document.body, 'mousedown').subscribe((event) => { const elementId = event.target.id; if (this.tagger && elementId === this.tagger.id) { this.resetTag(); const x = event.layerX; const y = event.layerY - 6; this.heightElement = event?.srcElement?.offsetHeight; const halfY = this.heightElement / 2; if (halfY < y) { this.tagger.isOffsideY = true; } else { this.tagger.isOffsideY = false; } this.widthElement = event?.srcElement?.offsetWidth; const halfX = this.widthElement / 2; if (halfX < x) { this.tagger.isOffsideX = true; } else { this.tagger.isOffsideX = false; } this.tagger.x = (x * 100) / this.widthElement; this.tagger.y = (y * 100) / this.heightElement; this.isShowForm = true; } }); } ngOnInit() { this.form = { id: '', x: 0, y: 0, isOffsideX: false, isOffsideY: false, tagger: this.tagger, open: false, }; if (this.onShowTagMode === 'IconClick') { this.isShowView = false; } } changeStyleClick(id, tag) { if (this.onShowTagMode != 'Click') { return; } tag.open = !tag.open; this.onShowStyle(id, tag.open); } changeStyleHover(id, show) { if (this.onShowTagMode == 'Click') { return; } this.onShowStyle(id, show); } onShowStyle(id, show) { const el = document.getElementById(id); if (el) { if (show) { el.style.display = "block"; el.style.zIndex = "100"; } else { el.style.display = "none"; el.style.zIndex = "1"; } } } goToURL(url) { window.open(url, "_blank"); } goToTag(item) { window.open(item.url, "_blank"); } resetTag() { this.form.name = ''; this.form.price = 0; this.form.url = ''; this.isShowForm = false; } submitTag(item) { if (item) { let isOffsideX = false; let isOffsideY = false; if (item?.x > 50) { isOffsideX = true; } else { isOffsideX = false; } if (item?.y > 0) { isOffsideY = true; } else { isOffsideY = false; } item.tags.push({ id: "", name: this.form.name, url: this.form.url, x: item.x, y: item.y, isOffsideX, isOffsideY, open: false, price: this.form.price, tagger: Object.assign(this.tagger), }); this.resetTag(); this.taggerChange.next(this.tagger); } } editTag(item, tag, subindex) { this.form.name = tag?.name; this.form.url = tag?.url; this.tagger.x = tag.x; this.tagger.y = tag.y; this.tagger.isOffsideX = tag.isOffsideX; this.tagger.isOffsideY = tag.isOffsideY; this.isShowForm = true; this.taggerChange.next(this.tagger); } deleteTag(item, tag, subindex) { this.tagger.tags.splice(subindex, 1); this.taggerChange.next(this.tagger); } } NgxImageTaggerComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NgxImageTaggerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); NgxImageTaggerComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.0.4", type: NgxImageTaggerComponent, selector: "ngx-image-tagger", inputs: { isAllowCreate: "isAllowCreate", isShowThumbnail: "isShowThumbnail", imageClassList: "imageClassList", placeholderName: "placeholderName", placeholderPrice: "placeholderPrice", isShowPrice: "isShowPrice", placeholderLink: "placeholderLink", isShowLink: "isShowLink", borderColor: "borderColor", backgroundColor: "backgroundColor", textColor: "textColor", inputClassList: "inputClassList", placeholderCreateTitle: "placeholderCreateTitle", buttonCancelTitle: "buttonCancelTitle", buttonCreateTitle: "buttonCreateTitle", isShowShop: "isShowShop", titleShop: "titleShop", onShowTagMode: "onShowTagMode", tagger: "tagger" }, outputs: { taggerChange: "taggerChange" }, ngImport: i0, template: "<div class=\"tagger\" id=\"{{ tagger.idParent }}\">\n <img alt=\"Image Tagger\" id=\"{{ tagger.id }}\" [src]=\"tagger.url\" [ngClass]=\"imageClassList\"> \n <ng-container *ngIf=\"tagger?.tags && tagger.tags?.length! > 0 && onShowTagMode === 'IconClick'\">\n <div class=\"shop-icon\" [class.active]=\"isShowView\" (click)=\"isShowView = !isShowView\" [class.without-shop]=\"!isShowShop\" [class.with-shop]=\"isShowShop\">\n <i class=\"material-icons\">local_mall</i>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"isShowForm\">\n <div class=\"add-tag flex\" *ngIf=\"isAllowCreate\" [ngStyle]=\"{\n 'top.%': tagger.y , \n 'left.%': tagger.x\n }\" [class.items-start]=\"tagger.isOffsideY && !tagger.isOffsideX || tagger.isOffsideY && tagger.isOffsideX\">\n\n <div class=\"pin mr-2\"></div>\n\n <div class=\"content\">\n <ng-container *ngIf=\"placeholderCreateTitle\">\n <div class=\"mb-3 create-title\">\n {{ placeholderCreateTitle }}\n </div>\n </ng-container>\n <div>\n <input class=\"input-style\" [(ngModel)]=\"form.name\" [placeholder]=\"placeholderName\" type=\"text\" [ngClass]=\"inputClassList\">\n </div>\n <ng-container *ngIf=\"isShowPrice\">\n <div class=\"mt-2\">\n <input class=\"input-style\" [(ngModel)]=\"form.price\" currencyMask [options]=\"{ prefix: '$ ', thousands: '.', decimal: ',' }\" [placeholder]=\"placeholderPrice\" [ngClass]=\"inputClassList\">\n </div>\n </ng-container>\n <ng-container *ngIf=\"isShowLink\">\n <div class=\"mt-2\">\n <input class=\"input-style\" [(ngModel)]=\"form.url\" [placeholder]=\"placeholderLink\" type=\"email\" [ngClass]=\"inputClassList\">\n </div>\n </ng-container>\n <div class=\"mt-2 flex items-center justify-space-between gap-2\">\n <div class=\"w-half\">\n <button class=\"button-style outline\" (click)=\"isShowForm = false\" [ngStyle]=\"{ 'border-color': backgroundColor, 'color': backgroundColor }\">\n {{ buttonCancelTitle }}\n </button>\n </div>\n <div class=\"w-half\">\n <button class=\"button-style\" (click)=\"submitTag(tagger)\" [ngStyle]=\"{ 'border-color': backgroundColor, 'background': backgroundColor, 'color': textColor }\" [disabled]=\"!form.name || !form.url && isShowLink\">\n {{ buttonCreateTitle }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"tagger.tags && isShowView\">\n <ng-container *ngFor=\"let tag of tagger.tags; let subindex = index\">\n <div class=\"tagging flex items-start\" (mouseover)=\"changeStyleHover(tag.id+subindex,true)\" (click)=\"changeStyleClick(tag.id+subindex, tag)\"\n (mouseout)=\"changeStyleHover(tag.id+subindex,false)\" [ngStyle]=\"{\n 'top.%': tag.y, \n 'left.%': tag.x\n }\">\n <div class=\"pin mr-2 pointer\">\n </div>\n <div [id]=\"tag.id+subindex\" class=\"content\" style=\"display: none;\">\n <div class=\"flex items-center justify-between gap-2\">\n <ng-container *ngIf=\"isShowThumbnail\">\n <div class=\"thumnbnail\">\n <img [src]=\"tagger.url\" [ngStyle]=\"{'object-position':''+tag.x+'% '+tag.y+'%'+'', 'object-fit': 'none'}\">\n </div>\n </ng-container>\n <div class=\"text-left\">\n <div class=\"name\">{{ tag.name }}</div>\n <div *ngIf=\"isShowPrice\" class=\"mt-1 price\" >{{ tag.price | currency:'USD' }}</div>\n <div *ngIf=\"isShowLink\" class=\"link mt-1 pointer\" (click)=\"goToTag(tag)\">Go to link</div>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-container *ngIf=\"isShowShop\">\n <div class=\"shop flex items-center justify-between\" [ngStyle]=\"{ 'background': backgroundColor }\" (click)=\"goToURL(tagger.urlShop!)\">\n <div class=\"w-half flex items-center justify-content-start\">\n {{ titleShop }}\n </div>\n <div class=\"flex items-center justify-content-end w-half\">\n <i class=\"material-icons\">navigate_next</i>\n </div>\n </div>\n</ng-container>", styles: ["@import\"~material-icons/iconfont/material-icons.css\";ngx-image-tagger{font-family:inherit;font-size:12px}ngx-image-tagger .pointer{cursor:pointer}ngx-image-tagger input{width:100%}ngx-image-tagger .items-end{align-items:end}ngx-image-tagger .items-start{align-items:start}ngx-image-tagger .items-center{align-items:center}ngx-image-tagger .justify-content-start{justify-content:start}ngx-image-tagger .justify-content-center{justify-content:center}ngx-image-tagger .justify-content-end{justify-content:end}ngx-image-tagger .justify-space-between{justify-content:space-between}ngx-image-tagger .w-half{width:50%}ngx-image-tagger .ml-2{margin-left:.5rem}ngx-image-tagger .mr-2{margin-right:.5rem}ngx-image-tagger .mb-2{margin-bottom:.5rem}ngx-image-tagger .mb-3{margin-bottom:.75rem}ngx-image-tagger .mt-1{margin-top:.25rem}ngx-image-tagger .mt-2{margin-top:.5rem}ngx-image-tagger .text-left{text-align:left}ngx-image-tagger .flex{display:flex}ngx-image-tagger .flex-col{direction:column}ngx-image-tagger .gap-2{gap:.5rem}ngx-image-tagger .thumnbnail{min-width:70px!important;width:70px!important;height:70px!important}ngx-image-tagger .thumnbnail img{min-width:70px!important;width:70px!important;height:70px!important;border-radius:6px}ngx-image-tagger .create-title{font-size:14px;text-align:center}ngx-image-tagger input.input-style{padding:10px;border-radius:6px;font-size:inherit;border:2px solid #eee;outline:none;box-sizing:border-box}ngx-image-tagger button{font-size:inherit;cursor:pointer;width:100%}ngx-image-tagger .w-full{width:100%}ngx-image-tagger .button-style[disabled]{border:1px solid #eee!important;background-color:#eee!important;color:#bbb!important}ngx-image-tagger .button-style{border:1px solid;padding:6px 12px;text-align:center;text-decoration:none;display:inline-block;border-radius:6px}ngx-image-tagger .button-style.outline{border:1px solid;background:white;padding:6px 12px;text-align:center;text-decoration:none;display:inline-block;border-radius:6px}ngx-image-tagger .tagger{position:relative;height:-moz-fit-content;height:fit-content;width:-moz-fit-content;width:fit-content;display:inline-block}ngx-image-tagger .tagger img{width:100%;object-fit:contain;object-position:center;height:100%}ngx-image-tagger .tagger .pin{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;height:15px;width:15px;border:2px solid;color:#fff;border-top-right-radius:100%;border-bottom-left-radius:100%;border-bottom-right-radius:100%;background-color:#fff;color:#eee}ngx-image-tagger .tagger .pin i{font-size:18px}ngx-image-tagger .tagger .add-tag{position:absolute;z-index:1}ngx-image-tagger .tagger .add-tag .content{width:200px;background-color:#fff;padding:14px;border-radius:6px;border:1px solid #fafafa;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}ngx-image-tagger .tagger .add-tag .content input{font-size:10px}ngx-image-tagger .tagger .add-tag .content input::placeholder{font-size:10px}ngx-image-tagger .tagger .button-tag{font-size:10px!important}ngx-image-tagger .tagger .tagging.is-view{width:auto}ngx-image-tagger .tagger .tagging{position:absolute}ngx-image-tagger .tagger .tagging i{font-size:14px}ngx-image-tagger .tagger .tagging .name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}ngx-image-tagger .tagger .tagging .price{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:10px}ngx-image-tagger .tagger .tagging .link{color:#007ac1;transition:all .4s ease;font-size:10px}ngx-image-tagger .tagger .tagging .content{width:200px;background-color:#fff;padding:14px;border-radius:6px;border:1px solid #fafafa;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}ngx-image-tagger .shop{padding:7.5px 10px;cursor:pointer;color:#fff;margin-top:-6px}ngx-image-tagger .shop-icon.with-shop{bottom:10px;left:10px}ngx-image-tagger .shop-icon.without-shop{bottom:15px;left:10px}ngx-image-tagger .shop-icon{position:absolute;height:30px;display:flex;align-items:center;justify-content:center;width:30px;background-color:#fff;color:#6e6e6e;border-radius:100%;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;cursor:pointer}ngx-image-tagger .shop-icon i{font-size:16px}ngx-image-tagger .shop-icon.active{color:#444}ngx-image-tagger .shop-icon:hover{transition:all .4s ease;color:#444}\n"], dependencies: [{ kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "directive", type: i2.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i3.CurrencyMaskDirective, selector: "[currencyMask]", inputs: ["options"] }, { kind: "pipe", type: i1.CurrencyPipe, name: "currency" }], encapsulation: i0.ViewEncapsulation.None }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.4", ngImport: i0, type: NgxImageTaggerComponent, decorators: [{ type: Component, args: [{ selector: 'ngx-image-tagger', encapsulation: ViewEncapsulation.None, template: "<div class=\"tagger\" id=\"{{ tagger.idParent }}\">\n <img alt=\"Image Tagger\" id=\"{{ tagger.id }}\" [src]=\"tagger.url\" [ngClass]=\"imageClassList\"> \n <ng-container *ngIf=\"tagger?.tags && tagger.tags?.length! > 0 && onShowTagMode === 'IconClick'\">\n <div class=\"shop-icon\" [class.active]=\"isShowView\" (click)=\"isShowView = !isShowView\" [class.without-shop]=\"!isShowShop\" [class.with-shop]=\"isShowShop\">\n <i class=\"material-icons\">local_mall</i>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"isShowForm\">\n <div class=\"add-tag flex\" *ngIf=\"isAllowCreate\" [ngStyle]=\"{\n 'top.%': tagger.y , \n 'left.%': tagger.x\n }\" [class.items-start]=\"tagger.isOffsideY && !tagger.isOffsideX || tagger.isOffsideY && tagger.isOffsideX\">\n\n <div class=\"pin mr-2\"></div>\n\n <div class=\"content\">\n <ng-container *ngIf=\"placeholderCreateTitle\">\n <div class=\"mb-3 create-title\">\n {{ placeholderCreateTitle }}\n </div>\n </ng-container>\n <div>\n <input class=\"input-style\" [(ngModel)]=\"form.name\" [placeholder]=\"placeholderName\" type=\"text\" [ngClass]=\"inputClassList\">\n </div>\n <ng-container *ngIf=\"isShowPrice\">\n <div class=\"mt-2\">\n <input class=\"input-style\" [(ngModel)]=\"form.price\" currencyMask [options]=\"{ prefix: '$ ', thousands: '.', decimal: ',' }\" [placeholder]=\"placeholderPrice\" [ngClass]=\"inputClassList\">\n </div>\n </ng-container>\n <ng-container *ngIf=\"isShowLink\">\n <div class=\"mt-2\">\n <input class=\"input-style\" [(ngModel)]=\"form.url\" [placeholder]=\"placeholderLink\" type=\"email\" [ngClass]=\"inputClassList\">\n </div>\n </ng-container>\n <div class=\"mt-2 flex items-center justify-space-between gap-2\">\n <div class=\"w-half\">\n <button class=\"button-style outline\" (click)=\"isShowForm = false\" [ngStyle]=\"{ 'border-color': backgroundColor, 'color': backgroundColor }\">\n {{ buttonCancelTitle }}\n </button>\n </div>\n <div class=\"w-half\">\n <button class=\"button-style\" (click)=\"submitTag(tagger)\" [ngStyle]=\"{ 'border-color': backgroundColor, 'background': backgroundColor, 'color': textColor }\" [disabled]=\"!form.name || !form.url && isShowLink\">\n {{ buttonCreateTitle }}\n </button>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n\n <ng-container *ngIf=\"tagger.tags && isShowView\">\n <ng-container *ngFor=\"let tag of tagger.tags; let subindex = index\">\n <div class=\"tagging flex items-start\" (mouseover)=\"changeStyleHover(tag.id+subindex,true)\" (click)=\"changeStyleClick(tag.id+subindex, tag)\"\n (mouseout)=\"changeStyleHover(tag.id+subindex,false)\" [ngStyle]=\"{\n 'top.%': tag.y, \n 'left.%': tag.x\n }\">\n <div class=\"pin mr-2 pointer\">\n </div>\n <div [id]=\"tag.id+subindex\" class=\"content\" style=\"display: none;\">\n <div class=\"flex items-center justify-between gap-2\">\n <ng-container *ngIf=\"isShowThumbnail\">\n <div class=\"thumnbnail\">\n <img [src]=\"tagger.url\" [ngStyle]=\"{'object-position':''+tag.x+'% '+tag.y+'%'+'', 'object-fit': 'none'}\">\n </div>\n </ng-container>\n <div class=\"text-left\">\n <div class=\"name\">{{ tag.name }}</div>\n <div *ngIf=\"isShowPrice\" class=\"mt-1 price\" >{{ tag.price | currency:'USD' }}</div>\n <div *ngIf=\"isShowLink\" class=\"link mt-1 pointer\" (click)=\"goToTag(tag)\">Go to link</div>\n </div>\n </div>\n </div>\n </div>\n </ng-container>\n </ng-container>\n</div>\n\n<ng-container *ngIf=\"isShowShop\">\n <div class=\"shop flex items-center justify-between\" [ngStyle]=\"{ 'background': backgroundColor }\" (click)=\"goToURL(tagger.urlShop!)\">\n <div class=\"w-half flex items-center justify-content-start\">\n {{ titleShop }}\n </div>\n <div class=\"flex items-center justify-content-end w-half\">\n <i class=\"material-icons\">navigate_next</i>\n </div>\n </div>\n</ng-container>", styles: ["@import\"~material-icons/iconfont/material-icons.css\";ngx-image-tagger{font-family:inherit;font-size:12px}ngx-image-tagger .pointer{cursor:pointer}ngx-image-tagger input{width:100%}ngx-image-tagger .items-end{align-items:end}ngx-image-tagger .items-start{align-items:start}ngx-image-tagger .items-center{align-items:center}ngx-image-tagger .justify-content-start{justify-content:start}ngx-image-tagger .justify-content-center{justify-content:center}ngx-image-tagger .justify-content-end{justify-content:end}ngx-image-tagger .justify-space-between{justify-content:space-between}ngx-image-tagger .w-half{width:50%}ngx-image-tagger .ml-2{margin-left:.5rem}ngx-image-tagger .mr-2{margin-right:.5rem}ngx-image-tagger .mb-2{margin-bottom:.5rem}ngx-image-tagger .mb-3{margin-bottom:.75rem}ngx-image-tagger .mt-1{margin-top:.25rem}ngx-image-tagger .mt-2{margin-top:.5rem}ngx-image-tagger .text-left{text-align:left}ngx-image-tagger .flex{display:flex}ngx-image-tagger .flex-col{direction:column}ngx-image-tagger .gap-2{gap:.5rem}ngx-image-tagger .thumnbnail{min-width:70px!important;width:70px!important;height:70px!important}ngx-image-tagger .thumnbnail img{min-width:70px!important;width:70px!important;height:70px!important;border-radius:6px}ngx-image-tagger .create-title{font-size:14px;text-align:center}ngx-image-tagger input.input-style{padding:10px;border-radius:6px;font-size:inherit;border:2px solid #eee;outline:none;box-sizing:border-box}ngx-image-tagger button{font-size:inherit;cursor:pointer;width:100%}ngx-image-tagger .w-full{width:100%}ngx-image-tagger .button-style[disabled]{border:1px solid #eee!important;background-color:#eee!important;color:#bbb!important}ngx-image-tagger .button-style{border:1px solid;padding:6px 12px;text-align:center;text-decoration:none;display:inline-block;border-radius:6px}ngx-image-tagger .button-style.outline{border:1px solid;background:white;padding:6px 12px;text-align:center;text-decoration:none;display:inline-block;border-radius:6px}ngx-image-tagger .tagger{position:relative;height:-moz-fit-content;height:fit-content;width:-moz-fit-content;width:fit-content;display:inline-block}ngx-image-tagger .tagger img{width:100%;object-fit:contain;object-position:center;height:100%}ngx-image-tagger .tagger .pin{box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;height:15px;width:15px;border:2px solid;color:#fff;border-top-right-radius:100%;border-bottom-left-radius:100%;border-bottom-right-radius:100%;background-color:#fff;color:#eee}ngx-image-tagger .tagger .pin i{font-size:18px}ngx-image-tagger .tagger .add-tag{position:absolute;z-index:1}ngx-image-tagger .tagger .add-tag .content{width:200px;background-color:#fff;padding:14px;border-radius:6px;border:1px solid #fafafa;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}ngx-image-tagger .tagger .add-tag .content input{font-size:10px}ngx-image-tagger .tagger .add-tag .content input::placeholder{font-size:10px}ngx-image-tagger .tagger .button-tag{font-size:10px!important}ngx-image-tagger .tagger .tagging.is-view{width:auto}ngx-image-tagger .tagger .tagging{position:absolute}ngx-image-tagger .tagger .tagging i{font-size:14px}ngx-image-tagger .tagger .tagging .name{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}ngx-image-tagger .tagger .tagging .price{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-size:10px}ngx-image-tagger .tagger .tagging .link{color:#007ac1;transition:all .4s ease;font-size:10px}ngx-image-tagger .tagger .tagging .content{width:200px;background-color:#fff;padding:14px;border-radius:6px;border:1px solid #fafafa;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f}ngx-image-tagger .shop{padding:7.5px 10px;cursor:pointer;color:#fff;margin-top:-6px}ngx-image-tagger .shop-icon.with-shop{bottom:10px;left:10px}ngx-image-tagger .shop-icon.without-shop{bottom:15px;left:10px}ngx-image-tagger .shop-icon{position:absolute;height:30px;display:flex;align-items:center;justify-content:center;width:30px;background-color:#fff;color:#6e6e6e;border-radius:100%;box-shadow:0 5px 5px -3px #0003,0 8px 10px 1px #00000024,0 3px 14px 2px #0000001f;cursor:pointer}ngx-image-tagger .shop-icon i{font-size:16px}ngx-image-tagger .shop-icon.active{color:#444}ngx-image-tagger .shop-icon:hover{transition:all .4s ease;color:#444}\n"] }] }], ctorParameters: function () { return []; }, propDecorators: { isAllowCreate: [{ type: Input }], isShowThumbnail: [{ type: Input }], imageClassList: [{ type: Input }], placeholderName: [{ type: Input }], placeholderPrice: [{ type: Input }], isShowPrice: [{ type: Input }], placeholderLink: [{ type: Input }], isShowLink: [{ type: Input }], borderColor: [{ type: Input }], backgroundColor: [{ type: Input }], textColor: [{ type: Input }], inputClassList: [{ type: Input }], placeholderCreateTitle: [{ type: Input }], buttonCancelTitle: [{ type: Input }], buttonCreateTitle: [{ type: Input }], isShowShop: [{ type: Input }], titleShop: [{ type: Input }], onShowTagMode: [{ type: Input }], tagger: [{ type: Input }], taggerChange: [{ type: Output }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWltYWdlLXRhZ2dlci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wYWNrYWdlcy9uZ3gtaW1hZ2UtdGFnZ2VyL3NyYy9saWIvbmd4LWltYWdlLXRhZ2dlci5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi9wYWNrYWdlcy9uZ3gtaW1hZ2UtdGFnZ2VyL3NyYy9saWIvbmd4LWltYWdlLXRhZ2dlci5jb21wb25lbnQuaHRtbCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxLQUFLLEVBQVUsTUFBTSxFQUFFLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxNQUFNLENBQUM7Ozs7O0FBVWpDLE1BQU0sT0FBTyx1QkFBdUI7SUFpRGxDO1FBaERBLGtCQUFhLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLGlCQUFZLEdBQUcsQ0FBQyxDQUFDO1FBRVIsa0JBQWEsR0FBRyxLQUFLLENBQUM7UUFDdEIsb0JBQWUsR0FBRyxJQUFJLENBQUM7UUFDdkIsbUJBQWMsR0FBRyxFQUFFLENBQUM7UUFFcEIsb0JBQWUsR0FBRyxNQUFNLENBQUM7UUFFekIscUJBQWdCLEdBQUcsT0FBTyxDQUFDO1FBQzNCLGdCQUFXLEdBQUcsSUFBSSxDQUFDO1FBRW5CLG9CQUFlLEdBQUcsTUFBTSxDQUFDO1FBQ3pCLGVBQVUsR0FBRyxJQUFJLENBQUM7UUFFbEIsZ0JBQVcsR0FBRyxTQUFTLENBQUM7UUFDeEIsb0JBQWUsR0FBRyxTQUFTLENBQUM7UUFDNUIsY0FBUyxHQUFHLFNBQVMsQ0FBQztRQUV0QixtQkFBYyxHQUFHLEVBQUUsQ0FBQztRQUVwQiwyQkFBc0IsR0FBRyxtQkFBbUIsQ0FBQztRQUM3QyxzQkFBaUIsR0FBRyxRQUFRLENBQUM7UUFDN0Isc0JBQWlCLEdBQUcsUUFBUSxDQUFDO1FBRTdCLGVBQVUsR0FBRyxLQUFL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QixLQUFLO2dCQUNHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBRUcsZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxVQUFVO3NCQUFsQixLQUFLO2dCQUVHLFdBQVc7c0JBQW5CLEtBQUs7Z0JBQ0csZUFBZTtzQkFBdkIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLGNBQWM7c0JBQXRCLEtBQUs7Z0JBRUcsc0JBQXNCO3NCQUE5QixLQUFLO2dCQUNHLGlCQUFpQjtzQkFBekIsS0FBSztnQkFDRyxpQkFBaUI7c0JBQXpCLEtBQUs7Z0JBRUcsVUFBVTtzQkFBbEIsS0FBSztnQkFDRyxTQUFTO3NCQUFqQixLQUFLO2dCQUVHLGFBQWE7c0JBQXJCLEtBQUs7Z0JBRUcsTUFBTTtzQkFBZCxLQUFLO2dCQVlJLFlBQVk7c0JBQXJCLE1BQU0iLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uSW5pdCwgT3V0cHV0LCBWaWV3RW5jYXBzdWxhdGlvbiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgZnJvbUV2ZW50IH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IFRhZ2dlZCwgVGFnZ2VyTW9kZWwgfSBmcm9tICcuL21vZGVsL3RhZyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC1pbWFnZS10YWdnZXInLFxuICB0ZW1wbGF0ZVVybDogJy4vbmd4LWltYWdlLXRhZ2dlci5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL25neC1pbWFnZS10YWdnZXIuY29tcG9uZW50LnNjc3MnXSxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbn0pXG5leHBvcnQgY2xhc3MgTmd4SW1hZ2VUYWdnZXJDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQge1xuICBoZWlnaHRFbGVtZW50ID0gMDtcbiAgd2lkdGhFbGVtZW50ID0gMDtcblxuICBASW5wdXQoKSBpc0FsbG93Q3JlYXRlID0gZmFsc2U7XG4gIEBJbnB1dCgpIGlzU2hvd1RodW1ibmFpbCA9IHRydWU7XG4gIEBJbnB1dCgpIGltYWdlQ2xhc3NMaXN0ID0gXCJcIjtcblxuICBASW5wdXQoKSBwbGFjZWhvbGRlck5hbWUgPSAnTmFtZSc7XG5cbiAgQElucHV0KCkgcGxhY2Vob2xkZXJQcmljZSA9ICdQcmljZSc7XG4gIEBJbnB1dCgpIGlzU2hvd1ByaWNlID0gdHJ1ZTtcblxuICBASW5wdXQoKSBwbGFjZWhvbGRlckxpbmsgPSAnTGluayc7XG4gIEBJbnB1dCgpIGlzU2hvd0xpbmsgPSB0cnVlO1xuXG4gIEBJbnB1dCgpIGJvcmRlckNvbG9yID0gXCIjMDA3YWMxXCI7XG4gIEBJbnB1dCgpIGJhY2tncm91bmRDb2xvciA9IFwiIzAzYTlmNFwiO1xuICBASW5wdXQoKSB0ZXh0Q29sb3IgPSBcIiNmZmZmZmZcIjtcblxuICBASW5wdXQoKSBpbnB1dENsYXNzTGlzdCA9IFwiXCI7XG5cbiAgQElucHV0KCkgcGxhY2Vob2xkZXJDcmVhdGVUaXRsZSA9ICdUYWcgeW91ciBwcm9kdWN0ISc7XG4gIEBJbnB1dCgpIGJ1dHRvbkNhbmNlbFRpdGxlID0gXCJDYW5jZWxcIjtcbiAgQElucHV0KCkgYnV0dG9uQ3JlYXRlVGl0bGUgPSBcIkNyZWF0ZVwiO1xuXG4gIEBJbnB1dCgpIGlzU2hvd1Nob3AgPSBmYWxzZTtcbiAgQElucHV0KCkgdGl0bGVTaG9wID0gXCJHbyB0byBzaG9wXCI7XG5cbiAgQElucHV0KCkgb25TaG93VGFnTW9kZTogXCJIb3ZlclwiIHwgXCJDbGlja1wiIHwgXCJJY29uQ2xpY2tcIiA9IFwiSG92ZXJcIjtcblxuICBASW5wdXQoKSB0YWdnZXI6IFRhZ2dlck1vZGVsID0ge1xuICAgIGlkUGFyZW50OiAnaW1hZ2UtcGFyZW50JyxcbiAgICBpZDogJ2ltYWdlJyxcbiAgICBzdHlsZTogJycsXG4gICAgdXJsU2hvcDogJycsXG4gICAgaXNPZmZzaWRlWDogZmFsc2UsXG4gICAgaXNPZmZzaWRlWTogZmFsc2UsXG4gICAgeDogMCxcbiAgICB5OiAwLFxuICAgIHVybDogJycsXG4gICAgdGFnczogW11cbiAgfVxuICBAT3V0cHV0KCkgdGFnZ2VyQ2hhbmdlOiBFdmVudEVtaXR0ZXI8VGFnZ2VyTW9kZWw+ID0gbmV3IEV2ZW50RW1pdHRlcjxUYWdnZXJNb2RlbD4oKTtcblxuICBpc1Nob3dGb3JtID0gZmFsc2U7XG4gIGlzU2hvd1ZpZXcgPSB0cnVlO1xuICBmb3JtITogVGFnZ2VkO1xuXG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIGZyb21FdmVudChkb2N1bWVudC5ib2R5LCAnbW91c2Vkb3duJykuc3Vic2NyaWJlKChldmVudDogYW55KSA9PiB7XG4gICAgICBjb25zdCBlbGVtZW50SWQgPSAoZXZlbnQudGFyZ2V0IGFzIEVsZW1lbnQpLmlkO1xuICAgICAgaWYgKHRoaXMudGFnZ2VyICYmIGVsZW1lbnRJZCA9PT0gdGhpcy50YWdnZXIuaWQpIHtcbiAgICAgICAgdGhpcy5yZXNldFRhZygpO1xuXG4gICAgICAgIGNvbnN0IHggPSBldmVudC5sYXllclg7XG4gICAgICAgIGNvbnN0IHkgPSBldmVudC5sYXllclkgLSA2O1xuXG4gICAgICAgIHRoaXMuaGVpZ2h0RWxlbWVudCA9IGV2ZW50Py5zcmNFbGVtZW50Py5vZmZzZXRIZWlnaHQ7XG4gICAgICAgIGNvbnN0IGhhbGZZID0gdGhpcy5oZWlnaHRFbGVtZW50IC8gMjtcbiAgICAgICAgaWYgKGhhbGZZIDwgeSkge1xuICAgICAgICAgIHRoaXMudGFnZ2VyLmlzT2Zmc2lkZVkgPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMudGFnZ2VyLmlzT2Zmc2lkZVkgPSBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMud2lkdGhFbGVtZW50ID0gZXZlbnQ/LnNyY0VsZW1lbnQ/Lm9mZnNldFdpZHRoO1xuICAgICAgICBjb25zdCBoYWxmWCA9IHRoaXMud2lkdGhFbGVtZW50IC8gMjtcbiAgICAgICAgaWYgKGhhbGZYIDwgeCkge1xuICAgICAgICAgIHRoaXMudGFnZ2VyLmlzT2Zmc2lkZVggPSB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMudGFnZ2VyLmlzT2Zmc2lkZVggPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICB0aGlzLnRhZ2dlci54ID0gKHggKiAxMDApIC8gdGhpcy53aWR0aEVsZW1lbnQ7XG4gICAgICAgIHRoaXMudGFnZ2VyLnkgPSAoeSAqIDEwMCkgLyB0aGlzLmhlaWdodEVsZW1lbnQ7XG4gICAgICAgIHRoaXMuaXNTaG93Rm9ybSA9IHRydWU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLmZvcm0gPSB7XG4gICAgICBpZDogJycsXG4gICAgICB4OiAwLFxuICAgICAgeTogMCxcbiAgICAgIGlzT2Zmc2lkZVg6IGZhbHNlLFxuICAgICAgaXNPZmZzaWRlWTogZmFsc2UsXG4gICAgICB0YWdnZXI6IHRoaXMudGFnZ2VyLFxuICAgICAgb3BlbjogZmFsc2UsXG4gICAgfVxuXG4gICAgaWYgKHRoaXMub25TaG93VGFnTW9kZSA9PT0gJ0ljb25DbGljaycpIHtcbiAgICAgIHRoaXMuaXNTaG93VmlldyA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGNoYW5nZVN0eWxlQ2xpY2soaWQ6IHN0cmluZywgdGFnOiBUYWdnZWQpIHtcbiAgICBpZiAodGhpcy5vblNob3dUYWdNb2RlICE9ICdDbGljaycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0YWcub3BlbiA9ICF0YWcub3BlbjtcbiAgICB0aGlzLm9uU2hvd1N0eWxlKGlkLCB0YWcub3Blbik7XG4gIH1cblxuICBjaGFuZ2VTdHlsZUhvdmVyKGlkOiBzdHJpbmcsIHNob3c6IGJvb2xlYW4pIHtcbiAgICBpZiAodGhpcy5vblNob3dUYWdNb2RlID09ICdDbGljaycpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5vblNob3dTdHlsZShpZCwgc2hvdyk7XG4gIH1cblxuICBvblNob3dTdHlsZShpZDogc3RyaW5nLCBzaG93OiBib29sZWFuKSB7XG4gICAgY29uc3QgZWwgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZChpZClcbiAgICBpZiAoZWwpIHtcbiAgICAgIGlmIChzaG93KSB7XG4gICAgICAgIGVsLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCJcbiAgICAgICAgZWwuc3R5bGUuekluZGV4ID0gXCIxMDBcIlxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZWwuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiXG4gICAgICAgIGVsLnN0eWxlLnpJbmRleCA9IFwiMVwiXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ29Ub1VSTCh1cmw6IHN0cmluZykge1xuICAgIHdpbmRvdy5vcGVuKHVybCwgXCJfYmxhbmtcIik7XG4gIH1cblxuICBnb1RvVGFnKGl0ZW06IFRhZ2dlZCkge1xuICAgIHdpbmRvdy5vcGVuKGl0ZW0udXJsLCBcIl9ibGFua1wiKTtcbiAgfVxuXG4gIHJlc2V0VGFnKCkge1xuICAgIHRoaXMuZm9ybS5uYW1lID0gJyc7XG4gICAgdGhpcy5mb3JtLnByaWNlID0gMDtcbiAgICB0aGlzLmZvcm0udXJsID0gJyc7XG4gICAgdGhpcy5pc1Nob3dGb3JtID0gZmFsc2U7XG4gIH1cblxuICBzdWJtaXRUYWcoaXRlbTogVGFnZ2VyTW9kZWwpIHtcbiAgICBpZiAoaXRlbSkge1xuICAgICAgbGV0IGlzT2Zmc2lkZVggPSBmYWxzZTtcbiAgICAgIGxldCBpc09mZnNpZGVZID0gZmFsc2U7XG5cbiAgICAgIGlmIChpdGVtPy54ISA+IDUwKSB7XG4gICAgICAgIGlzT2Zmc2lkZVggPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXNPZmZzaWRlWCA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAoaXRlbT8ueSEgPiAwKSB7XG4gICAgICAgIGlzT2Zmc2lkZVkgPSB0cnVlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaXNPZmZzaWRlWSA9IGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpdGVtLnRhZ3MucHVzaCh7XG4gICAgICAgIGlkOiBcIlwiLCBuYW1lOiB0aGlzLmZvcm0ubmFtZSwgdXJsOiB0aGlzLmZvcm0udXJsLCB4OiBpdGVtLnghLCB5OiBpdGVtLnkhLCBpc09mZnNpZGVYLCBpc09mZnNpZGVZLFxuICAgICAgICBvcGVuOiBmYWxzZSxcbiAgICAgICAgcHJpY2U6IHRoaXMuZm9ybS5wcmljZSxcbiAgICAgICAgdGFnZ2VyOiBPYmplY3QuYXNzaWduKHRoaXMudGFnZ2VyKSxcbiAgICAgIH0pO1xuICAgICAgdGhpcy5yZXNldFRhZygpO1xuICAgICAgdGhpcy50YWdnZXJDaGFuZ2UubmV4dCh0aGlzLnRhZ2dlcik7XG4gICAgfVxuICB9XG5cbiAgZWRpdFRhZyhpdGVtOiBUYWdnZXJNb2RlbCwgdGFnOiBUYWdnZWQsIHN1YmluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLmZvcm0ubmFtZSA9IHRhZz8ubmFtZSE7XG4gICAgdGhpcy5mb3JtLnVybCA9IHRhZz8udXJsITtcblxuICAgIHRoaXMudGFnZ2VyLnggPSB0YWcueDtcbiAgICB0aGlzLnRhZ2dlci55ID0gdGFnLnk7XG4gICAgdGhpcy50YWdnZXIuaXNPZmZzaWRlWCA9IHRhZy5pc09mZnNpZGVYXG4gICAgdGhpcy50YWdnZXIuaXNPZmZzaWRlWSA9IHRhZy5pc09mZnNpZGVZO1xuXG4gICAgdGhpcy5pc1Nob3dGb3JtID0gdHJ1ZTtcbiAgICB0aGlzLnRhZ2dlckNoYW5nZS5uZXh0KHRoaXMudGFnZ2VyKTtcbiAgfVxuXG4gIGRlbGV0ZVRhZyhpdGVtOiBUYWdnZXJNb2RlbCwgdGFnOiBUYWdnZWQsIHN1YmluZGV4OiBudW1iZXIpIHtcbiAgICB0aGlzLnRhZ2dlci50YWdzLnNwbGljZShzdWJpbmRleCwgMSk7XG4gICAgdGhpcy50YWdnZXJDaGFuZ2UubmV4dCh0aGlzLnRhZ2dlcik7XG4gIH1cbn1cbiIsIjxkaXYgY2xhc3M9XCJ0YWdnZXJcIiBpZD1cInt7IHRhZ2dlci5pZFBhcmVudCB9fVwiPlxuICA8aW1nIGFsdD1cIkltYWdlIFRhZ2dlclwiIGlkPVwie3sgdGFnZ2VyLmlkIH19XCIgW3NyY109XCJ0YWdnZXIudXJsXCIgW25nQ2xhc3NdPVwiaW1hZ2VDbGFzc0xpc3RcIj4gXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0YWdnZXI/LnRhZ3MgJiYgdGFnZ2VyLnRhZ3M/Lmxlbmd0aCEgPiAwICYmIG9uU2hvd1RhZ01vZGUgPT09ICdJY29uQ2xpY2snXCI+XG4gICAgPGRpdiBjbGFzcz1cInNob3AtaWNvblwiIFtjbGFzcy5hY3RpdmVdPVwiaXNTaG93Vmlld1wiIChjbGljayk9XCJpc1Nob3dWaWV3ID0gIWlzU2hvd1ZpZXdcIiBbY2xhc3Mud2l0aG91dC1zaG9wXT1cIiFpc1Nob3dTaG9wXCIgW2NsYXNzLndpdGgtc2hvcF09XCJpc1Nob3dTaG9wXCI+XG4gICAgICA8aSBjbGFzcz1cIm1hdGVyaWFsLWljb25zXCI+bG9jYWxfbWFsbDwvaT5cbiAgICA8L2Rpdj5cbiAgPC9uZy1jb250YWluZXI+XG5cbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImlzU2hvd0Zvcm1cIj5cbiAgICA8ZGl2IGNsYXNzPVwiYWRkLXRhZyBmbGV4XCIgKm5nSWY9XCJpc0FsbG93Q3JlYXRlXCIgW25nU3R5bGVdPVwie1xuICAgICAgICAndG9wLiUnOiB0YWdnZXIueSAsIFxuICAgICAgICAnbGVmdC4lJzogdGFnZ2VyLnhcbiAgICB9XCIgW2NsYXNzLml0ZW1zLXN0YXJ0XT1cInRhZ2dlci5pc09mZnNpZGVZICYmICF0YWdnZXIuaXNPZmZzaWRlWCB8fCB0YWdnZXIuaXNPZmZzaWRlWSAmJiB0YWdnZXIuaXNPZmZzaWRlWFwiPlxuXG4gICAgICA8ZGl2IGNsYXNzPVwicGluIG1yLTJcIj48L2Rpdj5cblxuICAgICAgPGRpdiBjbGFzcz1cImNvbnRlbnRcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInBsYWNlaG9sZGVyQ3JlYXRlVGl0bGVcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibWItMyBjcmVhdGUtdGl0bGVcIj5cbiAgICAgICAgICAgIHt7IHBsYWNlaG9sZGVyQ3JlYXRlVGl0bGUgfX1cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxkaXY+XG4gICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wdXQtc3R5bGVcIiBbKG5nTW9kZWwpXT1cImZvcm0ubmFtZVwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlck5hbWVcIiB0eXBlPVwidGV4dFwiIFtuZ0NsYXNzXT1cImlucHV0Q2xhc3NMaXN0XCI+XG4gICAgICAgIDwvZGl2PlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNTaG93UHJpY2VcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwibXQtMlwiPlxuICAgICAgICAgICAgPGlucHV0IGNsYXNzPVwiaW5wdXQtc3R5bGVcIiBbKG5nTW9kZWwpXT1cImZvcm0ucHJpY2VcIiBjdXJyZW5jeU1hc2sgW29wdGlvbnNdPVwieyBwcmVmaXg6ICckICcsIHRob3VzYW5kczogJy4nLCBkZWNpbWFsOiAnLCcgfVwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlclByaWNlXCIgW25nQ2xhc3NdPVwiaW5wdXRDbGFzc0xpc3RcIj5cbiAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJpc1Nob3dMaW5rXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cIm10LTJcIj5cbiAgICAgICAgICAgIDxpbnB1dCBjbGFzcz1cImlucHV0LXN0eWxlXCIgWyhuZ01vZGVsKV09XCJmb3JtLnVybFwiIFtwbGFjZWhvbGRlcl09XCJwbGFjZWhvbGRlckxpbmtcIiB0eXBlPVwiZW1haWxcIiBbbmdDbGFzc109XCJpbnB1dENsYXNzTGlzdFwiPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPGRpdiBjbGFzcz1cIm10LTIgZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1zcGFjZS1iZXR3ZWVuIGdhcC0yXCI+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInctaGFsZlwiPlxuICAgICAgICAgICAgPGJ1dHRvbiBjbGFzcz1cImJ1dHRvbi1zdHlsZSBvdXRsaW5lXCIgKGNsaWNrKT1cImlzU2hvd0Zvcm0gPSBmYWxzZVwiIFtuZ1N0eWxlXT1cInsgJ2JvcmRlci1jb2xvcic6IGJhY2tncm91bmRDb2xvciwgJ2NvbG9yJzogYmFja2dyb3VuZENvbG9yIH1cIj5cbiAgICAgICAgICAgICAge3sgYnV0dG9uQ2FuY2VsVGl0bGUgfX1cbiAgICAgICAgICAgIDwvYnV0dG9uPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxkaXYgY2xhc3M9XCJ3LWhhbGZcIj5cbiAgICAgICAgICAgIDxidXR0b24gY2xhc3M9XCJidXR0b24tc3R5bGVcIiAoY2xpY2spPVwic3VibWl0VGFnKHRhZ2dlcilcIiBbbmdTdHlsZV09XCJ7ICdib3JkZXItY29sb3InOiBiYWNrZ3JvdW5kQ29sb3IsICdiYWNrZ3JvdW5kJzogYmFja2dyb3VuZENvbG9yLCAnY29sb3InOiB0ZXh0Q29sb3IgIH1cIiBbZGlzYWJsZWRdPVwiIWZvcm0ubmFtZSB8fCAhZm9ybS51cmwgJiYgaXNTaG93TGlua1wiPlxuICAgICAgICAgICAgICB7eyBidXR0b25DcmVhdGVUaXRsZSB9fVxuICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvbmctY29udGFpbmVyPlxuXG4gIDxuZy1jb250YWluZXIgKm5nSWY9XCJ0YWdnZXIudGFncyAmJiBpc1Nob3dWaWV3XCI+XG4gICAgPG5nLWNvbnRhaW5lciAqbmdGb3I9XCJsZXQgdGFnIG9mIHRhZ2dlci50YWdzOyBsZXQgc3ViaW5kZXggPSBpbmRleFwiPlxuICAgICAgPGRpdiBjbGFzcz1cInRhZ2dpbmcgZmxleCBpdGVtcy1zdGFydFwiIChtb3VzZW92ZXIpPVwiY2hhbmdlU3R5bGVIb3Zlcih0YWcuaWQrc3ViaW5kZXgsdHJ1ZSlcIiAoY2xpY2spPVwiY2hhbmdlU3R5bGVDbGljayh0YWcuaWQrc3ViaW5kZXgsIHRhZylcIlxuICAgICAgICAobW91c2VvdXQpPVwiY2hhbmdlU3R5bGVIb3Zlcih0YWcuaWQrc3ViaW5kZXgsZmFsc2UpXCIgW25nU3R5bGVdPVwie1xuICAgICAgICAgICd0b3AuJSc6IHRhZy55LCBcbiAgICAgICAgICAnbGVmdC4lJzogdGFnLnhcbiAgICAgICAgICAgIH1cIj5cbiAgICAgICAgPGRpdiBjbGFzcz1cInBpbiBtci0yIHBvaW50ZXJcIj5cbiAgICAgICAgPC9kaXY+XG4gICAgICAgIDxkaXYgW2lkXT1cInRhZy5pZCtzdWJpbmRleFwiIGNsYXNzPVwiY29udGVudFwiIHN0eWxlPVwiZGlzcGxheTogbm9uZTtcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiZmxleCBpdGVtcy1jZW50ZXIganVzdGlmeS1iZXR3ZWVuIGdhcC0yXCI+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiaXNTaG93VGh1bWJuYWlsXCI+XG4gICAgICAgICAgICAgIDxkaXYgY2xhc3M9XCJ0aHVtbmJuYWlsXCI+XG4gICAgICAgICAgICAgICAgPGltZyBbc3JjXT1cInRhZ2dlci51cmxcIiBbbmdTdHlsZV09XCJ7J29iamVjdC1wb3NpdGlvbic6JycrdGFnLngrJyUgJyt0YWcueSsnJScrJycsICdvYmplY3QtZml0JzogJ25vbmUnfVwiPlxuICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cInRleHQtbGVmdFwiPlxuICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwibmFtZVwiPnt7IHRhZy5uYW1lIH19PC9kaXY+XG4gICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJpc1Nob3dQcmljZVwiIGNsYXNzPVwibXQtMSBwcmljZVwiID57eyB0YWcucHJpY2UgfCBjdXJyZW5jeTonVVNEJyB9fTwvZGl2PlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiaXNTaG93TGlua1wiIGNsYXNzPVwibGluayBtdC0xIHBvaW50ZXJcIiAoY2xpY2spPVwiZ29Ub1RhZyh0YWcpXCI+R28gdG8gbGluazwvZGl2PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgPC9uZy1jb250YWluZXI+XG4gIDwvbmctY29udGFpbmVyPlxuPC9kaXY+XG5cbjxuZy1jb250YWluZXIgKm5nSWY9XCJpc1Nob3dTaG9wXCI+XG4gIDxkaXYgY2xhc3M9XCJzaG9wIGZsZXggaXRlbXMtY2VudGVyIGp1c3RpZnktYmV0d2VlblwiICBbbmdTdHlsZV09XCJ7ICdiYWNrZ3JvdW5kJzogYmFja2dyb3VuZENvbG9yIH1cIiAoY2xpY2spPVwiZ29Ub1VSTCh0YWdnZXIudXJsU2hvcCEpXCI+XG4gICAgPGRpdiBjbGFzcz1cInctaGFsZiBmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtc3RhcnRcIj5cbiAgICAgIHt7IHRpdGxlU2hvcCB9fVxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJmbGV4IGl0ZW1zLWNlbnRlciBqdXN0aWZ5LWNvbnRlbnQtZW5kIHctaGFsZlwiPlxuICAgICAgPGkgY2xhc3M9XCJtYXRlcmlhbC1pY29uc1wiPm5hdmlnYXRlX25leHQ8L2k+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9uZy1jb250YWluZXI+Il19