ngx-kit 9.2.4 → 9.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { output, HostListener, Directive, InjectionToken, input, inject, signal, viewChild, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { output, HostListener, Directive, InjectionToken, input, inject, DOCUMENT, signal, viewChild, computed, effect, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import * as i1 from '@angular/forms';
4
4
  import { FormsModule } from '@angular/forms';
5
5
  import { SliderComponent } from 'ngx-kit/core';
@@ -104,9 +104,9 @@ function canvasToBlob(canvas, type = 'image/jpeg', quality = 0.92) {
104
104
  * کراپ روون بمونه؛ خروجی نهایی (save) همیشه از روی تصویر اصلیِ کامل رندر
105
105
  * می‌شه، نه از روی این کپی.
106
106
  */
107
- function createWorkingCopy(img, maxSize = 1200) {
107
+ function createWorkingCopy(doc, img, maxSize = 1200) {
108
108
  const { width, height } = fitWithin(img.naturalWidth, img.naturalHeight, maxSize, maxSize);
109
- const canvas = document.createElement('canvas');
109
+ const canvas = doc.createElement('canvas');
110
110
  canvas.width = width;
111
111
  canvas.height = height;
112
112
  const ctx = canvas.getContext('2d');
@@ -187,13 +187,13 @@ function applyCartoonEffect(ctx, width, height, options = {}) {
187
187
  }
188
188
 
189
189
  /** تصویر مبدأ رو با زاویه‌ی داده‌شده روی یه canvas جدید (به اندازه‌ی bounding-box نتیجه) می‌چرخونه */
190
- function renderRotated(source, width, height, degrees) {
190
+ function renderRotated(doc, source, width, height, degrees) {
191
191
  const rad = (degrees * Math.PI) / 180;
192
192
  const sin = Math.abs(Math.sin(rad));
193
193
  const cos = Math.abs(Math.cos(rad));
194
194
  const newW = Math.max(1, Math.round(width * cos + height * sin));
195
195
  const newH = Math.max(1, Math.round(width * sin + height * cos));
196
- const canvas = document.createElement('canvas');
196
+ const canvas = doc.createElement('canvas');
197
197
  canvas.width = newW;
198
198
  canvas.height = newH;
199
199
  const ctx = canvas.getContext('2d');
@@ -226,9 +226,9 @@ function buildCssFilter(adjustments) {
226
226
  * برای واکنش‌گرا موندن حین کشیدن اسلایدرها) و خروجی نهایی (بدون محدودیت یا
227
227
  * محدودیت دلخواه کاربر).
228
228
  */
229
- function renderComposite(source, sourceWidth, sourceHeight, crop, adjustments, maxWidth, maxHeight) {
229
+ function renderComposite(doc, source, sourceWidth, sourceHeight, crop, adjustments, maxWidth, maxHeight) {
230
230
  const { width: outW, height: outH } = fitWithin(crop.width, crop.height, maxWidth, maxHeight);
231
- const canvas = document.createElement('canvas');
231
+ const canvas = doc.createElement('canvas');
232
232
  canvas.width = Math.max(1, outW);
233
233
  canvas.height = Math.max(1, outH);
234
234
  const ctx = canvas.getContext('2d');
@@ -287,6 +287,7 @@ class NgxImageEditor {
287
287
  defaultLocalization = inject(NGX_IMAGE_EDITOR_LOCALIZATION);
288
288
  localize = input(this.defaultLocalization, /* @ts-ignore */
289
289
  ...(ngDevMode ? [{ debugName: "localize" }] : /* istanbul ignore next */ []));
290
+ doc = inject(DOCUMENT);
290
291
  saved = output();
291
292
  cancelled = output();
292
293
  loading = signal(false, /* @ts-ignore */
@@ -340,7 +341,7 @@ class NgxImageEditor {
340
341
  const wc = this.workingCanvas();
341
342
  if (!wc)
342
343
  return null;
343
- return renderRotated(wc, wc.width, wc.height, this.rotation());
344
+ return renderRotated(this.doc, wc, wc.width, wc.height, this.rotation());
344
345
  }, /* @ts-ignore */
345
346
  ...(ngDevMode ? [{ debugName: "rotatedWorkingCanvas" }] : /* istanbul ignore next */ []));
346
347
  panelSize = computed(() => {
@@ -388,7 +389,7 @@ class NgxImageEditor {
388
389
  const c = this.crop();
389
390
  if (!rc || c.width <= 0 || c.height <= 0)
390
391
  return null;
391
- const canvas = renderComposite(rc, rc.width, rc.height, c, this.adjustments(), 480, 480);
392
+ const canvas = renderComposite(this.doc, rc, rc.width, rc.height, c, this.adjustments(), 480, 480);
392
393
  return canvas.toDataURL('image/png');
393
394
  }, /* @ts-ignore */
394
395
  ...(ngDevMode ? [{ debugName: "previewUrl" }] : /* istanbul ignore next */ []));
@@ -408,7 +409,7 @@ class NgxImageEditor {
408
409
  loadImage(src)
409
410
  .then((img) => {
410
411
  this.originalImage.set(img);
411
- this.workingCanvas.set(createWorkingCopy(img));
412
+ this.workingCanvas.set(createWorkingCopy(this.doc, img));
412
413
  this.resetAdjustments();
413
414
  })
414
415
  .catch((err) => this.loadError.set(err?.message ?? 'Failed to load image'))
@@ -534,7 +535,7 @@ class NgxImageEditor {
534
535
  // اصلیِ کامل. چون createWorkingCopy مقیاس یکنواخت (هم‌جهت) اعمال
535
536
  // می‌کنه، همین یه ضریب برای هر دو بعد و بعد از چرخش هم معتبر می‌مونه.
536
537
  const scaleToOriginal = original.naturalWidth / working.width;
537
- const rotatedFull = renderRotated(original, original.naturalWidth, original.naturalHeight, this.rotation());
538
+ const rotatedFull = renderRotated(this.doc, original, original.naturalWidth, original.naturalHeight, this.rotation());
538
539
  const c = this.crop();
539
540
  const cropInFullRes = {
540
541
  x: c.x * scaleToOriginal,
@@ -542,7 +543,7 @@ class NgxImageEditor {
542
543
  width: c.width * scaleToOriginal,
543
544
  height: c.height * scaleToOriginal,
544
545
  };
545
- const finalCanvas = renderComposite(rotatedFull, rotatedFull.width, rotatedFull.height, cropInFullRes, this.adjustments(), this.outputMaxWidth(), this.outputMaxHeight());
546
+ const finalCanvas = renderComposite(this.doc, rotatedFull, rotatedFull.width, rotatedFull.height, cropInFullRes, this.adjustments(), this.outputMaxWidth(), this.outputMaxHeight());
546
547
  const type = this.outputType();
547
548
  const blob = await canvasToBlob(finalCanvas, type, this.quality());
548
549
  const dataUrl = finalCanvas.toDataURL(type, this.quality());
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-kit-image-editor.mjs","sources":["../../../projects/libs/image-editor/directives/pointer-drag.directive.ts","../../../projects/libs/image-editor/utils/image-io.ts","../../../projects/libs/image-editor/utils/cartoonify.ts","../../../projects/libs/image-editor/utils/render-pipeline.ts","../../../projects/libs/image-editor/tokens/localization.ts","../../../projects/libs/image-editor/components/image-editor.component.ts","../../../projects/libs/image-editor/components/image-editor.component.html","../../../projects/libs/image-editor/ngx-kit-image-editor.ts"],"sourcesContent":["import { Directive, HostListener, output } from '@angular/core';\n\nexport interface NgxPointerDragDelta {\n dx: number;\n dy: number;\n}\n\n/**\n * درگ عمومی روی پایه‌ی Pointer Events + setPointerCapture (دقیقاً همون\n * تکنیکی که در ngx-kit/data-table برای ریسایز ستون استفاده شده) — نیازی به\n * listener سطح document نداره چون بعد از setPointerCapture، رویدادهای\n * pointermove/pointerup حتی بیرون از محدوده‌ی المنت هم به خودش می‌رسن.\n *\n * dx/dy تجمعی از لحظه‌ی pointerdown هستن (نه دلتای بین دو move متوالی)، چون\n * معمولاً مصرف‌کننده می‌خواد «موقعیت شروع + دلتای کل» رو حساب کنه، نه جمع\n * تدریجی گرد شونده‌ی دلتاهای ریز.\n */\n@Directive({\n selector: '[ngxPointerDrag]',\n standalone: true,\n})\nexport class NgxPointerDragDirective {\n dragStart = output<void>();\n dragMove = output<NgxPointerDragDelta>();\n dragEnd = output<void>();\n\n private dragging = false;\n private startX = 0;\n private startY = 0;\n\n @HostListener('pointerdown', ['$event'])\n onPointerDown(ev: PointerEvent): void {\n ev.preventDefault();\n ev.stopPropagation();\n this.dragging = true;\n this.startX = ev.clientX;\n this.startY = ev.clientY;\n (ev.target as HTMLElement).setPointerCapture(ev.pointerId);\n this.dragStart.emit();\n }\n\n @HostListener('pointermove', ['$event'])\n onPointerMove(ev: PointerEvent): void {\n if (!this.dragging) return;\n this.dragMove.emit({ dx: ev.clientX - this.startX, dy: ev.clientY - this.startY });\n }\n\n @HostListener('pointerup')\n @HostListener('pointercancel')\n onPointerUp(): void {\n if (!this.dragging) return;\n this.dragging = false;\n this.dragEnd.emit();\n }\n}\n","/** یه File/Blob/data-URL/URL رو به یک HTMLImageElement بارگذاری‌شده تبدیل می‌کنه */\nexport function loadImage(source: File | Blob | string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n // برای URLهای cross-origin لازم می‌شه، وگرنه canvas بعداً «tainted» می‌شه\n // و toBlob/toDataURL با SecurityError شکست می‌خوره.\n img.crossOrigin = 'anonymous';\n\n const objectUrl = typeof source === 'string' ? null : URL.createObjectURL(source);\n const url = objectUrl ?? (source as string);\n\n img.onload = () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n resolve(img);\n };\n img.onerror = () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n reject(new Error('Failed to load image'));\n };\n img.src = url;\n });\n}\n\n/** canvas.toBlob به‌صورت Promise، به‌همراه fallback برای مرورگرهای قدیمی‌تر */\nexport function canvasToBlob(\n canvas: HTMLCanvasElement,\n type = 'image/jpeg',\n quality = 0.92,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (blob) resolve(blob);\n else reject(new Error('Failed to convert canvas to blob'));\n },\n type,\n quality,\n );\n });\n}\n\n/**\n * یه کپیِ کوچیک‌شده از تصویر اصلی می‌سازه که کل UI ویرایشگر (چرخش، کراپ،\n * پیش‌نمایش فیلترها/کارتونی) روی همین کار می‌کنه، نه روی تصویر اصلی که\n * ممکنه چند مگاپیکسل باشه. این باعث می‌شه درگ‌کردنِ اسلایدرها یا لبه‌های\n * کراپ روون بمونه؛ خروجی نهایی (save) همیشه از روی تصویر اصلیِ کامل رندر\n * می‌شه، نه از روی این کپی.\n */\nexport function createWorkingCopy(img: HTMLImageElement, maxSize = 1200): HTMLCanvasElement {\n const { width, height } = fitWithin(img.naturalWidth, img.naturalHeight, maxSize, maxSize);\n const canvas = document.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(img, 0, 0, width, height);\n return canvas;\n}\n\n/** ابعاد جدید رو طوری حساب می‌کنه که از maxWidth/maxHeight بیشتر نشه، با حفظ نسبت تصویر */\nexport function fitWithin(\n width: number,\n height: number,\n maxWidth?: number,\n maxHeight?: number,\n): { width: number; height: number } {\n if (!maxWidth && !maxHeight) return { width, height };\n let ratio = 1;\n if (maxWidth) ratio = Math.min(ratio, maxWidth / width);\n if (maxHeight) ratio = Math.min(ratio, maxHeight / height);\n if (ratio >= 1) return { width, height };\n return { width: Math.round(width * ratio), height: Math.round(height * ratio) };\n}\n","/**\n * افکت «کارتونی»: چون ctx.filter استاندارد چیزی شبیه cartoon نداره (فقط\n * brightness/contrast/saturate/grayscale/sepia/invert/blur/hue-rotate)، این\n * یکی رو واقعاً با پردازش پیکسلی پیاده کردیم؛ دو مرحله:\n *\n * ۱) Posterize: هر کانال رنگ به تعداد محدودی سطح گرد می‌شه (پهنه‌های رنگیِ\n * صاف و یکدست، حسِ کارتونی رنگ می‌ده).\n * ۲) لبه‌یابی Sobel روی نسخه‌ی خاکستریِ تصویر: هرجا شدت لبه از حد آستانه\n * بیشتر باشه، پیکسل تیره می‌شه (حسِ خط دور کارتونی).\n *\n * روی خودِ ImageData کار می‌کنه، پس هزینه‌ش با اندازه‌ی تصویر خطی‌ست؛ برای\n * تصاویر خیلی بزرگ (>~3000px) بهتره قبلش resize بشه (که در کامپوننت اصلی\n * با fitWithin قبل از اعمال فیلتر انجام می‌شه).\n */\nexport function applyCartoonEffect(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n options: { levels?: number; edgeThreshold?: number } = {},\n): void {\n const levels = options.levels ?? 5;\n const edgeThreshold = options.edgeThreshold ?? 80;\n\n const imageData = ctx.getImageData(0, 0, width, height);\n const src = imageData.data;\n\n // ۱) خاکستری برای Sobel\n const gray = new Uint8ClampedArray(width * height);\n for (let i = 0, p = 0; i < src.length; i += 4, p++) {\n gray[p] = (src[i] * 0.299 + src[i + 1] * 0.587 + src[i + 2] * 0.114) | 0;\n }\n\n // ۲) Posterize رنگ‌ها\n const step = 255 / (levels - 1);\n for (let i = 0; i < src.length; i += 4) {\n src[i] = Math.round(Math.round(src[i] / step) * step);\n src[i + 1] = Math.round(Math.round(src[i + 1] / step) * step);\n src[i + 2] = Math.round(Math.round(src[i + 2] / step) * step);\n }\n\n // ۳) Sobel روی gray، خط دور تیره روی src\n const gxKernel = [-1, 0, 1, -2, 0, 2, -1, 0, 1];\n const gyKernel = [-1, -2, -1, 0, 0, 0, 1, 2, 1];\n\n for (let y = 1; y < height - 1; y++) {\n for (let x = 1; x < width - 1; x++) {\n let gx = 0;\n let gy = 0;\n let k = 0;\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n const v = gray[(y + dy) * width + (x + dx)];\n gx += v * gxKernel[k];\n gy += v * gyKernel[k];\n k++;\n }\n }\n const magnitude = Math.sqrt(gx * gx + gy * gy);\n if (magnitude > edgeThreshold) {\n const idx = (y * width + x) * 4;\n src[idx] = 20;\n src[idx + 1] = 20;\n src[idx + 2] = 20;\n }\n }\n }\n\n ctx.putImageData(imageData, 0, 0);\n}\n","import { NgxCropRect, NgxImageEditorAdjustments } from '../contracts/image-editor-types';\nimport { applyCartoonEffect } from './cartoonify';\nimport { fitWithin } from './image-io';\n\n/** تصویر مبدأ رو با زاویه‌ی داده‌شده روی یه canvas جدید (به اندازه‌ی bounding-box نتیجه) می‌چرخونه */\nexport function renderRotated(\n source: CanvasImageSource,\n width: number,\n height: number,\n degrees: number,\n): HTMLCanvasElement {\n const rad = (degrees * Math.PI) / 180;\n const sin = Math.abs(Math.sin(rad));\n const cos = Math.abs(Math.cos(rad));\n const newW = Math.max(1, Math.round(width * cos + height * sin));\n const newH = Math.max(1, Math.round(width * sin + height * cos));\n\n const canvas = document.createElement('canvas');\n canvas.width = newW;\n canvas.height = newH;\n const ctx = canvas.getContext('2d')!;\n ctx.translate(newW / 2, newH / 2);\n ctx.rotate(rad);\n ctx.drawImage(source, -width / 2, -height / 2, width, height);\n return canvas;\n}\n\nfunction buildCssFilter(adjustments: NgxImageEditorAdjustments): string {\n const parts = [\n `brightness(${adjustments.brightness}%)`,\n `contrast(${adjustments.contrast}%)`,\n `saturate(${adjustments.saturation}%)`,\n ];\n if (adjustments.filter === 'grayscale') parts.push('grayscale(1)');\n if (adjustments.filter === 'sepia') parts.push('sepia(1)');\n if (adjustments.filter === 'invert') parts.push('invert(1)');\n return parts.join(' ');\n}\n\n/**\n * کراپ + فیلترها رو روی یه canvas خروجی می‌سازه. brightness/contrast/\n * saturation/grayscale/sepia/invert همه با ctx.filter بومیِ Canvas 2D انجام\n * می‌شن (شتاب‌دهی‌شده توسط مرورگر، بدون حلقه‌ی پیکسلی دستی)؛ فقط cartoon\n * (که معادل بومی نداره) با پردازش پیکسلی جدا انجام می‌شه.\n *\n * maxWidth/maxHeight برای دو حالت استفاده می‌شه: پیش‌نمایش زنده (عدد کوچیک،\n * برای واکنش‌گرا موندن حین کشیدن اسلایدرها) و خروجی نهایی (بدون محدودیت یا\n * محدودیت دلخواه کاربر).\n */\nexport function renderComposite(\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n crop: NgxCropRect,\n adjustments: NgxImageEditorAdjustments,\n maxWidth?: number,\n maxHeight?: number,\n): HTMLCanvasElement {\n const { width: outW, height: outH } = fitWithin(crop.width, crop.height, maxWidth, maxHeight);\n\n const canvas = document.createElement('canvas');\n canvas.width = Math.max(1, outW);\n canvas.height = Math.max(1, outH);\n const ctx = canvas.getContext('2d')!;\n\n ctx.filter = buildCssFilter(adjustments);\n ctx.drawImage(source, crop.x, crop.y, crop.width, crop.height, 0, 0, canvas.width, canvas.height);\n ctx.filter = 'none';\n\n if (adjustments.filter === 'cartoon') {\n applyCartoonEffect(ctx, canvas.width, canvas.height);\n }\n\n return canvas;\n}\n","import { InjectionToken } from '@angular/core';\n\nexport const NGX_IMAGE_EDITOR_LOCALIZATION = new InjectionToken<NgxImageEditorLocalization>(\n 'ngx-image-localization',\n {\n factory: () => DEFAULT_NGX_IMAGE_EDITOR_LOCALIZATION,\n },\n);\n\nexport class NgxImageEditorLocalization {\n LoadingImage = 'Loading image…';\n Rotation = 'Fine rotation';\n Brightness = 'Brightness';\n Contrast = 'Contrast';\n Saturation = 'Saturation';\n Filter = 'Filter';\n None = 'None';\n Grayscale = 'Grayscale';\n Sepia = 'Sepia';\n Invert = 'Invert';\n Cartoon = 'Cartoon';\n Cancel = 'Cancel';\n Save = 'Save';\n Saving = 'Saving…';\n Reset = 'Reset';\n}\nexport const DEFAULT_NGX_IMAGE_EDITOR_LOCALIZATION = new NgxImageEditorLocalization();\n","import {\n ChangeDetectionStrategy,\n Component,\n ElementRef,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { SliderComponent } from 'ngx-kit/core';\nimport {\n NgxCropRect,\n NgxImageEditorAdjustments,\n NgxImageEditorResult,\n NgxImageFilterPreset,\n type NgxImageFileType,\n} from '../contracts/image-editor-types';\nimport { NgxPointerDragDelta, NgxPointerDragDirective } from '../directives/pointer-drag.directive';\nimport { canvasToBlob, createWorkingCopy, loadImage } from '../utils/image-io';\nimport { renderComposite, renderRotated } from '../utils/render-pipeline';\nimport { Corner } from '../types/corner';\nimport { NGX_IMAGE_EDITOR_LOCALIZATION, NgxImageEditorLocalization } from '../tokens/localization';\n\nconst ALL_FILTERS: NgxImageFilterPreset[] = ['none', 'grayscale', 'sepia', 'invert', 'cartoon'];\n\n@Component({\n selector: 'ngx-image-editor',\n standalone: true,\n imports: [FormsModule, SliderComponent, NgxPointerDragDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './image-editor.component.html',\n styleUrl: './image-editor.component.scss',\n host: { class: 'ngx-image-editor-host' },\n})\nexport class NgxImageEditor {\n source = input<File | Blob | string | null>(null);\n /** قفل نسبتِ کراپ (مثلاً ۱ برای آواتار مربعی)؛ undefined یعنی آزاد */\n aspectRatio = input<number | undefined>(undefined);\n outputMaxWidth = input<number | undefined>(undefined);\n outputMaxHeight = input<number | undefined>(undefined);\n outputType = input<NgxImageFileType>('image/jpeg');\n\n /**\n * کدوم فیلترها نشون داده بشن (و به چه ترتیبی). اگه ندید، هر ۵ تا نشون داده\n * می‌شن. آرایه‌ی خالی یعنی کلِ بخشِ فیلتر مخفی بشه.\n */\n filters = input<NgxImageFilterPreset[]>(ALL_FILTERS);\n quality = input(0.92);\n\n defaultLocalization = inject(NGX_IMAGE_EDITOR_LOCALIZATION);\n localize = input<NgxImageEditorLocalization>(this.defaultLocalization);\n\n saved = output<NgxImageEditorResult>();\n cancelled = output<void>();\n\n protected readonly loading = signal(false);\n protected readonly saving = signal(false);\n protected readonly loadError = signal<string | null>(null);\n\n private readonly originalImage = signal<HTMLImageElement | null>(null);\n private readonly workingCanvas = signal<HTMLCanvasElement | null>(null);\n private readonly stageWrapEl = viewChild<ElementRef<HTMLElement>>('stageWrap');\n /** عرضِ واقعیِ رندرشده‌ی کانتینر؛ چون عرض همیشه ۱۰۰٪ (fluid) هست، باید زنده اندازه‌گیری بشه */\n private readonly containerWidth = signal(0);\n\n protected readonly rotation = signal(0);\n protected readonly brightness = signal(100);\n protected readonly contrast = signal(100);\n protected readonly saturation = signal(100);\n protected readonly filterPreset = signal<NgxImageFilterPreset>('none');\n\n protected readonly crop = signal<NgxCropRect>({ x: 0, y: 0, width: 0, height: 0 });\n\n protected readonly adjustments = computed<NgxImageEditorAdjustments>(() => ({\n brightness: this.brightness(),\n contrast: this.contrast(),\n saturation: this.saturation(),\n rotation: this.rotation(),\n filter: this.filterPreset(),\n }));\n\n protected readonly filterLabels = computed<Record<NgxImageFilterPreset, string>>(() => {\n const t = this.localize();\n return {\n none: t.None,\n grayscale: t.Grayscale,\n sepia: t.Sepia,\n invert: t.Invert,\n cartoon: t.Cartoon,\n };\n });\n\n /** تصویرِ (کوچیک‌شده‌یِ) چرخیده — پایه‌ی نمایش صحنه‌ی کراپ */\n protected readonly rotatedWorkingCanvas = computed(() => {\n const wc = this.workingCanvas();\n if (!wc) return null;\n return renderRotated(wc, wc.width, wc.height, this.rotation());\n });\n\n protected readonly panelSize = computed(() => {\n return this.stageWrapEl()?.nativeElement.getBoundingClientRect().height ?? 0;\n });\n\n /**\n * مقیاسِ «contain» واقعی: کوچیک‌ترینِ نسبتِ عرض و ارتفاع (هرکدوم تنگ‌تره)\n * تعیین‌کننده‌ست، و سقفش هم ۱ هست تا تصاویر کوچیک بزرگ‌نمایی نشن.\n */\n protected readonly displayScale = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const containerW = this.containerWidth();\n const panelH = this.panelSize();\n if (!rc || rc.width <= 0 || rc.height <= 0 || containerW <= 0 || panelH <= 0) return 1;\n return Math.min(containerW / rc.width, panelH / rc.height, 1);\n });\n\n protected readonly stageImageUrl = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n return rc ? rc.toDataURL('image/png') : null;\n });\n\n protected readonly stageSize = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const scale = this.displayScale();\n return rc ? { width: rc.width * scale, height: rc.height * scale } : { width: 0, height: 0 };\n });\n\n protected readonly cropOverlayStyle = computed(() => {\n const scale = this.displayScale();\n const c = this.crop();\n return {\n left: `${c.x * scale}px`,\n top: `${c.y * scale}px`,\n width: `${c.width * scale}px`,\n height: `${c.height * scale}px`,\n };\n });\n\n /** پیش‌نمایش نهایی (کوچیک، حداکثر ۴۸۰ پیکسل) — شامل همه‌چیز، حتی افکت کارتونی */\n protected readonly previewUrl = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const c = this.crop();\n if (!rc || c.width <= 0 || c.height <= 0) return null;\n const canvas = renderComposite(rc, rc.width, rc.height, c, this.adjustments(), 480, 480);\n return canvas.toDataURL('image/png');\n });\n\n private moveSnapshot: NgxCropRect | null = null;\n private resizeSnapshot: NgxCropRect | null = null;\n\n constructor() {\n // بارگذاری تصویر هروقت source عوض بشه\n effect(() => {\n const src = this.source();\n if (!src) {\n this.originalImage.set(null);\n this.workingCanvas.set(null);\n return;\n }\n this.loading.set(true);\n this.loadError.set(null);\n loadImage(src)\n .then((img) => {\n this.originalImage.set(img);\n this.workingCanvas.set(createWorkingCopy(img));\n this.resetAdjustments();\n })\n .catch((err) => this.loadError.set(err?.message ?? 'Failed to load image'))\n .finally(() => this.loading.set(false));\n });\n\n // هر وقت چرخیده‌شده عوض بشه (بارگذاریِ تصویر جدید یا چرخش)، کراپ روی کل قاب ریست بشه\n effect(() => {\n const rc = this.rotatedWorkingCanvas();\n if (rc) {\n this.crop.set({ x: 0, y: 0, width: rc.width, height: rc.height });\n }\n });\n\n // اگه فیلترِ فعلاً انتخاب‌شده دیگه توی لیستِ مجازِ filters() نباشه (مثلاً\n // مصرف‌کننده cartoon رو غیرفعال کرده درحالی‌که کاربر روش بود)، برو روی\n // اولین فیلترِ مجاز؛ اگه لیست خالی باشه (کلاً فیلتر مخفیه)، روی none بمون.\n effect(() => {\n const allowed = this.filters();\n if (allowed.length && !allowed.includes(this.filterPreset())) {\n this.filterPreset.set(allowed[0]);\n }\n });\n\n // اندازه‌گیریِ زنده‌ی عرضِ واقعیِ کانتینر — چون عرض همیشه ۱۰۰٪ (fluid)ه،\n // فقط با ResizeObserver می‌شه فهمید الان چند پیکسله (نه یه عددِ ثابتِ ورودی).\n effect((onCleanup) => {\n const el = this.stageWrapEl()?.nativeElement;\n if (!el) return;\n this.containerWidth.set(el.getBoundingClientRect().width);\n const ro = new ResizeObserver((entries) => {\n const width = entries[0]?.contentRect.width;\n if (width != null) this.containerWidth.set(width);\n });\n ro.observe(el);\n onCleanup(() => ro.disconnect());\n });\n }\n\n private resetAdjustments(): void {\n this.rotation.set(0);\n this.brightness.set(100);\n this.contrast.set(100);\n this.saturation.set(100);\n this.filterPreset.set(this.filters()[0] ?? 'none');\n }\n\n protected rotateBy(delta: number): void {\n this.rotation.update((r) => {\n let next = r + delta;\n if (next > 180) next -= 360;\n if (next < -180) next += 360;\n return next;\n });\n }\n\n protected setFilter(preset: NgxImageFilterPreset): void {\n this.filterPreset.set(preset);\n }\n\n // ---------- درگ جابه‌جاییِ کل کراپ‌باکس ----------\n protected onMoveDragStart(): void {\n this.moveSnapshot = { ...this.crop() };\n }\n\n protected onMoveDragMove(delta: NgxPointerDragDelta): void {\n const rc = this.rotatedWorkingCanvas();\n const snap = this.moveSnapshot;\n if (!rc || !snap) return;\n const scale = this.displayScale();\n const dxSrc = delta.dx / scale;\n const dySrc = delta.dy / scale;\n const maxX = Math.max(0, rc.width - snap.width);\n const maxY = Math.max(0, rc.height - snap.height);\n const x = Math.min(Math.max(0, snap.x + dxSrc), maxX);\n const y = Math.min(Math.max(0, snap.y + dySrc), maxY);\n this.crop.set({ ...snap, x, y });\n }\n\n // ---------- درگ ریسایز از گوشه‌ها ----------\n protected onResizeDragStart(): void {\n this.resizeSnapshot = { ...this.crop() };\n }\n\n protected onResizeDragMove(corner: Corner, delta: NgxPointerDragDelta): void {\n const rc = this.rotatedWorkingCanvas();\n const snap = this.resizeSnapshot;\n if (!rc || !snap) return;\n\n const scale = this.displayScale();\n const dxSrc = delta.dx / scale;\n const dySrc = delta.dy / scale;\n const minSize = 24;\n\n let { x, y, width, height } = snap;\n\n if (corner === 'nw' || corner === 'sw') {\n const newX = Math.min(snap.x + dxSrc, snap.x + snap.width - minSize);\n x = Math.max(0, newX);\n width = snap.x + snap.width - x;\n }\n if (corner === 'ne' || corner === 'se') {\n width = Math.min(Math.max(minSize, snap.width + dxSrc), rc.width - snap.x);\n }\n if (corner === 'nw' || corner === 'ne') {\n const newY = Math.min(snap.y + dySrc, snap.y + snap.height - minSize);\n y = Math.max(0, newY);\n height = snap.y + snap.height - y;\n }\n if (corner === 'sw' || corner === 'se') {\n height = Math.min(Math.max(minSize, snap.height + dySrc), rc.height - snap.y);\n }\n\n const ratio = this.aspectRatio();\n if (ratio) {\n height = width / ratio;\n }\n\n this.crop.set({ x, y, width, height });\n }\n\n protected cancel(): void {\n this.cancelled.emit();\n }\n\n async save(): Promise<void> {\n const original = this.originalImage();\n const working = this.workingCanvas();\n if (!original || !working) return;\n\n this.saving.set(true);\n try {\n // نسبت مقیاس بین کپیِ کوچیک‌شده (که کراپ/چرخش روش تعریف شده) و تصویر\n // اصلیِ کامل. چون createWorkingCopy مقیاس یکنواخت (هم‌جهت) اعمال\n // می‌کنه، همین یه ضریب برای هر دو بعد و بعد از چرخش هم معتبر می‌مونه.\n const scaleToOriginal = original.naturalWidth / working.width;\n\n const rotatedFull = renderRotated(\n original,\n original.naturalWidth,\n original.naturalHeight,\n this.rotation(),\n );\n\n const c = this.crop();\n const cropInFullRes: NgxCropRect = {\n x: c.x * scaleToOriginal,\n y: c.y * scaleToOriginal,\n width: c.width * scaleToOriginal,\n height: c.height * scaleToOriginal,\n };\n\n const finalCanvas = renderComposite(\n rotatedFull,\n rotatedFull.width,\n rotatedFull.height,\n cropInFullRes,\n this.adjustments(),\n this.outputMaxWidth(),\n this.outputMaxHeight(),\n );\n\n const type = this.outputType();\n const blob = await canvasToBlob(finalCanvas, type, this.quality());\n const dataUrl = finalCanvas.toDataURL(type, this.quality());\n const file = new File([blob], '', { type });\n this.saved.emit({\n blob,\n dataUrl,\n width: finalCanvas.width,\n height: finalCanvas.height,\n file,\n type,\n });\n } finally {\n this.saving.set(false);\n }\n }\n}\n","@if (loading()) {\n <div class=\"ngx-ie-state\">{{ localize().LoadingImage }}</div>\n} @else if (loadError()) {\n <div class=\"ngx-ie-state ngx-ie-state--error\">{{ loadError() }}</div>\n} @else if (stageImageUrl()) {\n <div class=\"ngx-ie-layout\">\n <div class=\"ngx-ie-stage-wrap\" #stageWrap>\n <div\n class=\"ngx-ie-stage\"\n [style.width.px]=\"stageSize().width\"\n [style.height.px]=\"stageSize().height\">\n <img class=\"ngx-ie-stage-img\" [src]=\"stageImageUrl()\" alt=\"\" draggable=\"false\" />\n\n <div\n class=\"ngx-ie-crop-box\"\n [style.left]=\"cropOverlayStyle().left\"\n [style.top]=\"cropOverlayStyle().top\"\n [style.width]=\"cropOverlayStyle().width\"\n [style.height]=\"cropOverlayStyle().height\"\n ngxPointerDrag\n (dragStart)=\"onMoveDragStart()\"\n (dragMove)=\"onMoveDragMove($event)\">\n <span\n class=\"ngx-ie-handle ngx-ie-handle--nw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('nw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--ne\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('ne', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--sw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('sw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--se\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('se', $event)\"></span>\n </div>\n </div>\n </div>\n\n <div class=\"ngx-ie-panel-row\">\n <div class=\"ngx-ie-panel\">\n <div class=\"ngx-ie-preview\">\n @if (previewUrl(); as url) {\n <img [src]=\"url\" alt=\"Preview\" />\n }\n </div>\n\n <div class=\"ngx-ie-row ngx-ie-rotate-row\">\n <button type=\"button\" (click)=\"rotateBy(-90)\" title=\"Rotate 90° left\">⟲ 90</button>\n <button type=\"button\" (click)=\"rotateBy(90)\" title=\"Rotate 90° right\">⟳ 90</button>\n </div>\n\n <div class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"rotation()\"\n (ngModelChange)=\"rotation.set($event)\"\n [min]=\"-180\"\n [max]=\"180\">\n <span>{{ localize().Rotation }} ({{ rotation() }}°)</span>\n </slider>\n\n <button\n type=\"button\"\n (click)=\"rotation.set(0)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </div>\n\n <div class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"brightness()\"\n (ngModelChange)=\"brightness.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Brightness }} ({{ brightness() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"brightness.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </div>\n\n <div class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"contrast()\"\n (ngModelChange)=\"contrast.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Contrast }} ({{ contrast() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"contrast.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </div>\n\n <div class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"saturation()\"\n (ngModelChange)=\"saturation.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Saturation }} ({{ saturation() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"saturation.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </div>\n\n @if (filters().length) {\n <div>\n <span>{{ localize().Filter }}</span>\n <div class=\"ngx-ie-filter-row\">\n @for (f of filters(); track f) {\n <button type=\"button\" [class.active]=\"filterPreset() === f\" (click)=\"setFilter(f)\">\n {{ filterLabels()[f] }}\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"ngx-ie-row ngx-ie-actions\">\n <button type=\"button\" class=\"ngx-ie-btn-secondary\" (click)=\"cancel()\">\n {{ localize().Cancel }}\n </button>\n <button type=\"button\" class=\"ngx-ie-btn-primary\" [disabled]=\"saving()\" (click)=\"save()\">\n {{ saving() ? localize().Saving : localize().Save }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-kit-image-editor.mjs","sources":["../../../projects/libs/image-editor/directives/pointer-drag.directive.ts","../../../projects/libs/image-editor/utils/image-io.ts","../../../projects/libs/image-editor/utils/cartoonify.ts","../../../projects/libs/image-editor/utils/render-pipeline.ts","../../../projects/libs/image-editor/tokens/localization.ts","../../../projects/libs/image-editor/components/image-editor.component.ts","../../../projects/libs/image-editor/components/image-editor.component.html","../../../projects/libs/image-editor/ngx-kit-image-editor.ts"],"sourcesContent":["import { Directive, HostListener, output } from '@angular/core';\n\nexport interface NgxPointerDragDelta {\n dx: number;\n dy: number;\n}\n\n/**\n * درگ عمومی روی پایه‌ی Pointer Events + setPointerCapture (دقیقاً همون\n * تکنیکی که در ngx-kit/data-table برای ریسایز ستون استفاده شده) — نیازی به\n * listener سطح document نداره چون بعد از setPointerCapture، رویدادهای\n * pointermove/pointerup حتی بیرون از محدوده‌ی المنت هم به خودش می‌رسن.\n *\n * dx/dy تجمعی از لحظه‌ی pointerdown هستن (نه دلتای بین دو move متوالی)، چون\n * معمولاً مصرف‌کننده می‌خواد «موقعیت شروع + دلتای کل» رو حساب کنه، نه جمع\n * تدریجی گرد شونده‌ی دلتاهای ریز.\n */\n@Directive({\n selector: '[ngxPointerDrag]',\n standalone: true,\n})\nexport class NgxPointerDragDirective {\n dragStart = output<void>();\n dragMove = output<NgxPointerDragDelta>();\n dragEnd = output<void>();\n\n private dragging = false;\n private startX = 0;\n private startY = 0;\n\n @HostListener('pointerdown', ['$event'])\n onPointerDown(ev: PointerEvent): void {\n ev.preventDefault();\n ev.stopPropagation();\n this.dragging = true;\n this.startX = ev.clientX;\n this.startY = ev.clientY;\n (ev.target as HTMLElement).setPointerCapture(ev.pointerId);\n this.dragStart.emit();\n }\n\n @HostListener('pointermove', ['$event'])\n onPointerMove(ev: PointerEvent): void {\n if (!this.dragging) return;\n this.dragMove.emit({ dx: ev.clientX - this.startX, dy: ev.clientY - this.startY });\n }\n\n @HostListener('pointerup')\n @HostListener('pointercancel')\n onPointerUp(): void {\n if (!this.dragging) return;\n this.dragging = false;\n this.dragEnd.emit();\n }\n}\n","/** یه File/Blob/data-URL/URL رو به یک HTMLImageElement بارگذاری‌شده تبدیل می‌کنه */\nexport function loadImage(source: File | Blob | string): Promise<HTMLImageElement> {\n return new Promise((resolve, reject) => {\n const img = new Image();\n // برای URLهای cross-origin لازم می‌شه، وگرنه canvas بعداً «tainted» می‌شه\n // و toBlob/toDataURL با SecurityError شکست می‌خوره.\n img.crossOrigin = 'anonymous';\n\n const objectUrl = typeof source === 'string' ? null : URL.createObjectURL(source);\n const url = objectUrl ?? (source as string);\n\n img.onload = () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n resolve(img);\n };\n img.onerror = () => {\n if (objectUrl) URL.revokeObjectURL(objectUrl);\n reject(new Error('Failed to load image'));\n };\n img.src = url;\n });\n}\n\n/** canvas.toBlob به‌صورت Promise، به‌همراه fallback برای مرورگرهای قدیمی‌تر */\nexport function canvasToBlob(\n canvas: HTMLCanvasElement,\n type = 'image/jpeg',\n quality = 0.92,\n): Promise<Blob> {\n return new Promise((resolve, reject) => {\n canvas.toBlob(\n (blob) => {\n if (blob) resolve(blob);\n else reject(new Error('Failed to convert canvas to blob'));\n },\n type,\n quality,\n );\n });\n}\n\n/**\n * یه کپیِ کوچیک‌شده از تصویر اصلی می‌سازه که کل UI ویرایشگر (چرخش، کراپ،\n * پیش‌نمایش فیلترها/کارتونی) روی همین کار می‌کنه، نه روی تصویر اصلی که\n * ممکنه چند مگاپیکسل باشه. این باعث می‌شه درگ‌کردنِ اسلایدرها یا لبه‌های\n * کراپ روون بمونه؛ خروجی نهایی (save) همیشه از روی تصویر اصلیِ کامل رندر\n * می‌شه، نه از روی این کپی.\n */\nexport function createWorkingCopy(\n doc: Document,\n img: HTMLImageElement,\n maxSize = 1200,\n): HTMLCanvasElement {\n const { width, height } = fitWithin(img.naturalWidth, img.naturalHeight, maxSize, maxSize);\n const canvas = doc.createElement('canvas');\n canvas.width = width;\n canvas.height = height;\n const ctx = canvas.getContext('2d')!;\n ctx.drawImage(img, 0, 0, width, height);\n return canvas;\n}\n\n/** ابعاد جدید رو طوری حساب می‌کنه که از maxWidth/maxHeight بیشتر نشه، با حفظ نسبت تصویر */\nexport function fitWithin(\n width: number,\n height: number,\n maxWidth?: number,\n maxHeight?: number,\n): { width: number; height: number } {\n if (!maxWidth && !maxHeight) return { width, height };\n let ratio = 1;\n if (maxWidth) ratio = Math.min(ratio, maxWidth / width);\n if (maxHeight) ratio = Math.min(ratio, maxHeight / height);\n if (ratio >= 1) return { width, height };\n return { width: Math.round(width * ratio), height: Math.round(height * ratio) };\n}\n","/**\n * افکت «کارتونی»: چون ctx.filter استاندارد چیزی شبیه cartoon نداره (فقط\n * brightness/contrast/saturate/grayscale/sepia/invert/blur/hue-rotate)، این\n * یکی رو واقعاً با پردازش پیکسلی پیاده کردیم؛ دو مرحله:\n *\n * ۱) Posterize: هر کانال رنگ به تعداد محدودی سطح گرد می‌شه (پهنه‌های رنگیِ\n * صاف و یکدست، حسِ کارتونی رنگ می‌ده).\n * ۲) لبه‌یابی Sobel روی نسخه‌ی خاکستریِ تصویر: هرجا شدت لبه از حد آستانه\n * بیشتر باشه، پیکسل تیره می‌شه (حسِ خط دور کارتونی).\n *\n * روی خودِ ImageData کار می‌کنه، پس هزینه‌ش با اندازه‌ی تصویر خطی‌ست؛ برای\n * تصاویر خیلی بزرگ (>~3000px) بهتره قبلش resize بشه (که در کامپوننت اصلی\n * با fitWithin قبل از اعمال فیلتر انجام می‌شه).\n */\nexport function applyCartoonEffect(\n ctx: CanvasRenderingContext2D,\n width: number,\n height: number,\n options: { levels?: number; edgeThreshold?: number } = {},\n): void {\n const levels = options.levels ?? 5;\n const edgeThreshold = options.edgeThreshold ?? 80;\n\n const imageData = ctx.getImageData(0, 0, width, height);\n const src = imageData.data;\n\n // ۱) خاکستری برای Sobel\n const gray = new Uint8ClampedArray(width * height);\n for (let i = 0, p = 0; i < src.length; i += 4, p++) {\n gray[p] = (src[i] * 0.299 + src[i + 1] * 0.587 + src[i + 2] * 0.114) | 0;\n }\n\n // ۲) Posterize رنگ‌ها\n const step = 255 / (levels - 1);\n for (let i = 0; i < src.length; i += 4) {\n src[i] = Math.round(Math.round(src[i] / step) * step);\n src[i + 1] = Math.round(Math.round(src[i + 1] / step) * step);\n src[i + 2] = Math.round(Math.round(src[i + 2] / step) * step);\n }\n\n // ۳) Sobel روی gray، خط دور تیره روی src\n const gxKernel = [-1, 0, 1, -2, 0, 2, -1, 0, 1];\n const gyKernel = [-1, -2, -1, 0, 0, 0, 1, 2, 1];\n\n for (let y = 1; y < height - 1; y++) {\n for (let x = 1; x < width - 1; x++) {\n let gx = 0;\n let gy = 0;\n let k = 0;\n for (let dy = -1; dy <= 1; dy++) {\n for (let dx = -1; dx <= 1; dx++) {\n const v = gray[(y + dy) * width + (x + dx)];\n gx += v * gxKernel[k];\n gy += v * gyKernel[k];\n k++;\n }\n }\n const magnitude = Math.sqrt(gx * gx + gy * gy);\n if (magnitude > edgeThreshold) {\n const idx = (y * width + x) * 4;\n src[idx] = 20;\n src[idx + 1] = 20;\n src[idx + 2] = 20;\n }\n }\n }\n\n ctx.putImageData(imageData, 0, 0);\n}\n","import { NgxCropRect, NgxImageEditorAdjustments } from '../contracts/image-editor-types';\nimport { applyCartoonEffect } from './cartoonify';\nimport { fitWithin } from './image-io';\n\n/** تصویر مبدأ رو با زاویه‌ی داده‌شده روی یه canvas جدید (به اندازه‌ی bounding-box نتیجه) می‌چرخونه */\nexport function renderRotated(\n doc: Document,\n source: CanvasImageSource,\n width: number,\n height: number,\n degrees: number,\n): HTMLCanvasElement {\n const rad = (degrees * Math.PI) / 180;\n const sin = Math.abs(Math.sin(rad));\n const cos = Math.abs(Math.cos(rad));\n const newW = Math.max(1, Math.round(width * cos + height * sin));\n const newH = Math.max(1, Math.round(width * sin + height * cos));\n\n const canvas = doc.createElement('canvas');\n canvas.width = newW;\n canvas.height = newH;\n const ctx = canvas.getContext('2d')!;\n ctx.translate(newW / 2, newH / 2);\n ctx.rotate(rad);\n ctx.drawImage(source, -width / 2, -height / 2, width, height);\n return canvas;\n}\n\nfunction buildCssFilter(adjustments: NgxImageEditorAdjustments): string {\n const parts = [\n `brightness(${adjustments.brightness}%)`,\n `contrast(${adjustments.contrast}%)`,\n `saturate(${adjustments.saturation}%)`,\n ];\n if (adjustments.filter === 'grayscale') parts.push('grayscale(1)');\n if (adjustments.filter === 'sepia') parts.push('sepia(1)');\n if (adjustments.filter === 'invert') parts.push('invert(1)');\n return parts.join(' ');\n}\n\n/**\n * کراپ + فیلترها رو روی یه canvas خروجی می‌سازه. brightness/contrast/\n * saturation/grayscale/sepia/invert همه با ctx.filter بومیِ Canvas 2D انجام\n * می‌شن (شتاب‌دهی‌شده توسط مرورگر، بدون حلقه‌ی پیکسلی دستی)؛ فقط cartoon\n * (که معادل بومی نداره) با پردازش پیکسلی جدا انجام می‌شه.\n *\n * maxWidth/maxHeight برای دو حالت استفاده می‌شه: پیش‌نمایش زنده (عدد کوچیک،\n * برای واکنش‌گرا موندن حین کشیدن اسلایدرها) و خروجی نهایی (بدون محدودیت یا\n * محدودیت دلخواه کاربر).\n */\nexport function renderComposite(\n doc: Document,\n source: CanvasImageSource,\n sourceWidth: number,\n sourceHeight: number,\n crop: NgxCropRect,\n adjustments: NgxImageEditorAdjustments,\n maxWidth?: number,\n maxHeight?: number,\n): HTMLCanvasElement {\n const { width: outW, height: outH } = fitWithin(crop.width, crop.height, maxWidth, maxHeight);\n\n const canvas = doc.createElement('canvas');\n canvas.width = Math.max(1, outW);\n canvas.height = Math.max(1, outH);\n const ctx = canvas.getContext('2d')!;\n\n ctx.filter = buildCssFilter(adjustments);\n ctx.drawImage(source, crop.x, crop.y, crop.width, crop.height, 0, 0, canvas.width, canvas.height);\n ctx.filter = 'none';\n\n if (adjustments.filter === 'cartoon') {\n applyCartoonEffect(ctx, canvas.width, canvas.height);\n }\n\n return canvas;\n}\n","import { InjectionToken } from '@angular/core';\n\nexport const NGX_IMAGE_EDITOR_LOCALIZATION = new InjectionToken<NgxImageEditorLocalization>(\n 'ngx-image-localization',\n {\n factory: () => DEFAULT_NGX_IMAGE_EDITOR_LOCALIZATION,\n },\n);\n\nexport class NgxImageEditorLocalization {\n LoadingImage = 'Loading image…';\n Rotation = 'Fine rotation';\n Brightness = 'Brightness';\n Contrast = 'Contrast';\n Saturation = 'Saturation';\n Filter = 'Filter';\n None = 'None';\n Grayscale = 'Grayscale';\n Sepia = 'Sepia';\n Invert = 'Invert';\n Cartoon = 'Cartoon';\n Cancel = 'Cancel';\n Save = 'Save';\n Saving = 'Saving…';\n Reset = 'Reset';\n}\nexport const DEFAULT_NGX_IMAGE_EDITOR_LOCALIZATION = new NgxImageEditorLocalization();\n","import {\n ChangeDetectionStrategy,\n Component,\n DOCUMENT,\n ElementRef,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { FormsModule } from '@angular/forms';\nimport { SliderComponent } from 'ngx-kit/core';\nimport {\n NgxCropRect,\n NgxImageEditorAdjustments,\n NgxImageEditorResult,\n NgxImageFilterPreset,\n type NgxImageFileType,\n} from '../contracts/image-editor-types';\nimport { NgxPointerDragDelta, NgxPointerDragDirective } from '../directives/pointer-drag.directive';\nimport { canvasToBlob, createWorkingCopy, loadImage } from '../utils/image-io';\nimport { renderComposite, renderRotated } from '../utils/render-pipeline';\nimport { Corner } from '../types/corner';\nimport { NGX_IMAGE_EDITOR_LOCALIZATION, NgxImageEditorLocalization } from '../tokens/localization';\n\nconst ALL_FILTERS: NgxImageFilterPreset[] = ['none', 'grayscale', 'sepia', 'invert', 'cartoon'];\n\n@Component({\n selector: 'ngx-image-editor',\n standalone: true,\n imports: [FormsModule, SliderComponent, NgxPointerDragDirective],\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './image-editor.component.html',\n styleUrl: './image-editor.component.scss',\n host: { class: 'ngx-image-editor-host' },\n})\nexport class NgxImageEditor {\n source = input<File | Blob | string | null>(null);\n /** قفل نسبتِ کراپ (مثلاً ۱ برای آواتار مربعی)؛ undefined یعنی آزاد */\n aspectRatio = input<number | undefined>(undefined);\n outputMaxWidth = input<number | undefined>(undefined);\n outputMaxHeight = input<number | undefined>(undefined);\n outputType = input<NgxImageFileType>('image/jpeg');\n\n /**\n * کدوم فیلترها نشون داده بشن (و به چه ترتیبی). اگه ندید، هر ۵ تا نشون داده\n * می‌شن. آرایه‌ی خالی یعنی کلِ بخشِ فیلتر مخفی بشه.\n */\n filters = input<NgxImageFilterPreset[]>(ALL_FILTERS);\n quality = input(0.92);\n\n defaultLocalization = inject(NGX_IMAGE_EDITOR_LOCALIZATION);\n localize = input<NgxImageEditorLocalization>(this.defaultLocalization);\n private readonly doc = inject(DOCUMENT);\n\n saved = output<NgxImageEditorResult>();\n cancelled = output<void>();\n\n protected readonly loading = signal(false);\n protected readonly saving = signal(false);\n protected readonly loadError = signal<string | null>(null);\n\n private readonly originalImage = signal<HTMLImageElement | null>(null);\n private readonly workingCanvas = signal<HTMLCanvasElement | null>(null);\n private readonly stageWrapEl = viewChild<ElementRef<HTMLElement>>('stageWrap');\n /** عرضِ واقعیِ رندرشده‌ی کانتینر؛ چون عرض همیشه ۱۰۰٪ (fluid) هست، باید زنده اندازه‌گیری بشه */\n private readonly containerWidth = signal(0);\n\n protected readonly rotation = signal(0);\n protected readonly brightness = signal(100);\n protected readonly contrast = signal(100);\n protected readonly saturation = signal(100);\n protected readonly filterPreset = signal<NgxImageFilterPreset>('none');\n\n protected readonly crop = signal<NgxCropRect>({ x: 0, y: 0, width: 0, height: 0 });\n\n protected readonly adjustments = computed<NgxImageEditorAdjustments>(() => ({\n brightness: this.brightness(),\n contrast: this.contrast(),\n saturation: this.saturation(),\n rotation: this.rotation(),\n filter: this.filterPreset(),\n }));\n\n protected readonly filterLabels = computed<Record<NgxImageFilterPreset, string>>(() => {\n const t = this.localize();\n return {\n none: t.None,\n grayscale: t.Grayscale,\n sepia: t.Sepia,\n invert: t.Invert,\n cartoon: t.Cartoon,\n };\n });\n\n /** تصویرِ (کوچیک‌شده‌یِ) چرخیده — پایه‌ی نمایش صحنه‌ی کراپ */\n protected readonly rotatedWorkingCanvas = computed(() => {\n const wc = this.workingCanvas();\n if (!wc) return null;\n return renderRotated(this.doc, wc, wc.width, wc.height, this.rotation());\n });\n\n protected readonly panelSize = computed(() => {\n return this.stageWrapEl()?.nativeElement.getBoundingClientRect().height ?? 0;\n });\n\n /**\n * مقیاسِ «contain» واقعی: کوچیک‌ترینِ نسبتِ عرض و ارتفاع (هرکدوم تنگ‌تره)\n * تعیین‌کننده‌ست، و سقفش هم ۱ هست تا تصاویر کوچیک بزرگ‌نمایی نشن.\n */\n protected readonly displayScale = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const containerW = this.containerWidth();\n const panelH = this.panelSize();\n if (!rc || rc.width <= 0 || rc.height <= 0 || containerW <= 0 || panelH <= 0) return 1;\n return Math.min(containerW / rc.width, panelH / rc.height, 1);\n });\n\n protected readonly stageImageUrl = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n return rc ? rc.toDataURL('image/png') : null;\n });\n\n protected readonly stageSize = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const scale = this.displayScale();\n return rc ? { width: rc.width * scale, height: rc.height * scale } : { width: 0, height: 0 };\n });\n\n protected readonly cropOverlayStyle = computed(() => {\n const scale = this.displayScale();\n const c = this.crop();\n return {\n left: `${c.x * scale}px`,\n top: `${c.y * scale}px`,\n width: `${c.width * scale}px`,\n height: `${c.height * scale}px`,\n };\n });\n\n /** پیش‌نمایش نهایی (کوچیک، حداکثر ۴۸۰ پیکسل) — شامل همه‌چیز، حتی افکت کارتونی */\n protected readonly previewUrl = computed(() => {\n const rc = this.rotatedWorkingCanvas();\n const c = this.crop();\n if (!rc || c.width <= 0 || c.height <= 0) return null;\n const canvas = renderComposite(\n this.doc,\n rc,\n rc.width,\n rc.height,\n c,\n this.adjustments(),\n 480,\n 480,\n );\n return canvas.toDataURL('image/png');\n });\n\n private moveSnapshot: NgxCropRect | null = null;\n private resizeSnapshot: NgxCropRect | null = null;\n\n constructor() {\n // بارگذاری تصویر هروقت source عوض بشه\n effect(() => {\n const src = this.source();\n if (!src) {\n this.originalImage.set(null);\n this.workingCanvas.set(null);\n return;\n }\n this.loading.set(true);\n this.loadError.set(null);\n loadImage(src)\n .then((img) => {\n this.originalImage.set(img);\n this.workingCanvas.set(createWorkingCopy(this.doc, img));\n this.resetAdjustments();\n })\n .catch((err) => this.loadError.set(err?.message ?? 'Failed to load image'))\n .finally(() => this.loading.set(false));\n });\n\n // هر وقت چرخیده‌شده عوض بشه (بارگذاریِ تصویر جدید یا چرخش)، کراپ روی کل قاب ریست بشه\n effect(() => {\n const rc = this.rotatedWorkingCanvas();\n if (rc) {\n this.crop.set({ x: 0, y: 0, width: rc.width, height: rc.height });\n }\n });\n\n // اگه فیلترِ فعلاً انتخاب‌شده دیگه توی لیستِ مجازِ filters() نباشه (مثلاً\n // مصرف‌کننده cartoon رو غیرفعال کرده درحالی‌که کاربر روش بود)، برو روی\n // اولین فیلترِ مجاز؛ اگه لیست خالی باشه (کلاً فیلتر مخفیه)، روی none بمون.\n effect(() => {\n const allowed = this.filters();\n if (allowed.length && !allowed.includes(this.filterPreset())) {\n this.filterPreset.set(allowed[0]);\n }\n });\n\n // اندازه‌گیریِ زنده‌ی عرضِ واقعیِ کانتینر — چون عرض همیشه ۱۰۰٪ (fluid)ه،\n // فقط با ResizeObserver می‌شه فهمید الان چند پیکسله (نه یه عددِ ثابتِ ورودی).\n effect((onCleanup) => {\n const el = this.stageWrapEl()?.nativeElement;\n if (!el) return;\n this.containerWidth.set(el.getBoundingClientRect().width);\n const ro = new ResizeObserver((entries) => {\n const width = entries[0]?.contentRect.width;\n if (width != null) this.containerWidth.set(width);\n });\n ro.observe(el);\n onCleanup(() => ro.disconnect());\n });\n }\n\n private resetAdjustments(): void {\n this.rotation.set(0);\n this.brightness.set(100);\n this.contrast.set(100);\n this.saturation.set(100);\n this.filterPreset.set(this.filters()[0] ?? 'none');\n }\n\n protected rotateBy(delta: number): void {\n this.rotation.update((r) => {\n let next = r + delta;\n if (next > 180) next -= 360;\n if (next < -180) next += 360;\n return next;\n });\n }\n\n protected setFilter(preset: NgxImageFilterPreset): void {\n this.filterPreset.set(preset);\n }\n\n // ---------- درگ جابه‌جاییِ کل کراپ‌باکس ----------\n protected onMoveDragStart(): void {\n this.moveSnapshot = { ...this.crop() };\n }\n\n protected onMoveDragMove(delta: NgxPointerDragDelta): void {\n const rc = this.rotatedWorkingCanvas();\n const snap = this.moveSnapshot;\n if (!rc || !snap) return;\n const scale = this.displayScale();\n const dxSrc = delta.dx / scale;\n const dySrc = delta.dy / scale;\n const maxX = Math.max(0, rc.width - snap.width);\n const maxY = Math.max(0, rc.height - snap.height);\n const x = Math.min(Math.max(0, snap.x + dxSrc), maxX);\n const y = Math.min(Math.max(0, snap.y + dySrc), maxY);\n this.crop.set({ ...snap, x, y });\n }\n\n // ---------- درگ ریسایز از گوشه‌ها ----------\n protected onResizeDragStart(): void {\n this.resizeSnapshot = { ...this.crop() };\n }\n\n protected onResizeDragMove(corner: Corner, delta: NgxPointerDragDelta): void {\n const rc = this.rotatedWorkingCanvas();\n const snap = this.resizeSnapshot;\n if (!rc || !snap) return;\n\n const scale = this.displayScale();\n const dxSrc = delta.dx / scale;\n const dySrc = delta.dy / scale;\n const minSize = 24;\n\n let { x, y, width, height } = snap;\n\n if (corner === 'nw' || corner === 'sw') {\n const newX = Math.min(snap.x + dxSrc, snap.x + snap.width - minSize);\n x = Math.max(0, newX);\n width = snap.x + snap.width - x;\n }\n if (corner === 'ne' || corner === 'se') {\n width = Math.min(Math.max(minSize, snap.width + dxSrc), rc.width - snap.x);\n }\n if (corner === 'nw' || corner === 'ne') {\n const newY = Math.min(snap.y + dySrc, snap.y + snap.height - minSize);\n y = Math.max(0, newY);\n height = snap.y + snap.height - y;\n }\n if (corner === 'sw' || corner === 'se') {\n height = Math.min(Math.max(minSize, snap.height + dySrc), rc.height - snap.y);\n }\n\n const ratio = this.aspectRatio();\n if (ratio) {\n height = width / ratio;\n }\n\n this.crop.set({ x, y, width, height });\n }\n\n protected cancel(): void {\n this.cancelled.emit();\n }\n\n async save(): Promise<void> {\n const original = this.originalImage();\n const working = this.workingCanvas();\n if (!original || !working) return;\n\n this.saving.set(true);\n try {\n // نسبت مقیاس بین کپیِ کوچیک‌شده (که کراپ/چرخش روش تعریف شده) و تصویر\n // اصلیِ کامل. چون createWorkingCopy مقیاس یکنواخت (هم‌جهت) اعمال\n // می‌کنه، همین یه ضریب برای هر دو بعد و بعد از چرخش هم معتبر می‌مونه.\n const scaleToOriginal = original.naturalWidth / working.width;\n\n const rotatedFull = renderRotated(\n this.doc,\n original,\n original.naturalWidth,\n original.naturalHeight,\n this.rotation(),\n );\n\n const c = this.crop();\n const cropInFullRes: NgxCropRect = {\n x: c.x * scaleToOriginal,\n y: c.y * scaleToOriginal,\n width: c.width * scaleToOriginal,\n height: c.height * scaleToOriginal,\n };\n\n const finalCanvas = renderComposite(\n this.doc,\n rotatedFull,\n rotatedFull.width,\n rotatedFull.height,\n cropInFullRes,\n this.adjustments(),\n this.outputMaxWidth(),\n this.outputMaxHeight(),\n );\n\n const type = this.outputType();\n const blob = await canvasToBlob(finalCanvas, type, this.quality());\n const dataUrl = finalCanvas.toDataURL(type, this.quality());\n const file = new File([blob], '', { type });\n this.saved.emit({\n blob,\n dataUrl,\n width: finalCanvas.width,\n height: finalCanvas.height,\n file,\n type,\n });\n } finally {\n this.saving.set(false);\n }\n }\n}\n","@if (loading()) {\n <div class=\"ngx-ie-state\">{{ localize().LoadingImage }}</div>\n} @else if (loadError()) {\n <div class=\"ngx-ie-state ngx-ie-state--error\">{{ loadError() }}</div>\n} @else if (stageImageUrl()) {\n <div class=\"ngx-ie-layout\">\n <div class=\"ngx-ie-stage-wrap\" #stageWrap>\n <div\n class=\"ngx-ie-stage\"\n [style.width.px]=\"stageSize().width\"\n [style.height.px]=\"stageSize().height\">\n <img class=\"ngx-ie-stage-img\" [src]=\"stageImageUrl()\" alt=\"\" draggable=\"false\" />\n\n <div\n class=\"ngx-ie-crop-box\"\n [style.left]=\"cropOverlayStyle().left\"\n [style.top]=\"cropOverlayStyle().top\"\n [style.width]=\"cropOverlayStyle().width\"\n [style.height]=\"cropOverlayStyle().height\"\n ngxPointerDrag\n (dragStart)=\"onMoveDragStart()\"\n (dragMove)=\"onMoveDragMove($event)\">\n <span\n class=\"ngx-ie-handle ngx-ie-handle--nw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('nw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--ne\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('ne', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--sw\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('sw', $event)\"></span>\n <span\n class=\"ngx-ie-handle ngx-ie-handle--se\"\n ngxPointerDrag\n (dragStart)=\"onResizeDragStart()\"\n (dragMove)=\"onResizeDragMove('se', $event)\"></span>\n </div>\n </div>\n </div>\n\n <div class=\"ngx-ie-panel-row\">\n <div class=\"ngx-ie-panel\">\n <div class=\"ngx-ie-preview\">\n @if (previewUrl(); as url) {\n <img [src]=\"url\" alt=\"Preview\" />\n }\n </div>\n\n <div class=\"ngx-ie-row ngx-ie-rotate-row\">\n <button type=\"button\" (click)=\"rotateBy(-90)\" title=\"Rotate 90° left\">⟲ 90</button>\n <button type=\"button\" (click)=\"rotateBy(90)\" title=\"Rotate 90° right\">⟳ 90</button>\n </div>\n\n <div class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"rotation()\"\n (ngModelChange)=\"rotation.set($event)\"\n [min]=\"-180\"\n [max]=\"180\">\n <span>{{ localize().Rotation }} ({{ rotation() }}°)</span>\n </slider>\n\n <button\n type=\"button\"\n (click)=\"rotation.set(0)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </div>\n\n <div class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"brightness()\"\n (ngModelChange)=\"brightness.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Brightness }} ({{ brightness() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"brightness.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </div>\n\n <div class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"contrast()\"\n (ngModelChange)=\"contrast.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Contrast }} ({{ contrast() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"contrast.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </div>\n\n <div class=\"ngx-ie-field\">\n <slider\n [ngModel]=\"saturation()\"\n (ngModelChange)=\"saturation.set($event)\"\n [min]=\"0\"\n [max]=\"200\">\n <span>{{ localize().Saturation }} ({{ saturation() }}%)</span>\n </slider>\n <button\n type=\"button\"\n (click)=\"saturation.set(100)\"\n class=\"ngx-ie-btn-secondary\"\n [title]=\"localize().Reset\">\n x\n </button>\n </div>\n\n @if (filters().length) {\n <div>\n <span>{{ localize().Filter }}</span>\n <div class=\"ngx-ie-filter-row\">\n @for (f of filters(); track f) {\n <button type=\"button\" [class.active]=\"filterPreset() === f\" (click)=\"setFilter(f)\">\n {{ filterLabels()[f] }}\n </button>\n }\n </div>\n </div>\n }\n\n <div class=\"ngx-ie-row ngx-ie-actions\">\n <button type=\"button\" class=\"ngx-ie-btn-secondary\" (click)=\"cancel()\">\n {{ localize().Cancel }}\n </button>\n <button type=\"button\" class=\"ngx-ie-btn-primary\" [disabled]=\"saving()\" (click)=\"save()\">\n {{ saving() ? localize().Saving : localize().Save }}\n </button>\n </div>\n </div>\n </div>\n </div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { input, output, signal, computed, viewChild, inject, ElementRef, DestroyRef, effect, HostListener, ChangeDetectionStrategy, Component } from '@angular/core';
2
+ import { input, output, signal, computed, viewChild, inject, ElementRef, DestroyRef, DOCUMENT, effect, HostListener, ChangeDetectionStrategy, Component } from '@angular/core';
3
3
  import { startDragSession } from 'ngx-kit/core';
4
4
 
5
5
  const NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR = {
@@ -136,6 +136,7 @@ class NgxImageViewer {
136
136
  ...(ngDevMode ? [{ debugName: "stageEl" }] : /* istanbul ignore next */ []));
137
137
  hostElRef = inject((ElementRef));
138
138
  destroyRef = inject(DestroyRef);
139
+ doc = inject(DOCUMENT);
139
140
  pinchStartDistance = 0;
140
141
  pinchStartZoom = 1;
141
142
  stopPanDrag;
@@ -248,8 +249,8 @@ class NgxImageViewer {
248
249
  }
249
250
  toggleFullscreen() {
250
251
  const el = this.hostElRef.nativeElement;
251
- if (document.fullscreenElement) {
252
- document.exitFullscreen();
252
+ if (this.doc.fullscreenElement) {
253
+ this.doc.exitFullscreen();
253
254
  }
254
255
  else {
255
256
  el.requestFullscreen?.();
@@ -271,6 +272,7 @@ class NgxImageViewer {
271
272
  const startY = this.clientYOf(ev);
272
273
  this.stopPanDrag?.();
273
274
  this.stopPanDrag = startDragSession({
275
+ doc: this.doc,
274
276
  onMove: (moveEv) => {
275
277
  this.panX.set(startPanX + (this.clientXOf(moveEv) - startX));
276
278
  this.panY.set(startPanY + (this.clientYOf(moveEv) - startY));
@@ -1 +1 @@
1
- {"version":3,"file":"ngx-kit-image-viewer.mjs","sources":["../../../projects/libs/image-viewer/contracts/image-viewer-types.ts","../../../projects/libs/image-viewer/utils/download-print.ts","../../../projects/libs/image-viewer/utils/zoom-math.ts","../../../projects/libs/image-viewer/components/image-viewer.component.ts","../../../projects/libs/image-viewer/components/image-viewer.component.html","../../../projects/libs/image-viewer/ngx-kit-image-viewer.ts"],"sourcesContent":["export interface NgxImageViewerItem {\n src: string;\n alt?: string;\n caption?: string;\n downloadFileName?: string;\n}\n\n\nexport interface NgxImageViewerToolbarConfig {\n prevNext?: boolean;\n counter?: boolean;\n zoomIn?: boolean;\n zoomOut?: boolean;\n resetZoom?: boolean;\n rotateLeft?: boolean;\n rotateRight?: boolean;\n download?: boolean;\n print?: boolean;\n fullscreen?: boolean;\n close?: boolean;\n}\n\nexport const NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR: Required<NgxImageViewerToolbarConfig> = {\n prevNext: true,\n counter: true,\n zoomIn: true,\n zoomOut: true,\n resetZoom: true,\n rotateLeft: true,\n rotateRight: true,\n download: true,\n print: true,\n fullscreen: true,\n close: false,\n};\n","/** دانلود تصویر با fetch→blob (نام‌گذاریِ درست فایل رو تضمین می‌کنه)؛ اگه CORS اجازه نداد، در تب جدید باز می‌شه */\nexport async function downloadImage(src: string, filename?: string): Promise<void> {\n try {\n const response = await fetch(src, { mode: 'cors' });\n if (!response.ok) throw new Error('fetch failed');\n const blob = await response.blob();\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename || guessFileName(src);\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(url);\n } catch {\n window.open(src, '_blank', 'noopener,noreferrer');\n }\n}\n\nfunction guessFileName(src: string): string {\n try {\n const url = new URL(src, typeof window !== 'undefined' ? window.location.href : undefined);\n const last = url.pathname.split('/').pop();\n return last || 'image';\n } catch {\n return 'image';\n }\n}\n\n/** یه پنجره‌ی جدید فقط با همون تصویر باز می‌کنه و بعد از لود، print می‌زنه؛ با DOM API (نه innerHTML) پس در برابر src مخرب امنه */\nexport function printImage(src: string): void {\n const win = window.open('', '_blank', 'noopener,noreferrer,width=800,height=600');\n if (!win) return;\n\n win.document.title = 'Print';\n const style = win.document.createElement('style');\n style.textContent =\n 'body{margin:0;display:flex;align-items:center;justify-content:center;min-height:100vh;background:#fff;}img{max-width:100%;max-height:100vh;}';\n win.document.head.appendChild(style);\n\n const img = win.document.createElement('img');\n img.onload = () => {\n win.focus();\n win.print();\n };\n img.src = src;\n win.document.body.appendChild(img);\n}\n","export interface PanZoomState {\n zoom: number;\n panX: number;\n panY: number;\n}\n\n/**\n * با تغییر zoom، pan رو طوری تنظیم می‌کنه که نقطه‌ی زیر cursor/انگشت‌ها\n * (نسبت به مرکز کانتینر) سرجاش بمونه — یعنی zoom-to-cursor به‌جای\n * zoom-to-center (که تجربه‌ی خیلی بهتری داره، دقیقاً مثل هر ویوئر حرفه‌ای).\n *\n * ریاضیِ پشتش: با transform=\"translate(panX,panY) scale(zoom)\"، موقعیتِ\n * صفحه‌ایِ یه نقطه‌ی محلیِ p (نسبت به مرکز) برابره با\n * center + pan + p*zoom. اول p رو از روی وضعیت فعلی حساب می‌کنیم، بعد pan\n * جدید رو طوری می‌سازیم که با zoom تازه، همون p به همون مختصات صفحه برسه.\n */\nexport function zoomAroundPoint(\n current: PanZoomState,\n newZoom: number,\n cursorX: number,\n cursorY: number,\n containerWidth: number,\n containerHeight: number,\n): PanZoomState {\n const centerX = containerWidth / 2;\n const centerY = containerHeight / 2;\n const localX = (cursorX - centerX - current.panX) / current.zoom;\n const localY = (cursorY - centerY - current.panY) / current.zoom;\n return {\n zoom: newZoom,\n panX: cursorX - centerX - localX * newZoom,\n panY: cursorY - centerY - localY * newZoom,\n };\n}\n\nexport function distanceBetweenTouches(a: Touch, b: Touch): number {\n return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);\n}\n\nexport function midpointOfTouches(a: Touch, b: Touch): { x: number; y: number } {\n return { x: (a.clientX + b.clientX) / 2, y: (a.clientY + b.clientY) / 2 };\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n ElementRef,\n HostListener,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { startDragSession } from 'ngx-kit/core';\nimport {\n NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR,\n NgxImageViewerItem,\n NgxImageViewerToolbarConfig,\n} from '../contracts/image-viewer-types';\nimport { downloadImage, printImage } from '../utils/download-print';\nimport {\n clamp,\n distanceBetweenTouches,\n midpointOfTouches,\n zoomAroundPoint,\n} from '../utils/zoom-math';\n\n@Component({\n selector: 'ngx-image-viewer',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './image-viewer.component.html',\n styleUrl: './image-viewer.component.scss',\n host: { class: 'ngx-image-viewer-host', tabindex: '0' },\n})\nexport class NgxImageViewer {\n images = input.required<NgxImageViewerItem[]>();\n startIndex = input<number>(0);\n toolbar = input<NgxImageViewerToolbarConfig>({});\n minZoom = input<number>(1);\n maxZoom = input<number>(6);\n zoomStep = input<number>(0.4);\n\n indexChange = output<number>();\n closed = output<void>();\n\n protected readonly activeIndex = signal(0);\n protected readonly zoom = signal(1);\n protected readonly panX = signal(0);\n protected readonly panY = signal(0);\n protected readonly rotation = signal(0);\n\n protected readonly activeImage = computed<NgxImageViewerItem | undefined>(\n () => this.images()[this.activeIndex()],\n );\n\n protected readonly toolbarConfig = computed(() => ({\n ...NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR,\n ...this.toolbar(),\n }));\n\n protected readonly isZoomed = computed(() => this.zoom() > 1);\n\n protected readonly stageTransform = computed(\n () =>\n `translate(${this.panX()}px, ${this.panY()}px) scale(${this.zoom()}) rotate(${this.rotation()}deg)`,\n );\n\n private readonly stageEl = viewChild<ElementRef<HTMLElement>>('stage');\n private readonly hostElRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n\n private pinchStartDistance = 0;\n private pinchStartZoom = 1;\n private stopPanDrag?: () => void;\n\n constructor() {\n this.activeIndex.set(this.startIndex());\n\n effect((onCleanup) => {\n const stage = this.stageEl()?.nativeElement;\n if (!stage) return;\n\n const onWheel = (ev: WheelEvent) => {\n ev.preventDefault();\n const rect = stage.getBoundingClientRect();\n this.applyZoomAt(\n this.zoom() + (ev.deltaY < 0 ? 1 : -1) * this.zoomStep(),\n ev.clientX - rect.left,\n ev.clientY - rect.top,\n rect.width,\n rect.height,\n );\n };\n\n const onTouchStart = (ev: TouchEvent) => {\n if (ev.touches.length === 2) {\n this.stopPanDrag?.();\n this.pinchStartDistance = distanceBetweenTouches(ev.touches[0], ev.touches[1]);\n this.pinchStartZoom = this.zoom();\n } else if (ev.touches.length === 1 && this.isZoomed()) {\n this.beginPanDrag(ev);\n }\n };\n\n const onTouchMove = (ev: TouchEvent) => {\n if (ev.touches.length === 2 && this.pinchStartDistance > 0) {\n ev.preventDefault();\n const dist = distanceBetweenTouches(ev.touches[0], ev.touches[1]);\n const newZoom = (dist / this.pinchStartDistance) * this.pinchStartZoom;\n const rect = stage.getBoundingClientRect();\n const mid = midpointOfTouches(ev.touches[0], ev.touches[1]);\n this.applyZoomAt(newZoom, mid.x - rect.left, mid.y - rect.top, rect.width, rect.height);\n }\n };\n\n const onTouchEnd = () => {\n this.pinchStartDistance = 0;\n };\n\n stage.addEventListener('wheel', onWheel, { passive: false });\n stage.addEventListener('touchstart', onTouchStart, { passive: false });\n stage.addEventListener('touchmove', onTouchMove, { passive: false });\n stage.addEventListener('touchend', onTouchEnd);\n stage.addEventListener('touchcancel', onTouchEnd);\n\n onCleanup(() => {\n stage.removeEventListener('wheel', onWheel);\n stage.removeEventListener('touchstart', onTouchStart);\n stage.removeEventListener('touchmove', onTouchMove);\n stage.removeEventListener('touchend', onTouchEnd);\n stage.removeEventListener('touchcancel', onTouchEnd);\n });\n });\n\n this.destroyRef.onDestroy(() => this.stopPanDrag?.());\n }\n\n @HostListener('keydown', ['$event'])\n protected onKeydown(ev: KeyboardEvent): void {\n if (ev.key === 'ArrowLeft') this.prev();\n else if (ev.key === 'ArrowRight') this.next();\n else if (ev.key === '+' || ev.key === '=') this.zoomIn();\n else if (ev.key === '-') this.zoomOut();\n else if (ev.key === 'Escape') this.closed.emit();\n else return;\n ev.preventDefault();\n }\n\n protected next(): void {\n const len = this.images().length;\n if (len) this.goTo((this.activeIndex() + 1) % len);\n }\n\n protected prev(): void {\n const len = this.images().length;\n if (len) this.goTo((this.activeIndex() - 1 + len) % len);\n }\n\n protected goTo(index: number): void {\n this.activeIndex.set(index);\n this.resetView();\n this.indexChange.emit(index);\n }\n\n protected zoomIn(): void {\n this.setZoomAtCenter(this.zoom() + this.zoomStep());\n }\n\n protected zoomOut(): void {\n this.setZoomAtCenter(this.zoom() - this.zoomStep());\n }\n\n protected resetView(): void {\n this.zoom.set(1);\n this.panX.set(0);\n this.panY.set(0);\n this.rotation.set(0);\n }\n\n protected rotateLeft(): void {\n this.rotation.update((r) => r - 90);\n }\n\n protected rotateRight(): void {\n this.rotation.update((r) => r + 90);\n }\n\n protected async download(): Promise<void> {\n const img = this.activeImage();\n if (img) await downloadImage(img.src, img.downloadFileName);\n }\n\n protected print(): void {\n const img = this.activeImage();\n if (img) printImage(img.src);\n }\n\n protected toggleFullscreen(): void {\n const el = this.hostElRef.nativeElement;\n if (document.fullscreenElement) {\n document.exitFullscreen();\n } else {\n el.requestFullscreen?.();\n }\n }\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected onPanPointerDown(ev: MouseEvent): void {\n if (!this.isZoomed()) return;\n this.beginPanDrag(ev);\n }\n\n private beginPanDrag(ev: MouseEvent | TouchEvent): void {\n ev.preventDefault();\n const startPanX = this.panX();\n const startPanY = this.panY();\n const startX = this.clientXOf(ev);\n const startY = this.clientYOf(ev);\n this.stopPanDrag?.();\n this.stopPanDrag = startDragSession({\n onMove: (moveEv) => {\n this.panX.set(startPanX + (this.clientXOf(moveEv) - startX));\n this.panY.set(startPanY + (this.clientYOf(moveEv) - startY));\n },\n onEnd: () => {\n this.stopPanDrag = undefined;\n },\n });\n }\n\n private setZoomAtCenter(newZoom: number): void {\n const stage = this.stageEl()?.nativeElement;\n if (!stage) {\n this.zoom.set(clamp(newZoom, this.minZoom(), this.maxZoom()));\n return;\n }\n const rect = stage.getBoundingClientRect();\n this.applyZoomAt(newZoom, rect.width / 2, rect.height / 2, rect.width, rect.height);\n }\n\n private applyZoomAt(\n rawZoom: number,\n x: number,\n y: number,\n containerWidth: number,\n containerHeight: number,\n ): void {\n const newZoom = clamp(rawZoom, this.minZoom(), this.maxZoom());\n if (newZoom === this.zoom()) return;\n const result = zoomAroundPoint(\n { zoom: this.zoom(), panX: this.panX(), panY: this.panY() },\n newZoom,\n x,\n y,\n containerWidth,\n containerHeight,\n );\n this.zoom.set(result.zoom);\n this.panX.set(result.panX);\n this.panY.set(result.panY);\n }\n\n private clientXOf(ev: MouseEvent | TouchEvent): number {\n return 'touches' in ev\n ? (ev.touches[0]?.clientX ?? ev.changedTouches[0]?.clientX ?? 0)\n : ev.clientX;\n }\n\n private clientYOf(ev: MouseEvent | TouchEvent): number {\n return 'touches' in ev\n ? (ev.touches[0]?.clientY ?? ev.changedTouches[0]?.clientY ?? 0)\n : ev.clientY;\n }\n}\n","@if (toolbarConfig().close) {\n <button type=\"button\" class=\"ngx-iv-close\" (click)=\"close()\" aria-label=\"Close\">✕</button>\n}\n<div #stage class=\"ngx-iv-stage\" [class.zoomed]=\"isZoomed()\">\n @if (activeImage(); as img) {\n <img\n class=\"ngx-iv-image\"\n [class.grab]=\"isZoomed()\"\n [src]=\"img.src\"\n [alt]=\"img.alt || ''\"\n draggable=\"false\"\n [style.transform]=\"stageTransform()\"\n (mousedown)=\"onPanPointerDown($event)\" />\n }\n</div>\n@if (toolbarConfig().prevNext && images().length > 1) {\n <button type=\"button\" class=\"ngx-iv-nav ngx-iv-nav--prev\" (click)=\"prev()\" aria-label=\"Previous\">\n ‹\n </button>\n <button type=\"button\" class=\"ngx-iv-nav ngx-iv-nav--next\" (click)=\"next()\" aria-label=\"Next\">\n ›\n </button>\n}\n@if (activeImage()?.caption) {\n <div class=\"ngx-iv-caption\">{{ activeImage()?.caption }}</div>\n}\n<div class=\"ngx-iv-toolbar\">\n <div class=\"ngx-iv-toolbar--inner\">\n @if (toolbarConfig().counter && images().length > 1) {\n <div class=\"ngx-iv-counter\">{{ activeIndex() + 1 }} / {{ images().length }}</div>\n }\n @if (toolbarConfig().zoomOut) {\n <button type=\"button\" (click)=\"zoomOut()\" title=\"Zoom out\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M18.5016 18.5L21 21M20 14.5C20 11.4624 17.5376 9 14.5 9C11.4624 9 9 11.4624 9 14.5C9 17.5376 11.4624 20 14.5 20C17.5376 20 20 17.5376 20 14.5Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M16.5 14.5H12.5\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M10 3H14M3 10V14M6.5 21C4.567 21 3 19.433 3 17.5M17.5 3C19.433 3 21 4.567 21 6.5M3 6.5C3 4.567 4.567 3 6.5 3\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().zoomIn) {\n <button type=\"button\" (click)=\"zoomIn()\" title=\"Zoom in\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M18.5016 19.1217L21 21.6217M20 15.1217C20 12.0842 17.5376 9.62173 14.5 9.62173C11.4624 9.62173 9 12.0842 9 15.1217C9 18.1593 11.4624 20.6217 14.5 20.6217C17.5376 20.6217 20 18.1593 20 15.1217Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M14.5 13.1217V17.1217M16.5 15.1217H12.5\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M10 3.62173H14M3 10.6217V14.6217M6.5 21.6217C4.567 21.6217 3 20.0547 3 18.1217M17.5 3.62173C19.433 3.62173 21 5.18873 21 7.12173M3 7.12173C3 5.18873 4.567 3.62173 6.5 3.62173\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().resetZoom) {\n <button type=\"button\" (click)=\"resetView()\" title=\"Reset zoom\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M17 17L21 21\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M19 11C19 6.58172 15.4183 3 11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19C15.4183 19 19 15.4183 19 11Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.4924 7.5C8.77591 7.54342 8.31993 7.66286 7.99139 7.99139C7.66286 8.31993 7.54342 8.77591 7.5 9.4924M12.5076 7.5C13.2241 7.54342 13.6801 7.66286 14.0086 7.99139C14.3371 8.31993 14.4566 8.77591 14.5 9.4924M14.4923 12.6214C14.4431 13.273 14.3194 13.6978 14.0086 14.0086C13.6801 14.3371 13.2241 14.4566 12.5076 14.5M9.4924 14.5C8.7759 14.4566 8.31993 14.3371 7.99139 14.0086C7.6806 13.6978 7.55693 13.273 7.50772 12.6214\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().rotateLeft) {\n <button type=\"button\" (click)=\"rotateLeft()\" title=\"Rotate left\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3 15C3 18.2998 3 19.9497 4.02513 20.9749C5.05025 22 6.70017 22 10 22C13.2998 22 14.9497 22 15.9749 20.9749C17 19.9497 17 18.2998 17 15C17 11.7002 17 10.0503 15.9749 9.02513C14.9497 8 13.2998 8 10 8C6.70017 8 5.05025 8 4.02513 9.02513C3 10.0503 3 11.7002 3 15Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M14.4201 2L13.0744 3.11013C12.3581 3.70104 12 3.99649 12 4.36364L13 4.36364C16.7712 4.36364 18.6569 4.36364 19.8284 5.53521C21 6.70678 21 8.59241 21 12.3636V13\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().rotateRight) {\n <button type=\"button\" (click)=\"rotateRight()\" title=\"Rotate right\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7 15C7 18.2998 7 19.9497 8.02513 20.9749C9.05025 22 10.7002 22 14 22C17.2998 22 18.9497 22 19.9749 20.9749C21 19.9497 21 18.2998 21 15C21 11.7002 21 10.0503 19.9749 9.02513C18.9497 8 17.2998 8 14 8C10.7002 8 9.05025 8 8.02513 9.02513C7 10.0503 7 11.7002 7 15Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.57987 2L10.9256 3.11013C11.6419 3.70104 12 3.99649 12 4.36364L11 4.36364C7.22876 4.36364 5.34315 4.36364 4.17157 5.53521C3 6.70678 3 8.5924 3 12.3636V13\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().download) {\n <button type=\"button\" (click)=\"download()\" title=\"Download\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 14.5L12 4.5M12 14.5C11.2998 14.5 9.99153 12.5057 9.5 12M12 14.5C12.7002 14.5 14.0085 12.5057 14.5 12\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M20 16.5C20 18.982 19.482 19.5 17 19.5H7C4.518 19.5 4 18.982 4 16.5\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().print) {\n <button type=\"button\" (click)=\"print()\" title=\"Print\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.35396 18C5.23084 18 4.16928 18 3.41349 17.5468C2.91953 17.2506 2.52158 16.8271 2.26475 16.3242C1.87179 15.5547 1.97742 14.5373 2.18868 12.5025C2.36503 10.8039 2.45321 9.95455 2.88684 9.33081C3.17153 8.92129 3.55659 8.58564 4.00797 8.35353C4.69548 8 5.58164 8 7.35396 8H16.646C18.4184 8 19.3045 8 19.992 8.35353C20.4434 8.58564 20.8285 8.92129 21.1132 9.33081C21.5468 9.95455 21.635 10.8039 21.8113 12.5025C22.0226 14.5373 22.1282 15.5547 21.7352 16.3242C21.4784 16.8271 21.0805 17.2506 20.5865 17.5468C19.8307 18 18.7692 18 16.646 18\"\n stroke-width=\"1.5\" />\n <path\n d=\"M17 8V6C17 4.11438 17 3.17157 16.4142 2.58579C15.8284 2 14.8856 2 13 2H11C9.11438 2 8.17157 2 7.58579 2.58579C7 3.17157 7 4.11438 7 6V8\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M13.9887 16L10.0113 16C9.32602 16 8.98337 16 8.69183 16.1089C8.30311 16.254 7.97026 16.536 7.7462 16.9099C7.57815 17.1904 7.49505 17.5511 7.32884 18.2724C7.06913 19.3995 6.93928 19.963 7.02759 20.4149C7.14535 21.0174 7.51237 21.5274 8.02252 21.7974C8.40513 22 8.94052 22 10.0113 22L13.9887 22C15.0595 22 15.5949 22 15.9775 21.7974C16.4876 21.5274 16.8547 21.0174 16.9724 20.4149C17.0607 19.963 16.9309 19.3995 16.6712 18.2724C16.505 17.5511 16.4218 17.1904 16.2538 16.9099C16.0297 16.536 15.6969 16.254 15.3082 16.1089C15.0166 16 14.674 16 13.9887 16Z\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\" />\n <path d=\"M18 12H18.009\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().fullscreen) {\n <button type=\"button\" (click)=\"toggleFullscreen()\" title=\"Fullscreen\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.00001 3.09779C8.00001 3.09779 4.03375 2.74194 3.38784 3.38785C2.74192 4.03375 3.09784 8 3.09784 8\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M8.00001 20.9022C8.00001 20.9022 4.03375 21.2581 3.38784 20.6122C2.74192 19.9662 3.09784 16 3.09784 16\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M16 3.09779C16 3.09779 19.9663 2.74194 20.6122 3.38785C21.2581 4.03375 20.9022 8 20.9022 8\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M16 20.9022C16 20.9022 19.9663 21.2581 20.6122 20.6122C21.2581 19.9662 20.9022 16 20.9022 16\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M14.0108 9.99847L20.0625 3.94678\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.99696 14.0024L3.63966 20.3807\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.99733 10.0024L3.84571 3.85889\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M13.9795 14.0024L20.5279 20.4983\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ngx-kit-image-viewer.mjs","sources":["../../../projects/libs/image-viewer/contracts/image-viewer-types.ts","../../../projects/libs/image-viewer/utils/download-print.ts","../../../projects/libs/image-viewer/utils/zoom-math.ts","../../../projects/libs/image-viewer/components/image-viewer.component.ts","../../../projects/libs/image-viewer/components/image-viewer.component.html","../../../projects/libs/image-viewer/ngx-kit-image-viewer.ts"],"sourcesContent":["export interface NgxImageViewerItem {\n src: string;\n alt?: string;\n caption?: string;\n downloadFileName?: string;\n}\n\n\nexport interface NgxImageViewerToolbarConfig {\n prevNext?: boolean;\n counter?: boolean;\n zoomIn?: boolean;\n zoomOut?: boolean;\n resetZoom?: boolean;\n rotateLeft?: boolean;\n rotateRight?: boolean;\n download?: boolean;\n print?: boolean;\n fullscreen?: boolean;\n close?: boolean;\n}\n\nexport const NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR: Required<NgxImageViewerToolbarConfig> = {\n prevNext: true,\n counter: true,\n zoomIn: true,\n zoomOut: true,\n resetZoom: true,\n rotateLeft: true,\n rotateRight: true,\n download: true,\n print: true,\n fullscreen: true,\n close: false,\n};\n","/** دانلود تصویر با fetch→blob (نام‌گذاریِ درست فایل رو تضمین می‌کنه)؛ اگه CORS اجازه نداد، در تب جدید باز می‌شه */\nexport async function downloadImage(src: string, filename?: string): Promise<void> {\n try {\n const response = await fetch(src, { mode: 'cors' });\n if (!response.ok) throw new Error('fetch failed');\n const blob = await response.blob();\n const url = URL.createObjectURL(blob);\n const a = document.createElement('a');\n a.href = url;\n a.download = filename || guessFileName(src);\n document.body.appendChild(a);\n a.click();\n a.remove();\n URL.revokeObjectURL(url);\n } catch {\n window.open(src, '_blank', 'noopener,noreferrer');\n }\n}\n\nfunction guessFileName(src: string): string {\n try {\n const url = new URL(src, typeof window !== 'undefined' ? window.location.href : undefined);\n const last = url.pathname.split('/').pop();\n return last || 'image';\n } catch {\n return 'image';\n }\n}\n\n/** یه پنجره‌ی جدید فقط با همون تصویر باز می‌کنه و بعد از لود، print می‌زنه؛ با DOM API (نه innerHTML) پس در برابر src مخرب امنه */\nexport function printImage(src: string): void {\n const win = window.open('', '_blank', 'noopener,noreferrer,width=800,height=600');\n if (!win) return;\n\n win.document.title = 'Print';\n const style = win.document.createElement('style');\n style.textContent =\n 'body{margin:0;display:flex;align-items:center;justify-content:center;min-height:100vh;background:#fff;}img{max-width:100%;max-height:100vh;}';\n win.document.head.appendChild(style);\n\n const img = win.document.createElement('img');\n img.onload = () => {\n win.focus();\n win.print();\n };\n img.src = src;\n win.document.body.appendChild(img);\n}\n","export interface PanZoomState {\n zoom: number;\n panX: number;\n panY: number;\n}\n\n/**\n * با تغییر zoom، pan رو طوری تنظیم می‌کنه که نقطه‌ی زیر cursor/انگشت‌ها\n * (نسبت به مرکز کانتینر) سرجاش بمونه — یعنی zoom-to-cursor به‌جای\n * zoom-to-center (که تجربه‌ی خیلی بهتری داره، دقیقاً مثل هر ویوئر حرفه‌ای).\n *\n * ریاضیِ پشتش: با transform=\"translate(panX,panY) scale(zoom)\"، موقعیتِ\n * صفحه‌ایِ یه نقطه‌ی محلیِ p (نسبت به مرکز) برابره با\n * center + pan + p*zoom. اول p رو از روی وضعیت فعلی حساب می‌کنیم، بعد pan\n * جدید رو طوری می‌سازیم که با zoom تازه، همون p به همون مختصات صفحه برسه.\n */\nexport function zoomAroundPoint(\n current: PanZoomState,\n newZoom: number,\n cursorX: number,\n cursorY: number,\n containerWidth: number,\n containerHeight: number,\n): PanZoomState {\n const centerX = containerWidth / 2;\n const centerY = containerHeight / 2;\n const localX = (cursorX - centerX - current.panX) / current.zoom;\n const localY = (cursorY - centerY - current.panY) / current.zoom;\n return {\n zoom: newZoom,\n panX: cursorX - centerX - localX * newZoom,\n panY: cursorY - centerY - localY * newZoom,\n };\n}\n\nexport function distanceBetweenTouches(a: Touch, b: Touch): number {\n return Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);\n}\n\nexport function midpointOfTouches(a: Touch, b: Touch): { x: number; y: number } {\n return { x: (a.clientX + b.clientX) / 2, y: (a.clientY + b.clientY) / 2 };\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value));\n}\n","import {\n ChangeDetectionStrategy,\n Component,\n DOCUMENT,\n DestroyRef,\n ElementRef,\n HostListener,\n computed,\n effect,\n inject,\n input,\n output,\n signal,\n viewChild,\n} from '@angular/core';\nimport { startDragSession } from 'ngx-kit/core';\nimport {\n NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR,\n NgxImageViewerItem,\n NgxImageViewerToolbarConfig,\n} from '../contracts/image-viewer-types';\nimport { downloadImage, printImage } from '../utils/download-print';\nimport {\n clamp,\n distanceBetweenTouches,\n midpointOfTouches,\n zoomAroundPoint,\n} from '../utils/zoom-math';\n\n@Component({\n selector: 'ngx-image-viewer',\n standalone: true,\n changeDetection: ChangeDetectionStrategy.OnPush,\n templateUrl: './image-viewer.component.html',\n styleUrl: './image-viewer.component.scss',\n host: { class: 'ngx-image-viewer-host', tabindex: '0' },\n})\nexport class NgxImageViewer {\n images = input.required<NgxImageViewerItem[]>();\n startIndex = input<number>(0);\n toolbar = input<NgxImageViewerToolbarConfig>({});\n minZoom = input<number>(1);\n maxZoom = input<number>(6);\n zoomStep = input<number>(0.4);\n\n indexChange = output<number>();\n closed = output<void>();\n\n protected readonly activeIndex = signal(0);\n protected readonly zoom = signal(1);\n protected readonly panX = signal(0);\n protected readonly panY = signal(0);\n protected readonly rotation = signal(0);\n\n protected readonly activeImage = computed<NgxImageViewerItem | undefined>(\n () => this.images()[this.activeIndex()],\n );\n\n protected readonly toolbarConfig = computed(() => ({\n ...NGX_IMAGE_VIEWER_DEFAULT_TOOLBAR,\n ...this.toolbar(),\n }));\n\n protected readonly isZoomed = computed(() => this.zoom() > 1);\n\n protected readonly stageTransform = computed(\n () =>\n `translate(${this.panX()}px, ${this.panY()}px) scale(${this.zoom()}) rotate(${this.rotation()}deg)`,\n );\n\n private readonly stageEl = viewChild<ElementRef<HTMLElement>>('stage');\n private readonly hostElRef = inject(ElementRef<HTMLElement>);\n private readonly destroyRef = inject(DestroyRef);\n private readonly doc = inject(DOCUMENT);\n\n private pinchStartDistance = 0;\n private pinchStartZoom = 1;\n private stopPanDrag?: () => void;\n\n constructor() {\n this.activeIndex.set(this.startIndex());\n\n effect((onCleanup) => {\n const stage = this.stageEl()?.nativeElement;\n if (!stage) return;\n\n const onWheel = (ev: WheelEvent) => {\n ev.preventDefault();\n const rect = stage.getBoundingClientRect();\n this.applyZoomAt(\n this.zoom() + (ev.deltaY < 0 ? 1 : -1) * this.zoomStep(),\n ev.clientX - rect.left,\n ev.clientY - rect.top,\n rect.width,\n rect.height,\n );\n };\n\n const onTouchStart = (ev: TouchEvent) => {\n if (ev.touches.length === 2) {\n this.stopPanDrag?.();\n this.pinchStartDistance = distanceBetweenTouches(ev.touches[0], ev.touches[1]);\n this.pinchStartZoom = this.zoom();\n } else if (ev.touches.length === 1 && this.isZoomed()) {\n this.beginPanDrag(ev);\n }\n };\n\n const onTouchMove = (ev: TouchEvent) => {\n if (ev.touches.length === 2 && this.pinchStartDistance > 0) {\n ev.preventDefault();\n const dist = distanceBetweenTouches(ev.touches[0], ev.touches[1]);\n const newZoom = (dist / this.pinchStartDistance) * this.pinchStartZoom;\n const rect = stage.getBoundingClientRect();\n const mid = midpointOfTouches(ev.touches[0], ev.touches[1]);\n this.applyZoomAt(newZoom, mid.x - rect.left, mid.y - rect.top, rect.width, rect.height);\n }\n };\n\n const onTouchEnd = () => {\n this.pinchStartDistance = 0;\n };\n\n stage.addEventListener('wheel', onWheel, { passive: false });\n stage.addEventListener('touchstart', onTouchStart, { passive: false });\n stage.addEventListener('touchmove', onTouchMove, { passive: false });\n stage.addEventListener('touchend', onTouchEnd);\n stage.addEventListener('touchcancel', onTouchEnd);\n\n onCleanup(() => {\n stage.removeEventListener('wheel', onWheel);\n stage.removeEventListener('touchstart', onTouchStart);\n stage.removeEventListener('touchmove', onTouchMove);\n stage.removeEventListener('touchend', onTouchEnd);\n stage.removeEventListener('touchcancel', onTouchEnd);\n });\n });\n\n this.destroyRef.onDestroy(() => this.stopPanDrag?.());\n }\n\n @HostListener('keydown', ['$event'])\n protected onKeydown(ev: KeyboardEvent): void {\n if (ev.key === 'ArrowLeft') this.prev();\n else if (ev.key === 'ArrowRight') this.next();\n else if (ev.key === '+' || ev.key === '=') this.zoomIn();\n else if (ev.key === '-') this.zoomOut();\n else if (ev.key === 'Escape') this.closed.emit();\n else return;\n ev.preventDefault();\n }\n\n protected next(): void {\n const len = this.images().length;\n if (len) this.goTo((this.activeIndex() + 1) % len);\n }\n\n protected prev(): void {\n const len = this.images().length;\n if (len) this.goTo((this.activeIndex() - 1 + len) % len);\n }\n\n protected goTo(index: number): void {\n this.activeIndex.set(index);\n this.resetView();\n this.indexChange.emit(index);\n }\n\n protected zoomIn(): void {\n this.setZoomAtCenter(this.zoom() + this.zoomStep());\n }\n\n protected zoomOut(): void {\n this.setZoomAtCenter(this.zoom() - this.zoomStep());\n }\n\n protected resetView(): void {\n this.zoom.set(1);\n this.panX.set(0);\n this.panY.set(0);\n this.rotation.set(0);\n }\n\n protected rotateLeft(): void {\n this.rotation.update((r) => r - 90);\n }\n\n protected rotateRight(): void {\n this.rotation.update((r) => r + 90);\n }\n\n protected async download(): Promise<void> {\n const img = this.activeImage();\n if (img) await downloadImage(img.src, img.downloadFileName);\n }\n\n protected print(): void {\n const img = this.activeImage();\n if (img) printImage(img.src);\n }\n\n protected toggleFullscreen(): void {\n const el = this.hostElRef.nativeElement;\n if (this.doc.fullscreenElement) {\n this.doc.exitFullscreen();\n } else {\n el.requestFullscreen?.();\n }\n }\n\n protected close(): void {\n this.closed.emit();\n }\n\n protected onPanPointerDown(ev: MouseEvent): void {\n if (!this.isZoomed()) return;\n this.beginPanDrag(ev);\n }\n\n private beginPanDrag(ev: MouseEvent | TouchEvent): void {\n ev.preventDefault();\n const startPanX = this.panX();\n const startPanY = this.panY();\n const startX = this.clientXOf(ev);\n const startY = this.clientYOf(ev);\n this.stopPanDrag?.();\n this.stopPanDrag = startDragSession({\n doc: this.doc,\n onMove: (moveEv) => {\n this.panX.set(startPanX + (this.clientXOf(moveEv) - startX));\n this.panY.set(startPanY + (this.clientYOf(moveEv) - startY));\n },\n onEnd: () => {\n this.stopPanDrag = undefined;\n },\n });\n }\n\n private setZoomAtCenter(newZoom: number): void {\n const stage = this.stageEl()?.nativeElement;\n if (!stage) {\n this.zoom.set(clamp(newZoom, this.minZoom(), this.maxZoom()));\n return;\n }\n const rect = stage.getBoundingClientRect();\n this.applyZoomAt(newZoom, rect.width / 2, rect.height / 2, rect.width, rect.height);\n }\n\n private applyZoomAt(\n rawZoom: number,\n x: number,\n y: number,\n containerWidth: number,\n containerHeight: number,\n ): void {\n const newZoom = clamp(rawZoom, this.minZoom(), this.maxZoom());\n if (newZoom === this.zoom()) return;\n const result = zoomAroundPoint(\n { zoom: this.zoom(), panX: this.panX(), panY: this.panY() },\n newZoom,\n x,\n y,\n containerWidth,\n containerHeight,\n );\n this.zoom.set(result.zoom);\n this.panX.set(result.panX);\n this.panY.set(result.panY);\n }\n\n private clientXOf(ev: MouseEvent | TouchEvent): number {\n return 'touches' in ev\n ? (ev.touches[0]?.clientX ?? ev.changedTouches[0]?.clientX ?? 0)\n : ev.clientX;\n }\n\n private clientYOf(ev: MouseEvent | TouchEvent): number {\n return 'touches' in ev\n ? (ev.touches[0]?.clientY ?? ev.changedTouches[0]?.clientY ?? 0)\n : ev.clientY;\n }\n}\n","@if (toolbarConfig().close) {\n <button type=\"button\" class=\"ngx-iv-close\" (click)=\"close()\" aria-label=\"Close\">✕</button>\n}\n<div #stage class=\"ngx-iv-stage\" [class.zoomed]=\"isZoomed()\">\n @if (activeImage(); as img) {\n <img\n class=\"ngx-iv-image\"\n [class.grab]=\"isZoomed()\"\n [src]=\"img.src\"\n [alt]=\"img.alt || ''\"\n draggable=\"false\"\n [style.transform]=\"stageTransform()\"\n (mousedown)=\"onPanPointerDown($event)\" />\n }\n</div>\n@if (toolbarConfig().prevNext && images().length > 1) {\n <button type=\"button\" class=\"ngx-iv-nav ngx-iv-nav--prev\" (click)=\"prev()\" aria-label=\"Previous\">\n ‹\n </button>\n <button type=\"button\" class=\"ngx-iv-nav ngx-iv-nav--next\" (click)=\"next()\" aria-label=\"Next\">\n ›\n </button>\n}\n@if (activeImage()?.caption) {\n <div class=\"ngx-iv-caption\">{{ activeImage()?.caption }}</div>\n}\n<div class=\"ngx-iv-toolbar\">\n <div class=\"ngx-iv-toolbar--inner\">\n @if (toolbarConfig().counter && images().length > 1) {\n <div class=\"ngx-iv-counter\">{{ activeIndex() + 1 }} / {{ images().length }}</div>\n }\n @if (toolbarConfig().zoomOut) {\n <button type=\"button\" (click)=\"zoomOut()\" title=\"Zoom out\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M18.5016 18.5L21 21M20 14.5C20 11.4624 17.5376 9 14.5 9C11.4624 9 9 11.4624 9 14.5C9 17.5376 11.4624 20 14.5 20C17.5376 20 20 17.5376 20 14.5Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M16.5 14.5H12.5\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M10 3H14M3 10V14M6.5 21C4.567 21 3 19.433 3 17.5M17.5 3C19.433 3 21 4.567 21 6.5M3 6.5C3 4.567 4.567 3 6.5 3\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().zoomIn) {\n <button type=\"button\" (click)=\"zoomIn()\" title=\"Zoom in\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M18.5016 19.1217L21 21.6217M20 15.1217C20 12.0842 17.5376 9.62173 14.5 9.62173C11.4624 9.62173 9 12.0842 9 15.1217C9 18.1593 11.4624 20.6217 14.5 20.6217C17.5376 20.6217 20 18.1593 20 15.1217Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M14.5 13.1217V17.1217M16.5 15.1217H12.5\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M10 3.62173H14M3 10.6217V14.6217M6.5 21.6217C4.567 21.6217 3 20.0547 3 18.1217M17.5 3.62173C19.433 3.62173 21 5.18873 21 7.12173M3 7.12173C3 5.18873 4.567 3.62173 6.5 3.62173\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().resetZoom) {\n <button type=\"button\" (click)=\"resetView()\" title=\"Reset zoom\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M17 17L21 21\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M19 11C19 6.58172 15.4183 3 11 3C6.58172 3 3 6.58172 3 11C3 15.4183 6.58172 19 11 19C15.4183 19 19 15.4183 19 11Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.4924 7.5C8.77591 7.54342 8.31993 7.66286 7.99139 7.99139C7.66286 8.31993 7.54342 8.77591 7.5 9.4924M12.5076 7.5C13.2241 7.54342 13.6801 7.66286 14.0086 7.99139C14.3371 8.31993 14.4566 8.77591 14.5 9.4924M14.4923 12.6214C14.4431 13.273 14.3194 13.6978 14.0086 14.0086C13.6801 14.3371 13.2241 14.4566 12.5076 14.5M9.4924 14.5C8.7759 14.4566 8.31993 14.3371 7.99139 14.0086C7.6806 13.6978 7.55693 13.273 7.50772 12.6214\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().rotateLeft) {\n <button type=\"button\" (click)=\"rotateLeft()\" title=\"Rotate left\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3 15C3 18.2998 3 19.9497 4.02513 20.9749C5.05025 22 6.70017 22 10 22C13.2998 22 14.9497 22 15.9749 20.9749C17 19.9497 17 18.2998 17 15C17 11.7002 17 10.0503 15.9749 9.02513C14.9497 8 13.2998 8 10 8C6.70017 8 5.05025 8 4.02513 9.02513C3 10.0503 3 11.7002 3 15Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M14.4201 2L13.0744 3.11013C12.3581 3.70104 12 3.99649 12 4.36364L13 4.36364C16.7712 4.36364 18.6569 4.36364 19.8284 5.53521C21 6.70678 21 8.59241 21 12.3636V13\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().rotateRight) {\n <button type=\"button\" (click)=\"rotateRight()\" title=\"Rotate right\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7 15C7 18.2998 7 19.9497 8.02513 20.9749C9.05025 22 10.7002 22 14 22C17.2998 22 18.9497 22 19.9749 20.9749C21 19.9497 21 18.2998 21 15C21 11.7002 21 10.0503 19.9749 9.02513C18.9497 8 17.2998 8 14 8C10.7002 8 9.05025 8 8.02513 9.02513C7 10.0503 7 11.7002 7 15Z\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.57987 2L10.9256 3.11013C11.6419 3.70104 12 3.99649 12 4.36364L11 4.36364C7.22876 4.36364 5.34315 4.36364 4.17157 5.53521C3 6.70678 3 8.5924 3 12.3636V13\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().download) {\n <button type=\"button\" (click)=\"download()\" title=\"Download\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 14.5L12 4.5M12 14.5C11.2998 14.5 9.99153 12.5057 9.5 12M12 14.5C12.7002 14.5 14.0085 12.5057 14.5 12\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M20 16.5C20 18.982 19.482 19.5 17 19.5H7C4.518 19.5 4 18.982 4 16.5\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().print) {\n <button type=\"button\" (click)=\"print()\" title=\"Print\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M7.35396 18C5.23084 18 4.16928 18 3.41349 17.5468C2.91953 17.2506 2.52158 16.8271 2.26475 16.3242C1.87179 15.5547 1.97742 14.5373 2.18868 12.5025C2.36503 10.8039 2.45321 9.95455 2.88684 9.33081C3.17153 8.92129 3.55659 8.58564 4.00797 8.35353C4.69548 8 5.58164 8 7.35396 8H16.646C18.4184 8 19.3045 8 19.992 8.35353C20.4434 8.58564 20.8285 8.92129 21.1132 9.33081C21.5468 9.95455 21.635 10.8039 21.8113 12.5025C22.0226 14.5373 22.1282 15.5547 21.7352 16.3242C21.4784 16.8271 21.0805 17.2506 20.5865 17.5468C19.8307 18 18.7692 18 16.646 18\"\n stroke-width=\"1.5\" />\n <path\n d=\"M17 8V6C17 4.11438 17 3.17157 16.4142 2.58579C15.8284 2 14.8856 2 13 2H11C9.11438 2 8.17157 2 7.58579 2.58579C7 3.17157 7 4.11438 7 6V8\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M13.9887 16L10.0113 16C9.32602 16 8.98337 16 8.69183 16.1089C8.30311 16.254 7.97026 16.536 7.7462 16.9099C7.57815 17.1904 7.49505 17.5511 7.32884 18.2724C7.06913 19.3995 6.93928 19.963 7.02759 20.4149C7.14535 21.0174 7.51237 21.5274 8.02252 21.7974C8.40513 22 8.94052 22 10.0113 22L13.9887 22C15.0595 22 15.5949 22 15.9775 21.7974C16.4876 21.5274 16.8547 21.0174 16.9724 20.4149C17.0607 19.963 16.9309 19.3995 16.6712 18.2724C16.505 17.5511 16.4218 17.1904 16.2538 16.9099C16.0297 16.536 15.6969 16.254 15.3082 16.1089C15.0166 16 14.674 16 13.9887 16Z\"\n stroke-width=\"1.5\"\n stroke-linejoin=\"round\" />\n <path d=\"M18 12H18.009\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n @if (toolbarConfig().fullscreen) {\n <button type=\"button\" (click)=\"toggleFullscreen()\" title=\"Fullscreen\">\n <svg\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M8.00001 3.09779C8.00001 3.09779 4.03375 2.74194 3.38784 3.38785C2.74192 4.03375 3.09784 8 3.09784 8\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M8.00001 20.9022C8.00001 20.9022 4.03375 21.2581 3.38784 20.6122C2.74192 19.9662 3.09784 16 3.09784 16\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M16 3.09779C16 3.09779 19.9663 2.74194 20.6122 3.38785C21.2581 4.03375 20.9022 8 20.9022 8\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M16 20.9022C16 20.9022 19.9663 21.2581 20.6122 20.6122C21.2581 19.9662 20.9022 16 20.9022 16\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M14.0108 9.99847L20.0625 3.94678\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.99696 14.0024L3.63966 20.3807\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M9.99733 10.0024L3.84571 3.85889\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path\n d=\"M13.9795 14.0024L20.5279 20.4983\"\n stroke-width=\"1.5\"\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n }\n </div>\n</div>\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}