epub-flow 0.0.1 → 0.0.3

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.
@@ -14,15 +14,8 @@ import { Editor, NgxEditorModule } from 'ngx-editor';
14
14
  import * as i1$1 from '@angular/cdk/overlay';
15
15
  import { OverlayConfig } from '@angular/cdk/overlay';
16
16
  import { ComponentPortal } from '@angular/cdk/portal';
17
- import * as i4 from 'primeng/api';
18
17
  import * as i1$3 from '@angular/platform-browser';
19
- import * as i8 from 'primeng/tabview';
20
- import { TabViewModule } from 'primeng/tabview';
21
18
  import ePub from 'epubjs';
22
- import * as i1$4 from 'primeng/progressbar';
23
- import { ProgressBarModule } from 'primeng/progressbar';
24
- import { TableModule } from 'primeng/table';
25
- import { ButtonModule } from 'primeng/button';
26
19
 
27
20
  class EpubReaderService {
28
21
  http;
@@ -197,13 +190,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
197
190
  args: [{ providedIn: 'root' }]
198
191
  }] });
199
192
 
193
+ class NotificationService {
194
+ notificationSubject = new Subject();
195
+ notifications$ = this.notificationSubject.asObservable();
196
+ counter = 0;
197
+ show(message, type = 'info', title, duration = 3000) {
198
+ this.notificationSubject.next({
199
+ id: ++this.counter,
200
+ message,
201
+ type,
202
+ title,
203
+ duration
204
+ });
205
+ }
206
+ success(message, title = 'Success', duration) {
207
+ this.show(message, 'success', title, duration);
208
+ }
209
+ error(message, title = 'Error', duration) {
210
+ this.show(message, 'error', title, duration);
211
+ }
212
+ info(message, title = 'Info', duration) {
213
+ this.show(message, 'info', title, duration);
214
+ }
215
+ warn(message, title = 'Warning', duration) {
216
+ this.show(message, 'warning', title, duration);
217
+ }
218
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
219
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: NotificationService, providedIn: 'root' });
220
+ }
221
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: NotificationService, decorators: [{
222
+ type: Injectable,
223
+ args: [{
224
+ providedIn: 'root'
225
+ }]
226
+ }] });
227
+
200
228
  class AddNotesComponent {
201
229
  dialog;
202
230
  sharedService;
203
231
  epubReader;
204
232
  userApi;
205
233
  dialogRef;
206
- messageService;
234
+ notificationService;
207
235
  editor; // Editor instance
208
236
  textToAddorEdit;
209
237
  toolbar = [
@@ -230,13 +258,13 @@ class AddNotesComponent {
230
258
  return this.form.get('editorContent');
231
259
  }
232
260
  onDestroy$ = new Subject();
233
- constructor(dialog, sharedService, epubReader, userApi, dialogRef, messageService) {
261
+ constructor(dialog, sharedService, epubReader, userApi, dialogRef, notificationService) {
234
262
  this.dialog = dialog;
235
263
  this.sharedService = sharedService;
236
264
  this.epubReader = epubReader;
237
265
  this.userApi = userApi;
238
266
  this.dialogRef = dialogRef;
239
- this.messageService = messageService;
267
+ this.notificationService = notificationService;
240
268
  }
241
269
  ngOnInit() {
242
270
  // Initialize the editor
@@ -301,12 +329,7 @@ class AddNotesComponent {
301
329
  .pipe(takeUntil(this.onDestroy$))
302
330
  .subscribe({
303
331
  next: (res) => {
304
- this.messageService.add({
305
- key: 'notifyToast',
306
- severity: 'success', // Use 'warn' for orange color
307
- summary: 'Success',
308
- detail: res.message,
309
- });
332
+ this.notificationService.success(res.message);
310
333
  this.dialog.closeAll();
311
334
  },
312
335
  error: (err) => {
@@ -347,12 +370,7 @@ class AddNotesComponent {
347
370
  .pipe(takeUntil(this.onDestroy$))
348
371
  .subscribe({
349
372
  next: (res) => {
350
- this.messageService.add({
351
- key: 'notifyToast',
352
- severity: 'success', // Use 'warn' for orange color
353
- summary: 'Success',
354
- detail: res.message,
355
- });
373
+ this.notificationService.success(res.message);
356
374
  this.dialog.closeAll();
357
375
  },
358
376
  error: (err) => {
@@ -364,13 +382,13 @@ class AddNotesComponent {
364
382
  },
365
383
  });
366
384
  }
367
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AddNotesComponent, deps: [{ token: CustomDialogService }, { token: SharedService }, { token: EpubReaderService }, { token: HttpApiService }, { token: CustomDialogRef }, { token: i4.MessageService }], target: i0.ɵɵFactoryTarget.Component });
385
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AddNotesComponent, deps: [{ token: CustomDialogService }, { token: SharedService }, { token: EpubReaderService }, { token: HttpApiService }, { token: CustomDialogRef }, { token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
368
386
  static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: AddNotesComponent, isStandalone: false, selector: "app-add-notes", host: { listeners: { "document:dragover": "onDragOver($event)", "document:drop": "onDrop($event)", "document:dragstart": "onDragStart($event)", "document:contextmenu": "onRightClick($event)", "document:keydown": "onKeyDown($event)", "document:copy": "onCopy($event)" } }, ngImport: i0, template: "<div class=\"note-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">{{ dialogRef.data.addNote ? 'Add Note' : 'Edit Note' }}</h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n <form class=\"note-form\" [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <!-- Editor Section -->\n <section class=\"editor-section\">\n <ngx-editor-menu [editor]=\"editor\" [toolbar]=\"toolbar\">\n </ngx-editor-menu>\n\n <ngx-editor class=\"editor-body\" [editor]=\"editor\" formControlName=\"editorContent\">\n </ngx-editor>\n </section>\n\n <!-- Validation -->\n <p class=\"error\" *ngIf=\"editorContent.invalid && editorContent.touched\">\n Content is required.\n </p>\n\n <!-- Footer / Actions -->\n <footer class=\"action-bar\">\n @if (dialogRef.data.addNote) {\n <button type=\"submit\" class=\"btn btn-primary\" (click)=\"addNote()\"\n [disabled]=\"!hasValidContent(editorContent.value) || isSubmitting\">\n Add Note\n </button>\n } @else {\n <button type=\"submit\" class=\"btn btn-primary\" (click)=\"updateNote()\"\n [disabled]=\"!hasValidContent(editorContent.value) || isSubmitting\">\n Update Note\n </button>\n }\n </footer>\n </form>\n</div>", styles: [":host{display:block;font-family:Figtree,sans-serif;--primary: #34c759;--primary-hover: #2ebd50;--bg: #ffffff;--text: #1f2937;--border: #e5e7eb}:host-context(.dark-mode){--bg: #1f2937;--text: #f9fafb;--border: #374151}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuBar{background:#1f2937;border-color:#374151}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuItem{color:#e5e7eb}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuItem:hover{background-color:#374151;color:#fff}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuItem.NgxEditor__MenuItem--Active{background-color:#374151;color:#34c759}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuItem svg{fill:currentColor}:host-context(.dark-mode) ::ng-deep .NgxEditor__Dropdown .NgxEditor__Dropdown--Selected,:host-context(.dark-mode) ::ng-deep .NgxEditor__Dropdown .NgxEditor__Dropdown--Open,:host-context(.dark-mode) ::ng-deep .NgxEditor__Dropdown:hover{background-color:#374151;color:#fff}.note-container{width:100%;max-width:560px;height:auto;min-height:480px;max-height:85vh;background:var(--bg);color:var(--text);border-radius:16px;box-shadow:0 20px 25px -5px #00000026;overflow:hidden;display:flex;flex-direction:column}.popup-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px 0}.popup-title{margin:0;font-size:1.125rem;font-weight:600;color:var(--text)}.close-btn{background:transparent;border:none;cursor:pointer;padding:8px;margin:-8px -8px -8px 0;border-radius:50%;color:var(--text);display:flex;align-items:center;justify-content:center;opacity:.7;transition:all .2s}.close-btn:hover{background-color:#0000000d;opacity:1}:host-context(.dark-mode) .close-btn:hover{background-color:#ffffff1a}.note-form{display:flex;flex-direction:column;flex:1;padding:1.5rem;overflow:hidden}.editor-section{display:flex;flex-direction:column;flex:1;min-height:250px;border:1px solid var(--border);border-radius:12px;overflow:hidden;transition:border-color .2s ease;background:var(--bg)}.editor-section:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px #34c75926}::ng-deep .NgxEditor__MenuBar{background:var(--bg);border-bottom:1px solid var(--border);padding:.5rem;gap:.25rem;flex-wrap:wrap}::ng-deep .NgxEditor{flex:1;height:100%;min-height:300px;padding:1rem;border:none!important;background:var(--bg);color:var(--text);font-size:.95rem;line-height:1.6;overflow-y:auto}.error{color:#ef4444;font-size:.85rem;margin:.5rem 0 0}.action-bar{display:flex;justify-content:flex-end;padding-top:.75rem}::ng-deep .NgxEditor__Popup{position:absolute;top:calc(var(--ngx-editor-menubar-height) + 2px);box-shadow:var(--ngx-editor-popup-shadow);border-radius:var(--ngx-editor-popup-border-radius);background-color:var(--ngx-editor-popup-bg-color);z-index:100;min-width:101px;padding:8px;right:2px}.btn{min-width:140px;padding:10px 24px;border-radius:10px;font-weight:600;border:none;cursor:pointer;transition:all .2s ease}.btn-primary{background:var(--primary);color:#fff;box-shadow:0 4px 6px #34c7594d}.btn-primary:hover:not(:disabled){background:var(--primary-hover);transform:translateY(-1px)}.btn-primary:disabled{opacity:.6;cursor:not-allowed;box-shadow:none}@media (max-width: 640px){.note-container{height:100vh;border-radius:0}.note-form{padding:.75rem}.action-bar{justify-content:stretch}.btn{width:100%}}\n"], dependencies: [{ kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: i6.NgxEditorComponent, selector: "ngx-editor", inputs: ["editor", "outputFormat", "placeholder"], outputs: ["focusOut", "focusIn"] }, { kind: "component", type: i6.NgxEditorMenuComponent, selector: "ngx-editor-menu", inputs: ["toolbar", "colorPresets", "disabled", "editor", "customMenuRef", "dropdownPlacement"] }, { kind: "directive", type: i7.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i7.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }] });
369
387
  }
370
388
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: AddNotesComponent, decorators: [{
371
389
  type: Component,
372
390
  args: [{ selector: 'app-add-notes', standalone: false, template: "<div class=\"note-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">{{ dialogRef.data.addNote ? 'Add Note' : 'Edit Note' }}</h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n <form class=\"note-form\" [formGroup]=\"form\" (ngSubmit)=\"onSubmit()\">\n <!-- Editor Section -->\n <section class=\"editor-section\">\n <ngx-editor-menu [editor]=\"editor\" [toolbar]=\"toolbar\">\n </ngx-editor-menu>\n\n <ngx-editor class=\"editor-body\" [editor]=\"editor\" formControlName=\"editorContent\">\n </ngx-editor>\n </section>\n\n <!-- Validation -->\n <p class=\"error\" *ngIf=\"editorContent.invalid && editorContent.touched\">\n Content is required.\n </p>\n\n <!-- Footer / Actions -->\n <footer class=\"action-bar\">\n @if (dialogRef.data.addNote) {\n <button type=\"submit\" class=\"btn btn-primary\" (click)=\"addNote()\"\n [disabled]=\"!hasValidContent(editorContent.value) || isSubmitting\">\n Add Note\n </button>\n } @else {\n <button type=\"submit\" class=\"btn btn-primary\" (click)=\"updateNote()\"\n [disabled]=\"!hasValidContent(editorContent.value) || isSubmitting\">\n Update Note\n </button>\n }\n </footer>\n </form>\n</div>", styles: [":host{display:block;font-family:Figtree,sans-serif;--primary: #34c759;--primary-hover: #2ebd50;--bg: #ffffff;--text: #1f2937;--border: #e5e7eb}:host-context(.dark-mode){--bg: #1f2937;--text: #f9fafb;--border: #374151}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuBar{background:#1f2937;border-color:#374151}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuItem{color:#e5e7eb}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuItem:hover{background-color:#374151;color:#fff}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuItem.NgxEditor__MenuItem--Active{background-color:#374151;color:#34c759}:host-context(.dark-mode) ::ng-deep .NgxEditor__MenuItem svg{fill:currentColor}:host-context(.dark-mode) ::ng-deep .NgxEditor__Dropdown .NgxEditor__Dropdown--Selected,:host-context(.dark-mode) ::ng-deep .NgxEditor__Dropdown .NgxEditor__Dropdown--Open,:host-context(.dark-mode) ::ng-deep .NgxEditor__Dropdown:hover{background-color:#374151;color:#fff}.note-container{width:100%;max-width:560px;height:auto;min-height:480px;max-height:85vh;background:var(--bg);color:var(--text);border-radius:16px;box-shadow:0 20px 25px -5px #00000026;overflow:hidden;display:flex;flex-direction:column}.popup-header{display:flex;justify-content:space-between;align-items:center;padding:16px 20px 0}.popup-title{margin:0;font-size:1.125rem;font-weight:600;color:var(--text)}.close-btn{background:transparent;border:none;cursor:pointer;padding:8px;margin:-8px -8px -8px 0;border-radius:50%;color:var(--text);display:flex;align-items:center;justify-content:center;opacity:.7;transition:all .2s}.close-btn:hover{background-color:#0000000d;opacity:1}:host-context(.dark-mode) .close-btn:hover{background-color:#ffffff1a}.note-form{display:flex;flex-direction:column;flex:1;padding:1.5rem;overflow:hidden}.editor-section{display:flex;flex-direction:column;flex:1;min-height:250px;border:1px solid var(--border);border-radius:12px;overflow:hidden;transition:border-color .2s ease;background:var(--bg)}.editor-section:focus-within{border-color:var(--primary);box-shadow:0 0 0 3px #34c75926}::ng-deep .NgxEditor__MenuBar{background:var(--bg);border-bottom:1px solid var(--border);padding:.5rem;gap:.25rem;flex-wrap:wrap}::ng-deep .NgxEditor{flex:1;height:100%;min-height:300px;padding:1rem;border:none!important;background:var(--bg);color:var(--text);font-size:.95rem;line-height:1.6;overflow-y:auto}.error{color:#ef4444;font-size:.85rem;margin:.5rem 0 0}.action-bar{display:flex;justify-content:flex-end;padding-top:.75rem}::ng-deep .NgxEditor__Popup{position:absolute;top:calc(var(--ngx-editor-menubar-height) + 2px);box-shadow:var(--ngx-editor-popup-shadow);border-radius:var(--ngx-editor-popup-border-radius);background-color:var(--ngx-editor-popup-bg-color);z-index:100;min-width:101px;padding:8px;right:2px}.btn{min-width:140px;padding:10px 24px;border-radius:10px;font-weight:600;border:none;cursor:pointer;transition:all .2s ease}.btn-primary{background:var(--primary);color:#fff;box-shadow:0 4px 6px #34c7594d}.btn-primary:hover:not(:disabled){background:var(--primary-hover);transform:translateY(-1px)}.btn-primary:disabled{opacity:.6;cursor:not-allowed;box-shadow:none}@media (max-width: 640px){.note-container{height:100vh;border-radius:0}.note-form{padding:.75rem}.action-bar{justify-content:stretch}.btn{width:100%}}\n"] }]
373
- }], ctorParameters: () => [{ type: CustomDialogService }, { type: SharedService }, { type: EpubReaderService }, { type: HttpApiService }, { type: CustomDialogRef }, { type: i4.MessageService }], propDecorators: { onDragOver: [{
391
+ }], ctorParameters: () => [{ type: CustomDialogService }, { type: SharedService }, { type: EpubReaderService }, { type: HttpApiService }, { type: CustomDialogRef }, { type: NotificationService }], propDecorators: { onDragOver: [{
374
392
  type: HostListener,
375
393
  args: ['document:dragover', ['$event']]
376
394
  }], onDrop: [{
@@ -429,7 +447,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
429
447
  class EpubCommonPopupComponent {
430
448
  sanitizer;
431
449
  userApi;
432
- messageService;
450
+ notificationService;
433
451
  dialog;
434
452
  dialogRef;
435
453
  loaderService;
@@ -461,14 +479,14 @@ class EpubCommonPopupComponent {
461
479
  searchData = null;
462
480
  searchCharaSmall = false;
463
481
  onDestroy$ = new Subject();
464
- tabviewIndex = 1;
482
+ activeTab = 0;
465
483
  Definition = [];
466
484
  isLoading = false;
467
485
  isSearchDataAvailable = false;
468
- constructor(sanitizer, userApi, messageService, dialog, dialogRef, loaderService, epubService, sharedService) {
486
+ constructor(sanitizer, userApi, notificationService, dialog, dialogRef, loaderService, epubService, sharedService) {
469
487
  this.sanitizer = sanitizer;
470
488
  this.userApi = userApi;
471
- this.messageService = messageService;
489
+ this.notificationService = notificationService;
472
490
  this.dialog = dialog;
473
491
  this.dialogRef = dialogRef;
474
492
  this.loaderService = loaderService;
@@ -496,23 +514,17 @@ class EpubCommonPopupComponent {
496
514
  this.getDefinition();
497
515
  }
498
516
  }
499
- /*
500
- *@Desc : Handles tab view changes
501
- *@Author: Aboobacker
502
- */
503
- onTabChange(data) {
517
+ setActiveTab(index) {
518
+ this.activeTab = index;
504
519
  this.paginationData = {
505
520
  totalCount: 0,
506
521
  pageSize: 10,
507
522
  currentPage: 1,
508
523
  };
509
- if (data.index === 1) {
510
- //noteas
511
- this.tabviewIndex = data.index;
524
+ if (index === 1) {
512
525
  this.getNotes();
513
526
  }
514
527
  else {
515
- //highlights
516
528
  this.getHighlightNotes();
517
529
  }
518
530
  }
@@ -634,12 +646,7 @@ class EpubCommonPopupComponent {
634
646
  .subscribe({
635
647
  next: (res) => {
636
648
  this.loaderService.showHide(false);
637
- this.messageService.add({
638
- key: 'notifyToast',
639
- severity: 'success',
640
- summary: 'Success',
641
- detail: res.message,
642
- });
649
+ this.notificationService.success(res.message);
643
650
  if (this.template == 1) {
644
651
  this.dialog.closeAll();
645
652
  }
@@ -723,13 +730,13 @@ class EpubCommonPopupComponent {
723
730
  this.onDestroy$.next();
724
731
  this.onDestroy$.complete();
725
732
  }
726
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EpubCommonPopupComponent, deps: [{ token: i1$3.DomSanitizer }, { token: HttpApiService }, { token: i4.MessageService }, { token: CustomDialogService }, { token: CustomDialogRef }, { token: SharedService }, { token: EpubReaderService }, { token: SharedService }], target: i0.ɵɵFactoryTarget.Component });
727
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EpubCommonPopupComponent, isStandalone: false, selector: "app-epub-common-popup", ngImport: i0, template: "<!-- Template 1: Single Note View -->\n@if (dialogRef.data.template == 1) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">Note Details</h2>\n <div class=\"header-actions\">\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"popup-content content-padded\">\n <div class=\"inner-html-class text-lg text-primary mb-6\" [innerHTML]=\"htmlString\"></div>\n </div>\n\n <div class=\"dialog-footer\">\n <button class=\"btn btn-secondary\" (click)=\"close()\">\n {{ htmlStaticText.btnText.cancel }}\n </button>\n <button class=\"btn btn-primary\" (click)=\"editNote()\">\n {{ htmlStaticText.btnText.edit }}\n </button>\n <button class=\"btn btn-danger\" (click)=\"deleteAnnotations(1, this.singlenoteDetails.id)\">\n {{ htmlStaticText.btnText.remove }}\n </button>\n </div>\n</div>\n}\n\n<!-- Template 2: Highlights & Notes Tabs -->\n@if (dialogRef.data.template == 2) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M16.035 2.977l4.988 4.989-12.022 12.021H4v-4.988L16.035 2.977z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n Highlights & Notes\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content\">\n <p-tabView (onChange)=\"onTabChange($event)\">\n\n <!-- Highlights Tab -->\n <p-tabPanel header=\"Highlights\">\n <div *ngIf=\"isLoading; else highlightsContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n <ng-template #highlightsContent>\n <div *ngIf=\"!notesandHighlights?.length; else noteList\" class=\"empty-state\">\n {{ htmlStaticText.htmlText.nohighlightsavailable }}\n </div>\n\n <ng-template #noteList>\n <div *ngFor=\"let note of notesandHighlights\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <div class=\"w-2 h-8 rounded-full\" [style.background-color]=\"note.colorCode\"\n style=\"width: 4px; height: 32px; border-radius: 4px;\"></div>\n </div>\n\n <div class=\"row-content\" (click)=\"gotoLocation(note.cfiLocation)\">\n <div class=\"row-title line-clamp\">{{ note.annotatedNotes }}</div>\n <div class=\"row-meta\">\n <span>Page {{ note.pageNumber || 'N/A' }}</span>\n </div>\n </div>\n\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(2, note.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n </ng-template>\n </p-tabPanel>\n\n <!-- Notes Tab -->\n <p-tabPanel header=\"Notes\">\n <div *ngIf=\"isLoading; else notesContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n <ng-template #notesContent>\n <div *ngIf=\"!notes?.length; else notesList\" class=\"empty-state\">\n No notes available.\n </div>\n\n <ng-template #notesList>\n <div *ngFor=\"let item of notes\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div class=\"row-content\" (click)=\"openNote(item)\">\n <div class=\"row-title line-clamp\"\n [innerHTML]=\"item.annotatedNotes ? item.annotatedNotes : item.customNotes\"></div>\n </div>\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(1, item.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n </ng-template>\n </p-tabPanel>\n\n </p-tabView>\n </div>\n</div>\n}\n\n<!-- Template 3: Search -->\n@if (dialogRef.data.template == 3) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n Search\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <svg class=\"search-icon\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <input [(ngModel)]=\"searchKey\" (keyup.enter)=\"updateSearchKey()\" type=\"text\" placeholder=\"Search in book...\"\n class=\"search-input\" autofocus />\n <div class=\"input-actions-wrapper\">\n <button *ngIf=\"searchKey\" class=\"icon-btn-clear\" (click)=\"clearSearch()\" title=\"Clear search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button class=\"btn btn-primary btn-sm\" (click)=\"updateSearchKey()\">\n Search\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"popup-content\">\n <div *ngIf=\"searchCharaSmall\" class=\"info-banner\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n <span>{{ staticText.validationText.atleastThreeChara }}</span>\n </div>\n\n <div *ngIf=\"isSearchDataAvailable; else searchResults\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n\n <ng-template #searchResults>\n <div *ngIf=\"searchKey?.length && searchData && !searchData?.length\" class=\"empty-state\">\n <app-no-data-found></app-no-data-found>\n </div>\n\n <div class=\"search-results\">\n <div *ngFor=\"let item of searchData\" class=\"popup-row\" (click)=\"clickSearchItem(item.cfi)\">\n <div class=\"row-content\">\n <div class=\"row-title\" [innerHTML]=\"item.highlightedSentence\"></div>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n}\n\n<!-- Template 4: Bookmarks -->\n@if (dialogRef.data.template == 4) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n Bookmarks\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content\">\n <div *ngIf=\"isLoading; else bookmarkContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n\n <ng-template #bookmarkContent>\n <div *ngIf=\"!bookMarkList || bookMarkList.length === 0\" class=\"empty-state\">\n No bookmarks yet.\n </div>\n\n <div *ngIf=\"bookMarkList && bookMarkList.length > 0\">\n <div *ngFor=\"let bookmark of bookMarkList\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <!-- Filled Bookmark Icon for list -->\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"\n [style.color]=\"bookmark.colorCode || '#3b82f6'\">\n <path d=\"M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z\" />\n </svg>\n </div>\n\n <div class=\"row-content\" (click)=\"closePopup(bookmark.cfiLocation)\">\n <div class=\"row-title line-clamp\">{{ bookmark.annotatedNotes || 'Bookmark' }}</div>\n <div class=\"row-meta mt-2\">\n <div class=\"progress-container\">\n <div class=\"progress-fill\" [style.width.%]=\"bookmark.customNotes\"></div>\n </div>\n <span>{{ bookmark.customNotes }}%</span>\n </div>\n </div>\n\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(4, bookmark.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n}\n\n<!-- Template 5: Definitions -->\n@if (dialogRef.data.template == 5) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n Definition\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content content-padded\">\n <h3 class=\"text-xl font-bold text-primary mb-4 select-text\">\n \"{{ dialogRef.data.selectedText }}\"\n </h3>\n\n <div *ngIf=\"isLoading; else defsContent\">\n <app-skeleton-loader [count]=\"3\" type=\"text\"></app-skeleton-loader>\n </div>\n\n <ng-template #defsContent>\n <div *ngIf=\"Definition?.length > 0; else noDefs\">\n <div *ngFor=\"let entry of Definition\" class=\"definition-group\">\n <span class=\"pos-tag\">{{ entry.partOfSpeech }}</span>\n\n <div *ngFor=\"let def of entry.definitions\" class=\"def-item\">\n <p class=\"def-text\">{{ def.definition }}</p>\n <p *ngIf=\"def.example\" class=\"def-example\">\"{{ def.example }}\"</p>\n </div>\n </div>\n </div>\n\n <ng-template #noDefs>\n <div class=\"empty-state\">No definitions found.</div>\n </ng-template>\n </ng-template>\n </div>\n</div>\n}", styles: [":host{--bg-primary: #ffffff;--bg-secondary: #f8fafc;--text-primary: #0f172a;--text-secondary: #64748b;--border-soft: #e2e8f0;--accent: #3b82f6;--accent-hover: #2563eb;--danger: #ef4444;--danger-bg: #fef2f2}:host-context(.dark-mode){--bg-primary: rgb(32 33 32);--bg-secondary: rgb(42 43 42);--text-primary: #f8fafc;--text-secondary: #94a3b8;--border-soft: #334155;--accent: #60a5fa;--accent-hover: #3b82f6;--danger: #f87171;--danger-bg: #450a0a}.popup-container{display:flex;flex-direction:column;width:500px;height:600px;max-width:95vw;max-height:85vh;background:var(--bg-primary);color:var(--text-primary);border-radius:16px;overflow:hidden;box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}.popup-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;background:var(--bg-secondary);border-bottom:1px solid var(--border-soft)}.popup-title{font-size:1.15rem;font-weight:600;color:var(--text-primary);display:flex;align-items:center;gap:12px;margin:0}.popup-title svg{color:var(--text-secondary)}.close-btn{background:transparent;border:none;color:var(--text-secondary);padding:8px;border-radius:50%;cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center}.close-btn:hover{background-color:#e2e8f0;color:var(--text-primary)}.popup-content{flex:1;overflow-y:auto;position:relative}.content-padded{padding:24px}.search-container{padding:16px 24px;background:var(--bg-primary);border-bottom:1px solid var(--border-soft);position:sticky;top:0;z-index:10}.search-input-wrapper{position:relative;display:flex;align-items:center}.search-input-wrapper svg.search-icon{position:absolute;left:12px;color:var(--text-secondary);z-index:1}.search-input{width:100%;padding:12px 110px 12px 40px;border-radius:10px;border:1px solid var(--border-soft);font-size:.95rem;background:var(--bg-secondary);color:var(--text-primary);transition:all .2s}.search-input:focus{outline:none;background:var(--bg-primary);border-color:var(--accent);box-shadow:0 0 0 3px #3b82f61a}.input-actions-wrapper{position:absolute;right:8px;display:flex;align-items:center;gap:8px}.icon-btn-clear{background:transparent;border:none;color:var(--text-secondary);display:flex;align-items:center;justify-content:center;padding:4px;cursor:pointer;border-radius:4px}.icon-btn-clear:hover{background-color:var(--border-soft);color:var(--text-primary)}.info-banner{display:flex;align-items:center;gap:12px;margin:12px 24px;padding:12px 16px;background:var(--primary-lite);color:var(--primary);border-radius:8px;font-size:.85rem;font-weight:500;border:1px solid var(--border-color)}.info-banner svg{flex-shrink:0;opacity:.8}.btn-sm{padding:4px 12px;font-size:.85rem;height:32px}.popup-row{display:flex;align-items:flex-start;gap:16px;padding:16px 24px;border-bottom:1px solid var(--border-soft);cursor:pointer;transition:background-color .2s}.popup-row:hover{background-color:var(--bg-secondary)}.popup-row:hover .row-actions{opacity:1}.popup-row:last-child{border-bottom:none}.row-icon-container{flex-shrink:0;margin-top:2px;color:var(--text-secondary)}.row-content{flex:1;min-width:0}.row-title{font-size:.95rem;font-weight:500;color:var(--text-primary);line-height:1.5;margin-bottom:4px}.row-meta{font-size:.8rem;color:var(--text-secondary);display:flex;align-items:center;gap:8px}.row-actions{opacity:0;transition:opacity .2s;display:flex;align-items:center}.action-btn{background:transparent;border:none;color:var(--text-secondary);padding:6px;border-radius:6px;cursor:pointer;transition:all .2s}.action-btn:hover{background-color:var(--danger-bg);color:var(--danger)}.dialog-footer{padding:16px 24px;border-top:1px solid var(--border-soft);background:var(--bg-primary);display:flex;justify-content:flex-end;gap:12px}.btn{padding:8px 16px;border-radius:8px;font-size:.9rem;font-weight:500;cursor:pointer;transition:all .2s;border:1px solid transparent}.btn-secondary{background:var(--bg-secondary);color:var(--text-primary);border-color:var(--border-soft)}.btn-secondary:hover{background:#e2e8f0}.btn-primary{background:var(--accent);color:#fff}.btn-primary:hover{background:var(--accent-hover)}.btn-danger{background:var(--danger-bg);color:var(--danger)}.btn-danger:hover{background:#fee2e2}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-primary{color:var(--accent)}.mb-4{margin-bottom:1rem}.select-text{user-select:text;-webkit-user-select:text}.definition-group{margin-bottom:24px}.pos-tag{display:inline-block;font-size:.75rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--accent);background:#3b82f61a;padding:4px 8px;border-radius:6px;margin-bottom:12px}.def-item{padding-bottom:16px;margin-bottom:16px;border-bottom:1px dashed var(--border-soft)}.def-item:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.def-text{font-size:.95rem;color:var(--text-primary);line-height:1.5;margin-bottom:4px}.def-example{font-size:.85rem;color:var(--text-secondary);font-style:italic;padding-left:12px;border-left:2px solid var(--border-soft)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--text-secondary);text-align:center;font-style:italic}.progress-container{width:100px;height:6px;background:var(--bg-secondary);border-radius:3px;overflow:hidden}.progress-fill{height:100%;background:var(--accent);border-radius:3px}.line-clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}:host::ng-deep .p-tabview-nav{background:var(--bg-primary)!important;border-bottom:1px solid var(--border-soft)!important;justify-content:center;padding:0}:host::ng-deep .p-tabview-nav li .p-tabview-nav-link{background:transparent!important;border:none!important;color:var(--text-secondary)!important;font-weight:500;padding:16px 20px!important;box-shadow:none!important;font-size:.95rem}:host::ng-deep .p-tabview-nav li.p-highlight .p-tabview-nav-link{color:var(--accent)!important;border-bottom:2px solid var(--accent)!important}:host::ng-deep .p-tabview-panels{padding:0!important;background:transparent!important}:host::ng-deep .highlight-key{color:var(--danger)!important;font-weight:700;background-color:#ef444426;padding:0 4px;border-radius:3px}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: i8.TabView, selector: "p-tabView", inputs: ["style", "styleClass", "controlClose", "scrollable", "activeIndex", "selectOnFocus", "nextButtonAriaLabel", "prevButtonAriaLabel", "autoHideButtons", "tabindex"], outputs: ["onChange", "onClose", "activeIndexChange"] }, { kind: "component", type: i8.TabPanel, selector: "p-tabPanel", inputs: ["closable", "headerStyle", "headerStyleClass", "cache", "tooltip", "tooltipPosition", "tooltipPositionStyle", "tooltipStyleClass", "selected", "disabled", "header", "leftIcon", "rightIcon"] }, { kind: "component", type: NoDataFoundComponent, selector: "app-no-data-found", inputs: ["message"] }, { kind: "component", type: SkeletonLoaderComponent, selector: "app-skeleton-loader", inputs: ["count", "type"] }] });
733
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EpubCommonPopupComponent, deps: [{ token: i1$3.DomSanitizer }, { token: HttpApiService }, { token: NotificationService }, { token: CustomDialogService }, { token: CustomDialogRef }, { token: SharedService }, { token: EpubReaderService }, { token: SharedService }], target: i0.ɵɵFactoryTarget.Component });
734
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: EpubCommonPopupComponent, isStandalone: false, selector: "app-epub-common-popup", ngImport: i0, template: "<!-- Template 1: Single Note View -->\n@if (dialogRef.data.template == 1) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">Note Details</h2>\n <div class=\"header-actions\">\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"popup-content content-padded\">\n <div class=\"inner-html-class text-lg text-primary mb-6\" [innerHTML]=\"htmlString\"></div>\n </div>\n\n <div class=\"dialog-footer\">\n <button class=\"btn btn-secondary\" (click)=\"close()\">\n {{ htmlStaticText.btnText.cancel }}\n </button>\n <button class=\"btn btn-primary\" (click)=\"editNote()\">\n {{ htmlStaticText.btnText.edit }}\n </button>\n <button class=\"btn btn-danger\" (click)=\"deleteAnnotations(1, this.singlenoteDetails.id)\">\n {{ htmlStaticText.btnText.remove }}\n </button>\n </div>\n</div>\n}\n\n<!-- Template 2: Highlights & Notes Tabs -->\n@if (dialogRef.data.template == 2) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M16.035 2.977l4.988 4.989-12.022 12.021H4v-4.988L16.035 2.977z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n Highlights & Notes\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content\">\n <div class=\"custom-tabs\">\n <div class=\"tab-header\">\n <button class=\"tab-btn\" [class.active]=\"activeTab === 0\" (click)=\"setActiveTab(0)\">Highlights</button>\n <button class=\"tab-btn\" [class.active]=\"activeTab === 1\" (click)=\"setActiveTab(1)\">Notes</button>\n </div>\n\n <div class=\"tab-panels\">\n <!-- Highlights Tab -->\n <div class=\"tab-panel\" *ngIf=\"activeTab === 0\">\n <div *ngIf=\"isLoading; else highlightsContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n <ng-template #highlightsContent>\n <div *ngIf=\"!notesandHighlights?.length; else noteList\" class=\"empty-state\">\n {{ htmlStaticText.htmlText.nohighlightsavailable }}\n </div>\n\n <ng-template #noteList>\n <div *ngFor=\"let note of notesandHighlights\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <div class=\"w-2 h-8 rounded-full\" [style.background-color]=\"note.colorCode\"\n style=\"width: 4px; height: 32px; border-radius: 4px;\"></div>\n </div>\n\n <div class=\"row-content\" (click)=\"gotoLocation(note.cfiLocation)\">\n <div class=\"row-title line-clamp\">{{ note.annotatedNotes }}</div>\n <div class=\"row-meta\">\n <span>Page {{ note.pageNumber || 'N/A' }}</span>\n </div>\n </div>\n\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(2, note.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n </ng-template>\n </div>\n\n <!-- Notes Tab -->\n <div class=\"tab-panel\" *ngIf=\"activeTab === 1\">\n <div *ngIf=\"isLoading; else notesContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n <ng-template #notesContent>\n <div *ngIf=\"!notes?.length; else notesList\" class=\"empty-state\">\n No notes available.\n </div>\n\n <ng-template #notesList>\n <div *ngFor=\"let item of notes\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div class=\"row-content\" (click)=\"openNote(item)\">\n <div class=\"row-title line-clamp\"\n [innerHTML]=\"item.annotatedNotes ? item.annotatedNotes : item.customNotes\"></div>\n </div>\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(1, item.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n\n<!-- Template 3: Search -->\n@if (dialogRef.data.template == 3) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n Search\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <svg class=\"search-icon\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <input [(ngModel)]=\"searchKey\" (keyup.enter)=\"updateSearchKey()\" type=\"text\" placeholder=\"Search in book...\"\n class=\"search-input\" autofocus />\n <div class=\"input-actions-wrapper\">\n <button *ngIf=\"searchKey\" class=\"icon-btn-clear\" (click)=\"clearSearch()\" title=\"Clear search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button class=\"btn btn-primary btn-sm\" (click)=\"updateSearchKey()\">\n Search\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"popup-content\">\n <div *ngIf=\"searchCharaSmall\" class=\"info-banner\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n <span>{{ staticText.validationText.atleastThreeChara }}</span>\n </div>\n\n <div *ngIf=\"isSearchDataAvailable; else searchResults\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n\n <ng-template #searchResults>\n <div *ngIf=\"searchKey?.length && searchData && !searchData?.length\" class=\"empty-state\">\n <app-no-data-found></app-no-data-found>\n </div>\n\n <div class=\"search-results\">\n <div *ngFor=\"let item of searchData\" class=\"popup-row\" (click)=\"clickSearchItem(item.cfi)\">\n <div class=\"row-content\">\n <div class=\"row-title\" [innerHTML]=\"item.highlightedSentence\"></div>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n}\n\n<!-- Template 4: Bookmarks -->\n@if (dialogRef.data.template == 4) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n Bookmarks\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content\">\n <div *ngIf=\"isLoading; else bookmarkContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n\n <ng-template #bookmarkContent>\n <div *ngIf=\"!bookMarkList || bookMarkList.length === 0\" class=\"empty-state\">\n No bookmarks yet.\n </div>\n\n <div *ngIf=\"bookMarkList && bookMarkList.length > 0\">\n <div *ngFor=\"let bookmark of bookMarkList\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <!-- Filled Bookmark Icon for list -->\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"\n [style.color]=\"bookmark.colorCode || '#3b82f6'\">\n <path d=\"M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z\" />\n </svg>\n </div>\n\n <div class=\"row-content\" (click)=\"closePopup(bookmark.cfiLocation)\">\n <div class=\"row-title line-clamp\">{{ bookmark.annotatedNotes || 'Bookmark' }}</div>\n <div class=\"row-meta mt-2\">\n <div class=\"progress-container\">\n <div class=\"progress-fill\" [style.width.%]=\"bookmark.customNotes\"></div>\n </div>\n <span>{{ bookmark.customNotes }}%</span>\n </div>\n </div>\n\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(4, bookmark.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n}\n\n<!-- Template 5: Definitions -->\n@if (dialogRef.data.template == 5) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n Definition\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content content-padded\">\n <h3 class=\"text-xl font-bold text-primary mb-4 select-text\">\n \"{{ dialogRef.data.selectedText }}\"\n </h3>\n\n <div *ngIf=\"isLoading; else defsContent\">\n <app-skeleton-loader [count]=\"3\" type=\"text\"></app-skeleton-loader>\n </div>\n\n <ng-template #defsContent>\n <div *ngIf=\"Definition?.length > 0; else noDefs\">\n <div *ngFor=\"let entry of Definition\" class=\"definition-group\">\n <span class=\"pos-tag\">{{ entry.partOfSpeech }}</span>\n\n <div *ngFor=\"let def of entry.definitions\" class=\"def-item\">\n <p class=\"def-text\">{{ def.definition }}</p>\n <p *ngIf=\"def.example\" class=\"def-example\">\"{{ def.example }}\"</p>\n </div>\n </div>\n </div>\n\n <ng-template #noDefs>\n <div class=\"empty-state\">No definitions found.</div>\n </ng-template>\n </ng-template>\n </div>\n</div>\n}", styles: [":host{--bg-primary: #ffffff;--bg-secondary: #f8fafc;--text-primary: #0f172a;--text-secondary: #64748b;--border-soft: #e2e8f0;--accent: #3b82f6;--accent-hover: #2563eb;--danger: #ef4444;--danger-bg: #fef2f2}:host-context(.dark-mode){--bg-primary: rgb(32 33 32);--bg-secondary: rgb(42 43 42);--text-primary: #f8fafc;--text-secondary: #94a3b8;--border-soft: #334155;--accent: #60a5fa;--accent-hover: #3b82f6;--danger: #f87171;--danger-bg: #450a0a}.popup-container{display:flex;flex-direction:column;width:500px;height:600px;max-width:95vw;max-height:85vh;background:var(--bg-primary);color:var(--text-primary);border-radius:16px;overflow:hidden;box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}.popup-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;background:var(--bg-secondary);border-bottom:1px solid var(--border-soft)}.popup-title{font-size:1.15rem;font-weight:600;color:var(--text-primary);display:flex;align-items:center;gap:12px;margin:0}.popup-title svg{color:var(--text-secondary)}.close-btn{background:transparent;border:none;color:var(--text-secondary);padding:8px;border-radius:50%;cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center}.close-btn:hover{background-color:#e2e8f0;color:var(--text-primary)}.popup-content{flex:1;overflow-y:auto;position:relative}.content-padded{padding:24px}.search-container{padding:16px 24px;background:var(--bg-primary);border-bottom:1px solid var(--border-soft);position:sticky;top:0;z-index:10}.search-input-wrapper{position:relative;display:flex;align-items:center}.search-input-wrapper svg.search-icon{position:absolute;left:12px;color:var(--text-secondary);z-index:1}.search-input{width:100%;padding:12px 110px 12px 40px;border-radius:10px;border:1px solid var(--border-soft);font-size:.95rem;background:var(--bg-secondary);color:var(--text-primary);transition:all .2s}.search-input:focus{outline:none;background:var(--bg-primary);border-color:var(--accent);box-shadow:0 0 0 3px #3b82f61a}.input-actions-wrapper{position:absolute;right:8px;display:flex;align-items:center;gap:8px}.icon-btn-clear{background:transparent;border:none;color:var(--text-secondary);display:flex;align-items:center;justify-content:center;padding:4px;cursor:pointer;border-radius:4px}.icon-btn-clear:hover{background-color:var(--border-soft);color:var(--text-primary)}.info-banner{display:flex;align-items:center;gap:12px;margin:12px 24px;padding:12px 16px;background:var(--primary-lite);color:var(--primary);border-radius:8px;font-size:.85rem;font-weight:500;border:1px solid var(--border-color)}.info-banner svg{flex-shrink:0;opacity:.8}.btn-sm{padding:4px 12px;font-size:.85rem;height:32px}.popup-row{display:flex;align-items:flex-start;gap:16px;padding:16px 24px;border-bottom:1px solid var(--border-soft);cursor:pointer;transition:background-color .2s}.popup-row:hover{background-color:var(--bg-secondary)}.popup-row:hover .row-actions{opacity:1}.popup-row:last-child{border-bottom:none}.row-icon-container{flex-shrink:0;margin-top:2px;color:var(--text-secondary)}.row-content{flex:1;min-width:0}.row-title{font-size:.95rem;font-weight:500;color:var(--text-primary);line-height:1.5;margin-bottom:4px}.row-meta{font-size:.8rem;color:var(--text-secondary);display:flex;align-items:center;gap:8px}.row-actions{opacity:0;transition:opacity .2s;display:flex;align-items:center}.action-btn{background:transparent;border:none;color:var(--text-secondary);padding:6px;border-radius:6px;cursor:pointer;transition:all .2s}.action-btn:hover{background-color:var(--danger-bg);color:var(--danger)}.dialog-footer{padding:16px 24px;border-top:1px solid var(--border-soft);background:var(--bg-primary);display:flex;justify-content:flex-end;gap:12px}.btn{padding:8px 16px;border-radius:8px;font-size:.9rem;font-weight:500;cursor:pointer;transition:all .2s;border:1px solid transparent}.btn-secondary{background:var(--bg-secondary);color:var(--text-primary);border-color:var(--border-soft)}.btn-secondary:hover{background:#e2e8f0}.btn-primary{background:var(--accent);color:#fff}.btn-primary:hover{background:var(--accent-hover)}.btn-danger{background:var(--danger-bg);color:var(--danger)}.btn-danger:hover{background:#fee2e2}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-primary{color:var(--accent)}.mb-4{margin-bottom:1rem}.select-text{user-select:text;-webkit-user-select:text}.definition-group{margin-bottom:24px}.pos-tag{display:inline-block;font-size:.75rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--accent);background:#3b82f61a;padding:4px 8px;border-radius:6px;margin-bottom:12px}.def-item{padding-bottom:16px;margin-bottom:16px;border-bottom:1px dashed var(--border-soft)}.def-item:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.def-text{font-size:.95rem;color:var(--text-primary);line-height:1.5;margin-bottom:4px}.def-example{font-size:.85rem;color:var(--text-secondary);font-style:italic;padding-left:12px;border-left:2px solid var(--border-soft)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--text-secondary);text-align:center;font-style:italic}.progress-container{width:100px;height:6px;background:var(--bg-secondary);border-radius:3px;overflow:hidden}.progress-fill{height:100%;background:var(--accent);border-radius:3px}.line-clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.custom-tabs{display:flex;flex-direction:column;height:100%}.tab-header{display:flex;justify-content:center;gap:32px;background:var(--bg-primary);border-bottom:1px solid var(--border-soft);padding:0 24px}.tab-btn{background:transparent;border:none;padding:16px 4px;font-size:.95rem;font-weight:500;color:var(--text-secondary);cursor:pointer;position:relative;transition:all .2s}.tab-btn:after{content:\"\";position:absolute;bottom:-1px;left:0;width:100%;height:2px;background:transparent;transition:all .2s}.tab-btn:hover{color:var(--text-primary)}.tab-btn.active{color:var(--accent)}.tab-btn.active:after{background:var(--accent)}.tab-panels{flex:1;overflow-y:auto}.tab-panel{animation:fade-in .3s ease-out}@keyframes fade-in{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}:host::ng-deep .highlight-key{color:var(--danger)!important;font-weight:700;background-color:#ef444426;padding:0 4px;border-radius:3px}\n"], dependencies: [{ kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: NoDataFoundComponent, selector: "app-no-data-found", inputs: ["message"] }, { kind: "component", type: SkeletonLoaderComponent, selector: "app-skeleton-loader", inputs: ["count", "type"] }] });
728
735
  }
729
736
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EpubCommonPopupComponent, decorators: [{
730
737
  type: Component,
731
- args: [{ selector: 'app-epub-common-popup', standalone: false, template: "<!-- Template 1: Single Note View -->\n@if (dialogRef.data.template == 1) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">Note Details</h2>\n <div class=\"header-actions\">\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"popup-content content-padded\">\n <div class=\"inner-html-class text-lg text-primary mb-6\" [innerHTML]=\"htmlString\"></div>\n </div>\n\n <div class=\"dialog-footer\">\n <button class=\"btn btn-secondary\" (click)=\"close()\">\n {{ htmlStaticText.btnText.cancel }}\n </button>\n <button class=\"btn btn-primary\" (click)=\"editNote()\">\n {{ htmlStaticText.btnText.edit }}\n </button>\n <button class=\"btn btn-danger\" (click)=\"deleteAnnotations(1, this.singlenoteDetails.id)\">\n {{ htmlStaticText.btnText.remove }}\n </button>\n </div>\n</div>\n}\n\n<!-- Template 2: Highlights & Notes Tabs -->\n@if (dialogRef.data.template == 2) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M16.035 2.977l4.988 4.989-12.022 12.021H4v-4.988L16.035 2.977z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n Highlights & Notes\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content\">\n <p-tabView (onChange)=\"onTabChange($event)\">\n\n <!-- Highlights Tab -->\n <p-tabPanel header=\"Highlights\">\n <div *ngIf=\"isLoading; else highlightsContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n <ng-template #highlightsContent>\n <div *ngIf=\"!notesandHighlights?.length; else noteList\" class=\"empty-state\">\n {{ htmlStaticText.htmlText.nohighlightsavailable }}\n </div>\n\n <ng-template #noteList>\n <div *ngFor=\"let note of notesandHighlights\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <div class=\"w-2 h-8 rounded-full\" [style.background-color]=\"note.colorCode\"\n style=\"width: 4px; height: 32px; border-radius: 4px;\"></div>\n </div>\n\n <div class=\"row-content\" (click)=\"gotoLocation(note.cfiLocation)\">\n <div class=\"row-title line-clamp\">{{ note.annotatedNotes }}</div>\n <div class=\"row-meta\">\n <span>Page {{ note.pageNumber || 'N/A' }}</span>\n </div>\n </div>\n\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(2, note.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n </ng-template>\n </p-tabPanel>\n\n <!-- Notes Tab -->\n <p-tabPanel header=\"Notes\">\n <div *ngIf=\"isLoading; else notesContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n <ng-template #notesContent>\n <div *ngIf=\"!notes?.length; else notesList\" class=\"empty-state\">\n No notes available.\n </div>\n\n <ng-template #notesList>\n <div *ngFor=\"let item of notes\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div class=\"row-content\" (click)=\"openNote(item)\">\n <div class=\"row-title line-clamp\"\n [innerHTML]=\"item.annotatedNotes ? item.annotatedNotes : item.customNotes\"></div>\n </div>\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(1, item.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n </ng-template>\n </p-tabPanel>\n\n </p-tabView>\n </div>\n</div>\n}\n\n<!-- Template 3: Search -->\n@if (dialogRef.data.template == 3) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n Search\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <svg class=\"search-icon\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <input [(ngModel)]=\"searchKey\" (keyup.enter)=\"updateSearchKey()\" type=\"text\" placeholder=\"Search in book...\"\n class=\"search-input\" autofocus />\n <div class=\"input-actions-wrapper\">\n <button *ngIf=\"searchKey\" class=\"icon-btn-clear\" (click)=\"clearSearch()\" title=\"Clear search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button class=\"btn btn-primary btn-sm\" (click)=\"updateSearchKey()\">\n Search\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"popup-content\">\n <div *ngIf=\"searchCharaSmall\" class=\"info-banner\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n <span>{{ staticText.validationText.atleastThreeChara }}</span>\n </div>\n\n <div *ngIf=\"isSearchDataAvailable; else searchResults\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n\n <ng-template #searchResults>\n <div *ngIf=\"searchKey?.length && searchData && !searchData?.length\" class=\"empty-state\">\n <app-no-data-found></app-no-data-found>\n </div>\n\n <div class=\"search-results\">\n <div *ngFor=\"let item of searchData\" class=\"popup-row\" (click)=\"clickSearchItem(item.cfi)\">\n <div class=\"row-content\">\n <div class=\"row-title\" [innerHTML]=\"item.highlightedSentence\"></div>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n}\n\n<!-- Template 4: Bookmarks -->\n@if (dialogRef.data.template == 4) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n Bookmarks\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content\">\n <div *ngIf=\"isLoading; else bookmarkContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n\n <ng-template #bookmarkContent>\n <div *ngIf=\"!bookMarkList || bookMarkList.length === 0\" class=\"empty-state\">\n No bookmarks yet.\n </div>\n\n <div *ngIf=\"bookMarkList && bookMarkList.length > 0\">\n <div *ngFor=\"let bookmark of bookMarkList\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <!-- Filled Bookmark Icon for list -->\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"\n [style.color]=\"bookmark.colorCode || '#3b82f6'\">\n <path d=\"M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z\" />\n </svg>\n </div>\n\n <div class=\"row-content\" (click)=\"closePopup(bookmark.cfiLocation)\">\n <div class=\"row-title line-clamp\">{{ bookmark.annotatedNotes || 'Bookmark' }}</div>\n <div class=\"row-meta mt-2\">\n <div class=\"progress-container\">\n <div class=\"progress-fill\" [style.width.%]=\"bookmark.customNotes\"></div>\n </div>\n <span>{{ bookmark.customNotes }}%</span>\n </div>\n </div>\n\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(4, bookmark.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n}\n\n<!-- Template 5: Definitions -->\n@if (dialogRef.data.template == 5) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n Definition\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content content-padded\">\n <h3 class=\"text-xl font-bold text-primary mb-4 select-text\">\n \"{{ dialogRef.data.selectedText }}\"\n </h3>\n\n <div *ngIf=\"isLoading; else defsContent\">\n <app-skeleton-loader [count]=\"3\" type=\"text\"></app-skeleton-loader>\n </div>\n\n <ng-template #defsContent>\n <div *ngIf=\"Definition?.length > 0; else noDefs\">\n <div *ngFor=\"let entry of Definition\" class=\"definition-group\">\n <span class=\"pos-tag\">{{ entry.partOfSpeech }}</span>\n\n <div *ngFor=\"let def of entry.definitions\" class=\"def-item\">\n <p class=\"def-text\">{{ def.definition }}</p>\n <p *ngIf=\"def.example\" class=\"def-example\">\"{{ def.example }}\"</p>\n </div>\n </div>\n </div>\n\n <ng-template #noDefs>\n <div class=\"empty-state\">No definitions found.</div>\n </ng-template>\n </ng-template>\n </div>\n</div>\n}", styles: [":host{--bg-primary: #ffffff;--bg-secondary: #f8fafc;--text-primary: #0f172a;--text-secondary: #64748b;--border-soft: #e2e8f0;--accent: #3b82f6;--accent-hover: #2563eb;--danger: #ef4444;--danger-bg: #fef2f2}:host-context(.dark-mode){--bg-primary: rgb(32 33 32);--bg-secondary: rgb(42 43 42);--text-primary: #f8fafc;--text-secondary: #94a3b8;--border-soft: #334155;--accent: #60a5fa;--accent-hover: #3b82f6;--danger: #f87171;--danger-bg: #450a0a}.popup-container{display:flex;flex-direction:column;width:500px;height:600px;max-width:95vw;max-height:85vh;background:var(--bg-primary);color:var(--text-primary);border-radius:16px;overflow:hidden;box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}.popup-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;background:var(--bg-secondary);border-bottom:1px solid var(--border-soft)}.popup-title{font-size:1.15rem;font-weight:600;color:var(--text-primary);display:flex;align-items:center;gap:12px;margin:0}.popup-title svg{color:var(--text-secondary)}.close-btn{background:transparent;border:none;color:var(--text-secondary);padding:8px;border-radius:50%;cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center}.close-btn:hover{background-color:#e2e8f0;color:var(--text-primary)}.popup-content{flex:1;overflow-y:auto;position:relative}.content-padded{padding:24px}.search-container{padding:16px 24px;background:var(--bg-primary);border-bottom:1px solid var(--border-soft);position:sticky;top:0;z-index:10}.search-input-wrapper{position:relative;display:flex;align-items:center}.search-input-wrapper svg.search-icon{position:absolute;left:12px;color:var(--text-secondary);z-index:1}.search-input{width:100%;padding:12px 110px 12px 40px;border-radius:10px;border:1px solid var(--border-soft);font-size:.95rem;background:var(--bg-secondary);color:var(--text-primary);transition:all .2s}.search-input:focus{outline:none;background:var(--bg-primary);border-color:var(--accent);box-shadow:0 0 0 3px #3b82f61a}.input-actions-wrapper{position:absolute;right:8px;display:flex;align-items:center;gap:8px}.icon-btn-clear{background:transparent;border:none;color:var(--text-secondary);display:flex;align-items:center;justify-content:center;padding:4px;cursor:pointer;border-radius:4px}.icon-btn-clear:hover{background-color:var(--border-soft);color:var(--text-primary)}.info-banner{display:flex;align-items:center;gap:12px;margin:12px 24px;padding:12px 16px;background:var(--primary-lite);color:var(--primary);border-radius:8px;font-size:.85rem;font-weight:500;border:1px solid var(--border-color)}.info-banner svg{flex-shrink:0;opacity:.8}.btn-sm{padding:4px 12px;font-size:.85rem;height:32px}.popup-row{display:flex;align-items:flex-start;gap:16px;padding:16px 24px;border-bottom:1px solid var(--border-soft);cursor:pointer;transition:background-color .2s}.popup-row:hover{background-color:var(--bg-secondary)}.popup-row:hover .row-actions{opacity:1}.popup-row:last-child{border-bottom:none}.row-icon-container{flex-shrink:0;margin-top:2px;color:var(--text-secondary)}.row-content{flex:1;min-width:0}.row-title{font-size:.95rem;font-weight:500;color:var(--text-primary);line-height:1.5;margin-bottom:4px}.row-meta{font-size:.8rem;color:var(--text-secondary);display:flex;align-items:center;gap:8px}.row-actions{opacity:0;transition:opacity .2s;display:flex;align-items:center}.action-btn{background:transparent;border:none;color:var(--text-secondary);padding:6px;border-radius:6px;cursor:pointer;transition:all .2s}.action-btn:hover{background-color:var(--danger-bg);color:var(--danger)}.dialog-footer{padding:16px 24px;border-top:1px solid var(--border-soft);background:var(--bg-primary);display:flex;justify-content:flex-end;gap:12px}.btn{padding:8px 16px;border-radius:8px;font-size:.9rem;font-weight:500;cursor:pointer;transition:all .2s;border:1px solid transparent}.btn-secondary{background:var(--bg-secondary);color:var(--text-primary);border-color:var(--border-soft)}.btn-secondary:hover{background:#e2e8f0}.btn-primary{background:var(--accent);color:#fff}.btn-primary:hover{background:var(--accent-hover)}.btn-danger{background:var(--danger-bg);color:var(--danger)}.btn-danger:hover{background:#fee2e2}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-primary{color:var(--accent)}.mb-4{margin-bottom:1rem}.select-text{user-select:text;-webkit-user-select:text}.definition-group{margin-bottom:24px}.pos-tag{display:inline-block;font-size:.75rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--accent);background:#3b82f61a;padding:4px 8px;border-radius:6px;margin-bottom:12px}.def-item{padding-bottom:16px;margin-bottom:16px;border-bottom:1px dashed var(--border-soft)}.def-item:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.def-text{font-size:.95rem;color:var(--text-primary);line-height:1.5;margin-bottom:4px}.def-example{font-size:.85rem;color:var(--text-secondary);font-style:italic;padding-left:12px;border-left:2px solid var(--border-soft)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--text-secondary);text-align:center;font-style:italic}.progress-container{width:100px;height:6px;background:var(--bg-secondary);border-radius:3px;overflow:hidden}.progress-fill{height:100%;background:var(--accent);border-radius:3px}.line-clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}:host::ng-deep .p-tabview-nav{background:var(--bg-primary)!important;border-bottom:1px solid var(--border-soft)!important;justify-content:center;padding:0}:host::ng-deep .p-tabview-nav li .p-tabview-nav-link{background:transparent!important;border:none!important;color:var(--text-secondary)!important;font-weight:500;padding:16px 20px!important;box-shadow:none!important;font-size:.95rem}:host::ng-deep .p-tabview-nav li.p-highlight .p-tabview-nav-link{color:var(--accent)!important;border-bottom:2px solid var(--accent)!important}:host::ng-deep .p-tabview-panels{padding:0!important;background:transparent!important}:host::ng-deep .highlight-key{color:var(--danger)!important;font-weight:700;background-color:#ef444426;padding:0 4px;border-radius:3px}\n"] }]
732
- }], ctorParameters: () => [{ type: i1$3.DomSanitizer }, { type: HttpApiService }, { type: i4.MessageService }, { type: CustomDialogService }, { type: CustomDialogRef }, { type: SharedService }, { type: EpubReaderService }, { type: SharedService }] });
738
+ args: [{ selector: 'app-epub-common-popup', standalone: false, template: "<!-- Template 1: Single Note View -->\n@if (dialogRef.data.template == 1) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">Note Details</h2>\n <div class=\"header-actions\">\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n\n <div class=\"popup-content content-padded\">\n <div class=\"inner-html-class text-lg text-primary mb-6\" [innerHTML]=\"htmlString\"></div>\n </div>\n\n <div class=\"dialog-footer\">\n <button class=\"btn btn-secondary\" (click)=\"close()\">\n {{ htmlStaticText.btnText.cancel }}\n </button>\n <button class=\"btn btn-primary\" (click)=\"editNote()\">\n {{ htmlStaticText.btnText.edit }}\n </button>\n <button class=\"btn btn-danger\" (click)=\"deleteAnnotations(1, this.singlenoteDetails.id)\">\n {{ htmlStaticText.btnText.remove }}\n </button>\n </div>\n</div>\n}\n\n<!-- Template 2: Highlights & Notes Tabs -->\n@if (dialogRef.data.template == 2) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M16.035 2.977l4.988 4.989-12.022 12.021H4v-4.988L16.035 2.977z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n Highlights & Notes\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content\">\n <div class=\"custom-tabs\">\n <div class=\"tab-header\">\n <button class=\"tab-btn\" [class.active]=\"activeTab === 0\" (click)=\"setActiveTab(0)\">Highlights</button>\n <button class=\"tab-btn\" [class.active]=\"activeTab === 1\" (click)=\"setActiveTab(1)\">Notes</button>\n </div>\n\n <div class=\"tab-panels\">\n <!-- Highlights Tab -->\n <div class=\"tab-panel\" *ngIf=\"activeTab === 0\">\n <div *ngIf=\"isLoading; else highlightsContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n <ng-template #highlightsContent>\n <div *ngIf=\"!notesandHighlights?.length; else noteList\" class=\"empty-state\">\n {{ htmlStaticText.htmlText.nohighlightsavailable }}\n </div>\n\n <ng-template #noteList>\n <div *ngFor=\"let note of notesandHighlights\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <div class=\"w-2 h-8 rounded-full\" [style.background-color]=\"note.colorCode\"\n style=\"width: 4px; height: 32px; border-radius: 4px;\"></div>\n </div>\n\n <div class=\"row-content\" (click)=\"gotoLocation(note.cfiLocation)\">\n <div class=\"row-title line-clamp\">{{ note.annotatedNotes }}</div>\n <div class=\"row-meta\">\n <span>Page {{ note.pageNumber || 'N/A' }}</span>\n </div>\n </div>\n\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(2, note.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n </ng-template>\n </div>\n\n <!-- Notes Tab -->\n <div class=\"tab-panel\" *ngIf=\"activeTab === 1\">\n <div *ngIf=\"isLoading; else notesContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n <ng-template #notesContent>\n <div *ngIf=\"!notes?.length; else notesList\" class=\"empty-state\">\n No notes available.\n </div>\n\n <ng-template #notesList>\n <div *ngFor=\"let item of notes\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M11 4H4a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2v-7\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n <path d=\"M18.5 2.5a2.121 2.121 0 013 3L12 15l-4 1 1-4 9.5-9.5z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </div>\n <div class=\"row-content\" (click)=\"openNote(item)\">\n <div class=\"row-title line-clamp\"\n [innerHTML]=\"item.annotatedNotes ? item.annotatedNotes : item.customNotes\"></div>\n </div>\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(1, item.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </ng-template>\n </ng-template>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n\n<!-- Template 3: Search -->\n@if (dialogRef.data.template == 3) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n Search\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"search-container\">\n <div class=\"search-input-wrapper\">\n <svg class=\"search-icon\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\"\n stroke-width=\"2\">\n <path d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n <input [(ngModel)]=\"searchKey\" (keyup.enter)=\"updateSearchKey()\" type=\"text\" placeholder=\"Search in book...\"\n class=\"search-input\" autofocus />\n <div class=\"input-actions-wrapper\">\n <button *ngIf=\"searchKey\" class=\"icon-btn-clear\" (click)=\"clearSearch()\" title=\"Clear search\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n <button class=\"btn btn-primary btn-sm\" (click)=\"updateSearchKey()\">\n Search\n </button>\n </div>\n </div>\n </div>\n\n <div class=\"popup-content\">\n <div *ngIf=\"searchCharaSmall\" class=\"info-banner\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <circle cx=\"12\" cy=\"12\" r=\"10\" />\n <line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"12\" />\n <line x1=\"12\" y1=\"8\" x2=\"12.01\" y2=\"8\" />\n </svg>\n <span>{{ staticText.validationText.atleastThreeChara }}</span>\n </div>\n\n <div *ngIf=\"isSearchDataAvailable; else searchResults\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n\n <ng-template #searchResults>\n <div *ngIf=\"searchKey?.length && searchData && !searchData?.length\" class=\"empty-state\">\n <app-no-data-found></app-no-data-found>\n </div>\n\n <div class=\"search-results\">\n <div *ngFor=\"let item of searchData\" class=\"popup-row\" (click)=\"clickSearchItem(item.cfi)\">\n <div class=\"row-content\">\n <div class=\"row-title\" [innerHTML]=\"item.highlightedSentence\"></div>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n}\n\n<!-- Template 4: Bookmarks -->\n@if (dialogRef.data.template == 4) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n Bookmarks\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content\">\n <div *ngIf=\"isLoading; else bookmarkContent\">\n <app-skeleton-loader [count]=\"4\" type=\"list\"></app-skeleton-loader>\n </div>\n\n <ng-template #bookmarkContent>\n <div *ngIf=\"!bookMarkList || bookMarkList.length === 0\" class=\"empty-state\">\n No bookmarks yet.\n </div>\n\n <div *ngIf=\"bookMarkList && bookMarkList.length > 0\">\n <div *ngFor=\"let bookmark of bookMarkList\" class=\"popup-row\">\n <div class=\"row-icon-container\">\n <!-- Filled Bookmark Icon for list -->\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"currentColor\"\n [style.color]=\"bookmark.colorCode || '#3b82f6'\">\n <path d=\"M5 5a2 2 0 012-2h10a2 2 0 012 2v16l-7-3.5L5 21V5z\" />\n </svg>\n </div>\n\n <div class=\"row-content\" (click)=\"closePopup(bookmark.cfiLocation)\">\n <div class=\"row-title line-clamp\">{{ bookmark.annotatedNotes || 'Bookmark' }}</div>\n <div class=\"row-meta mt-2\">\n <div class=\"progress-container\">\n <div class=\"progress-fill\" [style.width.%]=\"bookmark.customNotes\"></div>\n </div>\n <span>{{ bookmark.customNotes }}%</span>\n </div>\n </div>\n\n <div class=\"row-actions\">\n <button class=\"action-btn\" (click)=\"deleteAnnotations(4, bookmark.id)\" title=\"Remove\">\n <svg width=\"18\" height=\"18\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path\n d=\"M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16\"\n stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n </ng-template>\n </div>\n</div>\n}\n\n<!-- Template 5: Definitions -->\n@if (dialogRef.data.template == 5) {\n<div class=\"popup-container\">\n <div class=\"popup-header\">\n <h2 class=\"popup-title\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M4 19.5A2.5 2.5 0 016.5 17H20\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n <path d=\"M6.5 2H20v20H6.5A2.5 2.5 0 014 19.5v-15A2.5 2.5 0 016.5 2z\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n Definition\n </h2>\n <button class=\"close-btn\" (click)=\"close()\">\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n\n <div class=\"popup-content content-padded\">\n <h3 class=\"text-xl font-bold text-primary mb-4 select-text\">\n \"{{ dialogRef.data.selectedText }}\"\n </h3>\n\n <div *ngIf=\"isLoading; else defsContent\">\n <app-skeleton-loader [count]=\"3\" type=\"text\"></app-skeleton-loader>\n </div>\n\n <ng-template #defsContent>\n <div *ngIf=\"Definition?.length > 0; else noDefs\">\n <div *ngFor=\"let entry of Definition\" class=\"definition-group\">\n <span class=\"pos-tag\">{{ entry.partOfSpeech }}</span>\n\n <div *ngFor=\"let def of entry.definitions\" class=\"def-item\">\n <p class=\"def-text\">{{ def.definition }}</p>\n <p *ngIf=\"def.example\" class=\"def-example\">\"{{ def.example }}\"</p>\n </div>\n </div>\n </div>\n\n <ng-template #noDefs>\n <div class=\"empty-state\">No definitions found.</div>\n </ng-template>\n </ng-template>\n </div>\n</div>\n}", styles: [":host{--bg-primary: #ffffff;--bg-secondary: #f8fafc;--text-primary: #0f172a;--text-secondary: #64748b;--border-soft: #e2e8f0;--accent: #3b82f6;--accent-hover: #2563eb;--danger: #ef4444;--danger-bg: #fef2f2}:host-context(.dark-mode){--bg-primary: rgb(32 33 32);--bg-secondary: rgb(42 43 42);--text-primary: #f8fafc;--text-secondary: #94a3b8;--border-soft: #334155;--accent: #60a5fa;--accent-hover: #3b82f6;--danger: #f87171;--danger-bg: #450a0a}.popup-container{display:flex;flex-direction:column;width:500px;height:600px;max-width:95vw;max-height:85vh;background:var(--bg-primary);color:var(--text-primary);border-radius:16px;overflow:hidden;box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}.popup-header{display:flex;justify-content:space-between;align-items:center;padding:20px 24px;background:var(--bg-secondary);border-bottom:1px solid var(--border-soft)}.popup-title{font-size:1.15rem;font-weight:600;color:var(--text-primary);display:flex;align-items:center;gap:12px;margin:0}.popup-title svg{color:var(--text-secondary)}.close-btn{background:transparent;border:none;color:var(--text-secondary);padding:8px;border-radius:50%;cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center}.close-btn:hover{background-color:#e2e8f0;color:var(--text-primary)}.popup-content{flex:1;overflow-y:auto;position:relative}.content-padded{padding:24px}.search-container{padding:16px 24px;background:var(--bg-primary);border-bottom:1px solid var(--border-soft);position:sticky;top:0;z-index:10}.search-input-wrapper{position:relative;display:flex;align-items:center}.search-input-wrapper svg.search-icon{position:absolute;left:12px;color:var(--text-secondary);z-index:1}.search-input{width:100%;padding:12px 110px 12px 40px;border-radius:10px;border:1px solid var(--border-soft);font-size:.95rem;background:var(--bg-secondary);color:var(--text-primary);transition:all .2s}.search-input:focus{outline:none;background:var(--bg-primary);border-color:var(--accent);box-shadow:0 0 0 3px #3b82f61a}.input-actions-wrapper{position:absolute;right:8px;display:flex;align-items:center;gap:8px}.icon-btn-clear{background:transparent;border:none;color:var(--text-secondary);display:flex;align-items:center;justify-content:center;padding:4px;cursor:pointer;border-radius:4px}.icon-btn-clear:hover{background-color:var(--border-soft);color:var(--text-primary)}.info-banner{display:flex;align-items:center;gap:12px;margin:12px 24px;padding:12px 16px;background:var(--primary-lite);color:var(--primary);border-radius:8px;font-size:.85rem;font-weight:500;border:1px solid var(--border-color)}.info-banner svg{flex-shrink:0;opacity:.8}.btn-sm{padding:4px 12px;font-size:.85rem;height:32px}.popup-row{display:flex;align-items:flex-start;gap:16px;padding:16px 24px;border-bottom:1px solid var(--border-soft);cursor:pointer;transition:background-color .2s}.popup-row:hover{background-color:var(--bg-secondary)}.popup-row:hover .row-actions{opacity:1}.popup-row:last-child{border-bottom:none}.row-icon-container{flex-shrink:0;margin-top:2px;color:var(--text-secondary)}.row-content{flex:1;min-width:0}.row-title{font-size:.95rem;font-weight:500;color:var(--text-primary);line-height:1.5;margin-bottom:4px}.row-meta{font-size:.8rem;color:var(--text-secondary);display:flex;align-items:center;gap:8px}.row-actions{opacity:0;transition:opacity .2s;display:flex;align-items:center}.action-btn{background:transparent;border:none;color:var(--text-secondary);padding:6px;border-radius:6px;cursor:pointer;transition:all .2s}.action-btn:hover{background-color:var(--danger-bg);color:var(--danger)}.dialog-footer{padding:16px 24px;border-top:1px solid var(--border-soft);background:var(--bg-primary);display:flex;justify-content:flex-end;gap:12px}.btn{padding:8px 16px;border-radius:8px;font-size:.9rem;font-weight:500;cursor:pointer;transition:all .2s;border:1px solid transparent}.btn-secondary{background:var(--bg-secondary);color:var(--text-primary);border-color:var(--border-soft)}.btn-secondary:hover{background:#e2e8f0}.btn-primary{background:var(--accent);color:#fff}.btn-primary:hover{background:var(--accent-hover)}.btn-danger{background:var(--danger-bg);color:var(--danger)}.btn-danger:hover{background:#fee2e2}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-bold{font-weight:700}.text-primary{color:var(--accent)}.mb-4{margin-bottom:1rem}.select-text{user-select:text;-webkit-user-select:text}.definition-group{margin-bottom:24px}.pos-tag{display:inline-block;font-size:.75rem;font-weight:700;letter-spacing:.05em;text-transform:uppercase;color:var(--accent);background:#3b82f61a;padding:4px 8px;border-radius:6px;margin-bottom:12px}.def-item{padding-bottom:16px;margin-bottom:16px;border-bottom:1px dashed var(--border-soft)}.def-item:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.def-text{font-size:.95rem;color:var(--text-primary);line-height:1.5;margin-bottom:4px}.def-example{font-size:.85rem;color:var(--text-secondary);font-style:italic;padding-left:12px;border-left:2px solid var(--border-soft)}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;color:var(--text-secondary);text-align:center;font-style:italic}.progress-container{width:100px;height:6px;background:var(--bg-secondary);border-radius:3px;overflow:hidden}.progress-fill{height:100%;background:var(--accent);border-radius:3px}.line-clamp{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.custom-tabs{display:flex;flex-direction:column;height:100%}.tab-header{display:flex;justify-content:center;gap:32px;background:var(--bg-primary);border-bottom:1px solid var(--border-soft);padding:0 24px}.tab-btn{background:transparent;border:none;padding:16px 4px;font-size:.95rem;font-weight:500;color:var(--text-secondary);cursor:pointer;position:relative;transition:all .2s}.tab-btn:after{content:\"\";position:absolute;bottom:-1px;left:0;width:100%;height:2px;background:transparent;transition:all .2s}.tab-btn:hover{color:var(--text-primary)}.tab-btn.active{color:var(--accent)}.tab-btn.active:after{background:var(--accent)}.tab-panels{flex:1;overflow-y:auto}.tab-panel{animation:fade-in .3s ease-out}@keyframes fade-in{0%{opacity:0;transform:translateY(5px)}to{opacity:1;transform:translateY(0)}}:host::ng-deep .highlight-key{color:var(--danger)!important;font-weight:700;background-color:#ef444426;padding:0 4px;border-radius:3px}\n"] }]
739
+ }], ctorParameters: () => [{ type: i1$3.DomSanitizer }, { type: HttpApiService }, { type: NotificationService }, { type: CustomDialogService }, { type: CustomDialogRef }, { type: SharedService }, { type: EpubReaderService }, { type: SharedService }] });
733
740
 
734
741
  class ConfirmPopupComponent {
735
742
  ref;
@@ -767,6 +774,85 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
767
774
  `, styles: [".confirm-popup-container{padding:24px;background:#fff;border-radius:8px;min-width:300px;box-shadow:0 4px 6px -1px #0000001a}.title{margin:0 0 12px;font-size:1.125rem;font-weight:600;color:#111827}.message{margin:0 0 24px;color:#4b5563;font-size:.95rem}.actions{display:flex;justify-content:flex-end;gap:12px}button{padding:8px 16px;border-radius:6px;font-weight:500;cursor:pointer;transition:all .2s;border:none}.btn-cancel{background:#f3f4f6;color:#374151}.btn-cancel:hover{background:#e5e7eb}.btn-confirm{background:#dc2626;color:#fff}.btn-confirm:hover{background:#b91c1c}\n"] }]
768
775
  }], ctorParameters: () => [{ type: CustomDialogRef }] });
769
776
 
777
+ class NotificationToastComponent {
778
+ notificationService;
779
+ toasts = [];
780
+ subscription;
781
+ constructor(notificationService) {
782
+ this.notificationService = notificationService;
783
+ }
784
+ ngOnInit() {
785
+ this.subscription = this.notificationService.notifications$.subscribe(toast => {
786
+ this.toasts.push(toast);
787
+ if (toast.duration !== 0) {
788
+ setTimeout(() => {
789
+ this.removeToast(toast.id);
790
+ }, toast.duration || 3000);
791
+ }
792
+ });
793
+ }
794
+ removeToast(id) {
795
+ this.toasts = this.toasts.filter(t => t.id !== id);
796
+ }
797
+ ngOnDestroy() {
798
+ if (this.subscription) {
799
+ this.subscription.unsubscribe();
800
+ }
801
+ }
802
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: NotificationToastComponent, deps: [{ token: NotificationService }], target: i0.ɵɵFactoryTarget.Component });
803
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.2.17", type: NotificationToastComponent, isStandalone: true, selector: "epub-notification-toast", ngImport: i0, template: `
804
+ <div class="notification-container">
805
+ <div *ngFor="let toast of toasts"
806
+ class="toast-item"
807
+ [class]="toast.type"
808
+ (click)="removeToast(toast.id)">
809
+ <div class="toast-icon">
810
+ <ng-container [ngSwitch]="toast.type">
811
+ <svg *ngSwitchCase="'success'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6L9 17L4 12"></path></svg>
812
+ <svg *ngSwitchCase="'error'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>
813
+ <svg *ngSwitchCase="'warning'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
814
+ <svg *ngSwitchCase="'info'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
815
+ </ng-container>
816
+ </div>
817
+ <div class="toast-content">
818
+ <div class="toast-title" *ngIf="toast.title">{{ toast.title }}</div>
819
+ <div class="toast-message">{{ toast.message }}</div>
820
+ </div>
821
+ <button class="toast-close">
822
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6L18 18"></path></svg>
823
+ </button>
824
+ </div>
825
+ </div>
826
+ `, isInline: true, styles: [".notification-container{position:fixed;top:24px;right:24px;z-index:9999;display:flex;flex-direction:column;gap:12px;pointer-events:none}.toast-item{pointer-events:auto;display:flex;align-items:flex-start;gap:12px;min-width:300px;max-width:400px;padding:16px;background:#fff;border-radius:12px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;border:1px solid rgba(0,0,0,.05);cursor:pointer;animation:toast-in .3s cubic-bezier(.68,-.55,.265,1.55);transition:all .2s ease}.toast-item:hover{transform:translateY(-2px);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}@keyframes toast-in{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}.toast-icon{flex-shrink:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center}.toast-icon svg{width:20px;height:20px}.toast-content{flex-grow:1}.toast-title{font-weight:600;font-size:14px;margin-bottom:2px;color:#1f2937}.toast-message{font-size:14px;color:#4b5563;line-height:1.5}.toast-close{flex-shrink:0;background:transparent;border:none;padding:4px;color:#9ca3af;cursor:pointer;opacity:.6;transition:opacity .2s}.toast-close:hover{opacity:1}.success{border-left:4px solid #10b981}.success .toast-icon{color:#10b981}.error{border-left:4px solid #ef4444}.error .toast-icon{color:#ef4444}.warning{border-left:4px solid #f59e0b}.warning .toast-icon{color:#f59e0b}.info{border-left:4px solid #3b82f6}.info .toast-icon{color:#3b82f6}:host-context(.dark-mode) .toast-item{background:#1f2937;border-color:#374151}:host-context(.dark-mode) .toast-title{color:#f9fafb}:host-context(.dark-mode) .toast-message{color:#d1d5db}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1$2.NgSwitch, selector: "[ngSwitch]", inputs: ["ngSwitch"] }, { kind: "directive", type: i1$2.NgSwitchCase, selector: "[ngSwitchCase]", inputs: ["ngSwitchCase"] }] });
827
+ }
828
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: NotificationToastComponent, decorators: [{
829
+ type: Component,
830
+ args: [{ selector: 'epub-notification-toast', standalone: true, imports: [CommonModule], template: `
831
+ <div class="notification-container">
832
+ <div *ngFor="let toast of toasts"
833
+ class="toast-item"
834
+ [class]="toast.type"
835
+ (click)="removeToast(toast.id)">
836
+ <div class="toast-icon">
837
+ <ng-container [ngSwitch]="toast.type">
838
+ <svg *ngSwitchCase="'success'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20 6L9 17L4 12"></path></svg>
839
+ <svg *ngSwitchCase="'error'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="15" y1="9" x2="9" y2="15"></line><line x1="9" y1="9" x2="15" y2="15"></line></svg>
840
+ <svg *ngSwitchCase="'warning'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10.29 3.86L1.82 18a2 2 0 001.71 3h16.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z"></path><line x1="12" y1="9" x2="12" y2="13"></line><line x1="12" y1="17" x2="12.01" y2="17"></line></svg>
841
+ <svg *ngSwitchCase="'info'" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="16" x2="12" y2="12"></line><line x1="12" y1="8" x2="12.01" y2="8"></line></svg>
842
+ </ng-container>
843
+ </div>
844
+ <div class="toast-content">
845
+ <div class="toast-title" *ngIf="toast.title">{{ toast.title }}</div>
846
+ <div class="toast-message">{{ toast.message }}</div>
847
+ </div>
848
+ <button class="toast-close">
849
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6L18 18"></path></svg>
850
+ </button>
851
+ </div>
852
+ </div>
853
+ `, styles: [".notification-container{position:fixed;top:24px;right:24px;z-index:9999;display:flex;flex-direction:column;gap:12px;pointer-events:none}.toast-item{pointer-events:auto;display:flex;align-items:flex-start;gap:12px;min-width:300px;max-width:400px;padding:16px;background:#fff;border-radius:12px;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -2px #0000000d;border:1px solid rgba(0,0,0,.05);cursor:pointer;animation:toast-in .3s cubic-bezier(.68,-.55,.265,1.55);transition:all .2s ease}.toast-item:hover{transform:translateY(-2px);box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a}@keyframes toast-in{0%{transform:translate(100%);opacity:0}to{transform:translate(0);opacity:1}}.toast-icon{flex-shrink:0;width:24px;height:24px;display:flex;align-items:center;justify-content:center}.toast-icon svg{width:20px;height:20px}.toast-content{flex-grow:1}.toast-title{font-weight:600;font-size:14px;margin-bottom:2px;color:#1f2937}.toast-message{font-size:14px;color:#4b5563;line-height:1.5}.toast-close{flex-shrink:0;background:transparent;border:none;padding:4px;color:#9ca3af;cursor:pointer;opacity:.6;transition:opacity .2s}.toast-close:hover{opacity:1}.success{border-left:4px solid #10b981}.success .toast-icon{color:#10b981}.error{border-left:4px solid #ef4444}.error .toast-icon{color:#ef4444}.warning{border-left:4px solid #f59e0b}.warning .toast-icon{color:#f59e0b}.info{border-left:4px solid #3b82f6}.info .toast-icon{color:#3b82f6}:host-context(.dark-mode) .toast-item{background:#1f2937;border-color:#374151}:host-context(.dark-mode) .toast-title{color:#f9fafb}:host-context(.dark-mode) .toast-message{color:#d1d5db}\n"] }]
854
+ }], ctorParameters: () => [{ type: NotificationService }] });
855
+
770
856
  class ChapterlistComponent {
771
857
  chapterData = [];
772
858
  chapterClick = new EventEmitter();
@@ -808,7 +894,7 @@ class ReaderMainComponent {
808
894
  cdr;
809
895
  route;
810
896
  dialog;
811
- messageService;
897
+ notificationService;
812
898
  location;
813
899
  platformId;
814
900
  router;
@@ -888,7 +974,7 @@ class ReaderMainComponent {
888
974
  event.stopPropagation();
889
975
  }
890
976
  }
891
- constructor(ngZone, httpService, sharedService, epubService, cdr, route, dialog, messageService, location, platformId, router, overlay) {
977
+ constructor(ngZone, httpService, sharedService, epubService, cdr, route, dialog, notificationService, location, platformId, router, overlay) {
892
978
  this.ngZone = ngZone;
893
979
  this.httpService = httpService;
894
980
  this.sharedService = sharedService;
@@ -896,7 +982,7 @@ class ReaderMainComponent {
896
982
  this.cdr = cdr;
897
983
  this.route = route;
898
984
  this.dialog = dialog;
899
- this.messageService = messageService;
985
+ this.notificationService = notificationService;
900
986
  this.location = location;
901
987
  this.platformId = platformId;
902
988
  this.router = router;
@@ -1052,12 +1138,7 @@ class ReaderMainComponent {
1052
1138
  handleBookLoadError(message) {
1053
1139
  this.showBookPageLoader = false;
1054
1140
  this.showDwndLoader = false;
1055
- this.messageService.add({
1056
- key: 'notifyToast',
1057
- severity: 'error',
1058
- summary: 'Error',
1059
- detail: message,
1060
- });
1141
+ this.notificationService.error(message);
1061
1142
  this.ngZone.run(() => {
1062
1143
  this.sharedService.showHide(false);
1063
1144
  });
@@ -1886,12 +1967,7 @@ class ReaderMainComponent {
1886
1967
  .pipe(takeUntil(this.onDestroy$))
1887
1968
  .subscribe({
1888
1969
  next: (res) => {
1889
- this.messageService.add({
1890
- key: 'notifyToast',
1891
- severity: 'success', // Use 'warn' for orange color
1892
- summary: 'Success',
1893
- detail: res.message,
1894
- });
1970
+ this.notificationService.success(res.message);
1895
1971
  },
1896
1972
  error: () => {
1897
1973
  this.sharedService.showHide(false);
@@ -2100,13 +2176,13 @@ class ReaderMainComponent {
2100
2176
  this.onDestroy$.next();
2101
2177
  this.onDestroy$.complete();
2102
2178
  }
2103
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ReaderMainComponent, deps: [{ token: i0.NgZone }, { token: HttpApiService }, { token: SharedService }, { token: EpubReaderService }, { token: i0.ChangeDetectorRef }, { token: i3.ActivatedRoute }, { token: CustomDialogService }, { token: i4.MessageService }, { token: i1$2.Location }, { token: PLATFORM_ID }, { token: i3.Router }, { token: i1$1.Overlay }], target: i0.ɵɵFactoryTarget.Component });
2104
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: ReaderMainComponent, isStandalone: false, selector: "epub-flow", inputs: { epubUrl: "epubUrl", epubBlob: "epubBlob", coverPage: "coverPage", enableDarkMode: "enableDarkMode", enableSearch: "enableSearch", enableHighlights: "enableHighlights", enableBookmarks: "enableBookmarks", enableChapterList: "enableChapterList", enableTextSelection: "enableTextSelection", enableFontSize: "enableFontSize", enableNotes: "enableNotes" }, outputs: { underlineRemoveRequest: "underlineRemoveRequest" }, host: { listeners: { "document:keyup": "handleKeyUp($event)", "document:keydown": "onKeyDown($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div id=\"reader-container\" [hidden]=\"showBookPageLoader || showDwndLoader\">\n <div id=\"reader-content\" style=\"overflow: hidden;\">\n <div id=\"reader\"></div>\n </div>\n\n <div id=\"reader-footer\">\n <div class=\"footer-container\">\n <!-- Left: Previous Button -->\n <button class=\"nav-btn prev-btn\" (click)=\"prevClick()\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <!-- Center: Progress Bar -->\n <div class=\"progress-section\">\n <div class=\"progress-label\">Read Progress</div>\n <div class=\"progress-bar-container\">\n <div class=\"progress-track\">\n <div class=\"progress-fill\" [style.width.%]=\"readPercentage.roudedOff\"></div>\n </div>\n <input type=\"range\" class=\"progress-slider\" min=\"0\" max=\"100\" [value]=\"readPercentage.roudedOff\"\n (input)=\"onProgressChange($event)\" />\n <span class=\"progress-text\">{{ readPercentage.roudedOff }}%</span>\n </div>\n </div>\n\n <!-- Right: Menu Toggle & Next Button -->\n <div class=\"right-controls\">\n <!-- Menu Toggle Button (Green) -->\n <div class=\"menu-container relative\">\n <!-- The Menu Popup -->\n @if (isMenuOpen) {\n <div class=\"menu-popup fade-in\">\n <ul class=\"menu-list\">\n <!-- Dark Mode -->\n <!-- Dark Mode -->\n @if (enableDarkMode) {\n <li (click)=\"toggleDarkMode = !toggleDarkMode; darkMode()\">\n <div class=\"menu-item\">\n <span class=\"icon moon-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M13.5 10C12.7 10.3 11.9 10.5 11 10.5C7.4 10.5 4.5 7.6 4.5 4C4.5 3.1 4.7 2.3 5 1.5C2.7 2.5 1 4.8 1 7.5C1 11.1 3.9 14 7.5 14C10.2 14 12.5 12.3 13.5 10Z\"\n stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>{{ toggleDarkMode ? 'Light Mode' : 'Dark Mode' }}</span>\n </div>\n </li>\n }\n\n <!-- Highlights & Notes -->\n <!-- Highlights & Notes -->\n @if (enableHighlights || enableNotes) {\n <li (click)=\"openCommonPopup(1); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon notes-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2 4H14M2 8H14M2 12H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>Highlights & Notes</span>\n </div>\n </li>\n }\n\n <!-- Search Book -->\n <!-- Search Book -->\n @if (enableSearch) {\n <li (click)=\"openCommonPopup(2); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon search-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14 14L10.5 10.5M10.5 10.5C11.4 9.6 12 8.4 12 7C12 4.2 9.8 2 7 2C4.2 2 2 4.2 2 7C2 9.8 4.2 12 7 12C8.4 12 9.6 11.4 10.5 10.5Z\"\n stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>Search Book</span>\n </div>\n </li>\n }\n\n <!-- Bookmark List -->\n <!-- Bookmark List -->\n @if (enableBookmarks) {\n <li (click)=\"getBookMarkList(); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon bookmark-list-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 1.33H4C3.26 1.33 2.66 1.93 2.66 2.66V13.33C2.66 14.06 3.26 14.66 4 14.66H12C12.73 14.66 13.33 14.06 13.33 13.33V2.66C13.33 1.93 12.73 1.33 12 1.33ZM6 2.66H7.33V6L6.66 5.5L6 6V2.66ZM12 13.33H4V2.66H4.66V8.66L6.66 7.16L8.66 8.66V2.66H12V13.33Z\"\n fill=\"currentColor\" />\n </svg>\n </span>\n <span>Bookmark List</span>\n </div>\n </li>\n }\n\n <!-- Chapters List -->\n <!-- Chapters List -->\n @if (enableChapterList) {\n <li (click)=\"showChapterPopup(); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon chapter-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 15.33H2.66C1.93 15.33 1.33 14.73 1.33 14V4.66H2.66V14H12V15.33ZM11 8.66H7V10H11V8.66ZM10 0.66H5.33C4.6 0.66 4 1.26 4 2L4 11.33C4 12.06 4.6 12.66 5.33 12.66H12.66C13.4 12.66 14 12.06 14 11.33V4.66L10 0.66ZM12.66 11.33H5.33V2H9.44L12.66 5.22V11.33Z\"\n fill=\"currentColor\" />\n </svg>\n </span>\n <span>Chapters List</span>\n </div>\n </li>\n }\n\n <!-- Divider Row for Quick Actions -->\n <!-- Divider Row for Quick Actions -->\n <li class=\"quick-actions-row\">\n @if (enableFontSize) {\n <div class=\"quick-action-btn\" (click)=\"changeFontSize('+')\">\n <span class=\"text-sm font-bold\">A+</span>\n </div>\n <div class=\"quick-action-btn\" (click)=\"changeFontSize('-')\">\n <span class=\"text-sm font-bold\">A-</span>\n </div>\n }\n @if (enableNotes) {\n <div class=\"quick-action-btn\" (click)=\"addNoteToPage(); isMenuOpen = false\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3 17.25V21H6.75L17.81 9.94L14.06 6.19L3 17.25ZM20.71 7.04C21.1 6.65 21.1 6.02 20.71 5.63L18.37 3.29C17.98 2.9 17.35 2.9 16.96 3.29L15.13 5.12L18.88 8.87L20.71 7.04Z\"\n fill=\"currentColor\" />\n </svg>\n </div>\n }\n @if (enableBookmarks) {\n <div class=\"quick-action-btn\" (click)=\"addBookMark(); isMenuOpen = false\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M17 3H7C5.9 3 5 3.9 5 5V21L12 18L19 21V5C19 3.9 18.1 3 17 3Z\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n }\n </li>\n </ul>\n </div>\n }\n\n <!-- Selection Menu Inside Footer Hub -->\n @if (freeSample === 'false') {\n @if (showHighlightOverlay) {\n <div class=\"custom-selection-toolbar selection-menu fade-in\">\n @if (enableNotes) {\n <div class=\"menu-item\" (click)=\"addNotes(); showHighlightOverlay = false\">\n <span class=\"menu-text\">Add Notes</span>\n </div>\n }\n @if (enableHighlights) {\n <div class=\"menu-item\" (click)=\"showhightLightColor = true; showHighlightOverlay = false\" title=\"Highlight\">\n <span class=\"menu-text\">Highlights</span>\n </div>\n }\n @if (enableHighlights) {\n <div class=\"menu-item\" (click)=\"addUnderline(); showHighlightOverlay = false\">\n <span class=\"menu-text\">Underline</span>\n </div>\n }\n @if (enableNotes || enableHighlights) {\n <!-- Definition often goes with these tools -->\n <div class=\"menu-item border-none\" (click)=\"openCommonPopup(4); showHighlightOverlay = false\">\n <span class=\"menu-text\">Definition</span>\n </div>\n }\n </div>\n }\n\n @if (showhightLightColor) {\n <div class=\"custom-selection-toolbar color-picker fade-in\">\n @for (color of colourCodeList; track color) {\n <div class=\"color-circle\" [style.background]=\"color\"\n (click)=\"addHighlight(color); showhightLightColor = false\"></div>\n }\n <button class=\"toolbar-btn close-colors\" (click)=\"showhightLightColor = false; showHighlightOverlay = true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M19 12H5\"></path>\n </svg>\n </button>\n </div>\n }\n }\n\n <!-- The Green Toggle Button -->\n <button class=\"menu-toggle-btn\" (click)=\"toggleAllMenus()\"\n [class.open]=\"isMenuOpen || showHighlightOverlay || showhightLightColor\">\n <!-- X Icon when open, Burger/Menu when closed -->\n @if (isMenuOpen || showHighlightOverlay || showhightLightColor) {\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n } @else {\n <!-- Menu Grid Icon -->\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6H20M4 12H20M4 18H20\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n }\n </button>\n </div>\n\n <!-- Next Button -->\n <button class=\"nav-btn next-btn\" (click)=\"nextClick()\" [class.ml-4]=\"true\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n</div>\n\n\n@if (showBookPageLoader) {\n<div class=\"fixed inset-0 z-[45] flex items-center justify-center bg-premium-loader fade-in\">\n <div class=\"text-center\">\n <div class=\"mb-8 relative inline-block\">\n <!-- Decorative Backdrop for Book -->\n <div class=\"absolute inset-0 bg-black/5 blur-2xl rounded-full transform scale-110\"></div>\n\n <!-- Larger, Premium Book Image -->\n <img [src]=\"coverImg ?? ''\" alt=\"Loading\"\n class=\"w-56 h-80 object-cover rounded-xl shadow-premium border-[6px] border-white relative z-10 animate-pulse\" />\n </div>\n\n <!-- Enhanced Loading Text Container -->\n <div class=\"flex flex-col items-center space-y-3\">\n <div class=\"flex items-center space-x-2 text-gray-400\">\n <span class=\"text-base font-medium\">Please wait a moment</span>\n <div class=\"flex space-x-1.5\">\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce\"></div>\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce [animation-delay:-0.15s]\"></div>\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce [animation-delay:-0.3s]\"></div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n@if (showOverlay) {\n<div class=\"screenshot-overlay\"></div>\n}\n\n<!-- Full-screen Preview End Modal -->\n@if (showPreviewModal) {\n<div class=\"fixed inset-0 z-40 bg-white dark:bg-gray-900 flex flex-col items-center justify-center text-center px-4\">\n <h2\n class=\"text-[1.375rem] sm:text-2xl font-medium leading-snug text-center text-gray-800 dark:text-white mb-6 max-w-xs sm:max-w-sm mx-auto\">\n You\u2019ve reached the end of the sample for\n </h2>\n\n <img [src]=\"coverImg ?? ''\" alt=\"Book Cover\" class=\"w-40 h-auto rounded-lg shadow-lg mb-6\" />\n</div>\n}\n\n\n<!-- Custom Chapter List Modal -->\n@if (showChapterList) {\n<div class=\"custom-modal-overlay fade-in\">\n <div class=\"custom-modal-content\">\n <app-chapterlist [chapterData]=\"chaptersData\" (chapterClick)=\"onChapterSelect($event)\"\n (closeDialog)=\"showChapterList = false\">\n </app-chapterlist>\n </div>\n</div>\n}", styles: [":host{--bg-primary: #ffffff;--bg-secondary: #f8fafc;--text-primary: #0f172a;--text-secondary: #475569;--border-base: #edf2f7;--shadow-base: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06);--accent-color: #34C759;--modal-bg: #ffffff;--modal-text: #0f172a}:host-context(.dark-mode){--bg-primary: rgb(32 33 32);--bg-secondary: rgb(42 43 42);--text-primary: #f8fafc;--text-secondary: #94a3b8;--border-base: #2d3748;--shadow-base: 0 10px 15px -3px rgba(0, 0, 0, .5);--accent-color: #32d74b;--modal-bg: rgb(32 33 32);--modal-text: #f9fafb}#reader{width:100%;height:100%}.no-select{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:default}.screenshot-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#fff;z-index:9999}img,[draggable=true]{-webkit-user-drag:none}::ng-deep *{-webkit-user-drag:none}::ng-deep .textLayer span{-webkit-user-drag:none;pointer-events:auto}.fade-in{animation:fadeIn .5s ease-in forwards}.fade-out{animation:fadeOut .5s ease-out forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.7}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media print{#viewer{display:none!important}body:before{content:\"Printing is disabled.\";font-size:24px;color:red;text-align:center;display:block;margin-top:100px}}.progress-container{position:relative;height:4px}.range-overlay{position:absolute;top:0;left:0;width:100%;z-index:10;background:transparent;cursor:pointer;-webkit-appearance:none;appearance:none;touch-action:none}.range-overlay::-webkit-slider-thumb{-webkit-appearance:none;height:14px;width:14px;margin-top:-5px;border-radius:50%;background:#0ea951;border:2px solid #ffffff;box-shadow:0 1px 3px #0003;transition:background .2s ease,transform .2s ease}.range-overlay::-webkit-slider-thumb:hover{background:#0cb14f;transform:scale(1.1)}.range-overlay::-webkit-slider-thumb:active{background:#0ba046;transform:scale(1.15)}.range-overlay::-webkit-slider-runnable-track{background:transparent;height:4px}.range-overlay::-moz-range-thumb{height:16px;width:16px;border-radius:50%;background:#0ea951;border:2px solid white}.range-overlay::-moz-range-track{background:transparent;height:4px}.range-overlay::-ms-thumb{height:16px;width:16px;border-radius:50%;background:#0ea951;border:2px solid white}.range-overlay::-ms-track{background:transparent;height:4px;border-color:transparent;color:transparent}#reader-container:after{content:\"\";position:absolute;top:13%;bottom:10%;left:50%;transform:translate(-50%);width:2px;background:linear-gradient(to bottom,#06030300,#0d080833,#0000);box-shadow:0 0 10px #0000001a;z-index:1}@media (max-width: 767px){#reader-container:after{display:none!important}}@media (max-width: 991px){#reader-container:after{display:none!important}}::ng-deep nav{box-shadow:none!important}::ng-deep .highlightandNotes .ngneat-dialog-content{width:510px!important;padding:24px}::ng-deep .highlightandNotes .ngneat-close-dialog{top:1.2rem}::ng-deep .highlightandNotes.dark-mode .ngneat-dialog-content{background-color:#333;color:#fff!important}::ng-deep .highlightandNotes.dark-mode .ngneat-close-dialog{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .ngneat-dialog-content{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .text-\\[\\#272C47\\]{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .text-black{color:#fff!important}::ng-deep .addandeditNotepopup .ngneat-dialog-content{width:690px!important}::ng-deep .crop-popup .ngneat-dialog-content{width:420px!important}:host,app-notes{background-color:var(--bg-primary);display:flex;width:100%;justify-content:center;transition:background-color .3s ease}#reader-container{width:100%;height:98vh;background-color:var(--bg-primary);padding-top:0;display:flex;flex-direction:column;overflow:hidden;transition:background-color .3s ease}#reader-content{flex:1;overflow:hidden;position:relative}#reader-footer{position:relative;width:60vw;margin:0 auto;padding:10px 38px 20px;background:var(--bg-primary);z-index:50;transition:background-color .3s ease}#reader-footer .footer-container{display:flex;justify-content:space-between;align-items:flex-end;gap:20px}#reader-footer .nav-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;cursor:pointer;transition:background .2s;background:transparent;border:none;color:var(--text-primary)}#reader-footer .nav-btn:hover{background:#f5f5f5}#reader-footer .nav-btn svg{width:20px;height:20px}#reader-footer .progress-section{flex:1;display:flex;flex-direction:column;align-items:center;max-width:600px;margin:0 auto;padding-bottom:5px}#reader-footer .progress-section .progress-label{font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:#666;margin-bottom:6px}#reader-footer .progress-section .progress-bar-container{position:relative;width:100%;height:14px;display:flex;align-items:center}#reader-footer .progress-section .progress-bar-container .progress-track{flex:1;height:4px;background:#e7ebeb;border-radius:2px;overflow:hidden;position:relative}#reader-footer .progress-section .progress-bar-container .progress-fill{height:100%;background:#34c759;transition:width .2s ease-out;border-radius:2px}#reader-footer .progress-section .progress-bar-container .progress-slider{position:absolute;width:100%;height:100%;opacity:0;cursor:pointer;top:0;left:0;z-index:2}#reader-footer .progress-section .progress-bar-container .progress-text{margin-left:12px;font-size:12px;font-weight:600;min-width:35px;color:var(--text-primary)}#reader-footer .right-controls{display:flex;align-items:center;gap:16px}#reader-footer .menu-toggle-btn{width:48px;height:48px;border-radius:50%;background:#34c759;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);box-shadow:0 4px 10px #34c7594d;border:none}#reader-footer .menu-toggle-btn.open{background:#34c759;transform:rotate(90deg)}#reader-footer .menu-toggle-btn:hover{transform:scale(1.05);background:#2ebd50}#reader-footer .menu-popup{position:absolute;bottom:70px;right:0;width:280px;background:var(--bg-primary);border-radius:16px;box-shadow:var(--shadow-base);padding:8px 0;z-index:100;border:1px solid var(--border-base);transform-origin:bottom right}#reader-footer .menu-popup .menu-list{list-style:none;padding:0;margin:0}#reader-footer .menu-popup .menu-list li{padding:0 8px;cursor:pointer}#reader-footer .menu-popup .menu-list .menu-item{display:flex;align-items:center;padding:12px;font-size:14px;font-weight:500;color:var(--text-primary);border-radius:8px;transition:background .1s}#reader-footer .menu-popup .menu-list .menu-item:hover{background:var(--bg-secondary)}#reader-footer .menu-popup .menu-list .menu-item .icon{width:32px;display:flex;align-items:center;justify-content:flex-start;color:var(--text-secondary)}#reader-footer .menu-popup .menu-list .menu-item .icon svg{width:18px;height:18px}#reader-footer .menu-popup .quick-actions-row{display:flex;justify-content:space-between;padding:12px 16px;margin-top:8px;border-top:1px solid #f0f0f0;gap:8px}#reader-footer .menu-popup .quick-actions-row .quick-action-btn{flex:1;height:40px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:var(--bg-secondary);cursor:pointer;color:var(--text-primary);transition:all .2s}#reader-footer .menu-popup .quick-actions-row .quick-action-btn:hover{background:var(--border-base)}.calibre{padding:0!important}.hightlight-overlay ::ng-deep .p-overlay{top:-232px!important}app-chapterlist ::ng-deep #reader-content{padding:0!important}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;backdrop-filter:blur(4px);z-index:200;display:flex;align-items:center;justify-content:center}.custom-modal-content{background:var(--modal-bg);color:var(--modal-text);width:90%;max-width:500px;border-radius:12px;box-shadow:var(--shadow-base);overflow:hidden;animation:modalEnter .2s ease-out;transition:background-color .3s ease,color .3s ease}@keyframes modalEnter{0%{opacity:0;transform:scale(.95) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}.animate-bounce{animation:bounce .6s infinite}.fixed{position:fixed}.inset-0{inset:0}.z-40{z-index:40}.z-45{z-index:45}.flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.text-center{text-align:center}.bg-white{background-color:#fff}.bg-white\\/95{background-color:#fffffff2!important}.bg-black\\/5{background-color:#0000000d}.bg-accent-color{background-color:var(--accent-color)}.bg-premium-loader{background:var(--bg-primary)}.blur-2xl{filter:blur(40px)}.transform{--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1}.relative{position:relative}.absolute{position:absolute}.inline-block{display:inline-block}.z-10{z-index:10}.mb-8{margin-bottom:2rem}.space-y-3>*+*{margin-top:.75rem}.space-x-1\\.5>*+*{margin-left:.375rem}.tracking-tight{letter-spacing:-.025em}.text-gray-800{color:#1f2937}.border-\\[6px\\]{border-width:6px}.backdrop-blur-sm{backdrop-filter:blur(4px)}.w-full{width:100%}.px-4{padding-left:1rem;padding-right:1rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-\\[-1\\.5rem\\]{margin-top:-1.5rem}.ml-1{margin-left:.25rem}.space-x-1>*+*{margin-left:.25rem}.space-x-2>*+*{margin-left:.5rem}.inline-flex{display:inline-flex}.text-gray-700{color:#374151}.text-gray-400{color:#9ca3af}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.w-40{width:10rem}.h-56{height:14rem}.w-56{width:14rem}.h-80{height:20rem}.w-32{width:8rem}.h-44{height:11rem}.object-cover{object-fit:cover}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.shadow-2xl{box-shadow:0 25px 50px -12px #00000040}.shadow-premium{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a,0 0 0 1px #0000000d}.mx-auto{margin-left:auto;margin-right:auto}.border-4{border-width:4px}.border-white{border-color:#fff}.border-gray-50{border-color:#f9fafb}.w-1\\.5{width:.375rem}.h-1\\.5{height:.375rem}.bg-gray-400{background-color:#9ca3af}.rounded-full{border-radius:9999px}.custom-selection-toolbar{position:absolute;bottom:70px;right:0;z-index:100;width:280px;background:var(--bg-primary);border-radius:16px;box-shadow:var(--shadow-base);display:flex;flex-direction:column;overflow:hidden;border:1px solid var(--border-base);padding:8px 0;transform-origin:bottom right}.custom-selection-toolbar .menu-item{padding:12px 20px;border-bottom:1px solid #f1f5f9;cursor:pointer;transition:all .2s ease;display:flex;align-items:center}.custom-selection-toolbar .menu-item:hover{background:#f8fafc}.custom-selection-toolbar .menu-item:hover .menu-text{color:var(--accent-color)}.custom-selection-toolbar .menu-item.border-none{border-bottom:none}.custom-selection-toolbar .menu-item .menu-text{font-size:15px;font-weight:500;color:#334155}.custom-selection-toolbar.color-picker{width:auto;flex-direction:row;padding:8px 12px;gap:12px;align-items:center}.custom-selection-toolbar.color-picker .color-circle{width:24px;height:24px;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0000001a;transition:transform .2s ease}.custom-selection-toolbar.color-picker .color-circle:hover{transform:scale(1.2)}.custom-selection-toolbar.color-picker .toolbar-btn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;border:none;background:#f1f5f9;color:#64748b;cursor:pointer;margin-left:4px}.custom-selection-toolbar.color-picker .toolbar-btn:hover{background:#e2e8f0}:host-context(.dark-mode) .custom-selection-toolbar{background:#1e293b;border-color:#334155}:host-context(.dark-mode) .custom-selection-toolbar .menu-item{border-bottom-color:#334155}:host-context(.dark-mode) .custom-selection-toolbar .menu-item:hover{background:#0f172a}:host-context(.dark-mode) .custom-selection-toolbar .menu-item .menu-text{color:#f1f5f9}:host-context(.dark-mode) .custom-selection-toolbar.color-picker .toolbar-btn{background:#334155;color:#f1f5f9}\n"], dependencies: [{ kind: "component", type: ChapterlistComponent, selector: "app-chapterlist", inputs: ["chapterData"], outputs: ["chapterClick", "closeDialog"] }] });
2179
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ReaderMainComponent, deps: [{ token: i0.NgZone }, { token: HttpApiService }, { token: SharedService }, { token: EpubReaderService }, { token: i0.ChangeDetectorRef }, { token: i3.ActivatedRoute }, { token: CustomDialogService }, { token: NotificationService }, { token: i1$2.Location }, { token: PLATFORM_ID }, { token: i3.Router }, { token: i1$1.Overlay }], target: i0.ɵɵFactoryTarget.Component });
2180
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.17", type: ReaderMainComponent, isStandalone: false, selector: "epub-flow", inputs: { epubUrl: "epubUrl", epubBlob: "epubBlob", coverPage: "coverPage", enableDarkMode: "enableDarkMode", enableSearch: "enableSearch", enableHighlights: "enableHighlights", enableBookmarks: "enableBookmarks", enableChapterList: "enableChapterList", enableTextSelection: "enableTextSelection", enableFontSize: "enableFontSize", enableNotes: "enableNotes", bookId: "bookId" }, outputs: { underlineRemoveRequest: "underlineRemoveRequest" }, host: { listeners: { "document:keyup": "handleKeyUp($event)", "document:keydown": "onKeyDown($event)" } }, usesOnChanges: true, ngImport: i0, template: "<div id=\"reader-container\" [hidden]=\"showBookPageLoader || showDwndLoader\">\n <div id=\"reader-content\" style=\"overflow: hidden;\">\n <div id=\"reader\"></div>\n </div>\n\n <div id=\"reader-footer\">\n <div class=\"footer-container\">\n <!-- Left: Previous Button -->\n <button class=\"nav-btn prev-btn\" (click)=\"prevClick()\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <!-- Center: Progress Bar -->\n <div class=\"progress-section\">\n <div class=\"progress-label\">Read Progress</div>\n <div class=\"progress-bar-container\">\n <div class=\"progress-track\">\n <div class=\"progress-fill\" [style.width.%]=\"readPercentage.roudedOff\"></div>\n </div>\n <input type=\"range\" class=\"progress-slider\" min=\"0\" max=\"100\" [value]=\"readPercentage.roudedOff\"\n (input)=\"onProgressChange($event)\" />\n <span class=\"progress-text\">{{ readPercentage.roudedOff }}%</span>\n </div>\n </div>\n\n <!-- Right: Menu Toggle & Next Button -->\n <div class=\"right-controls\">\n <!-- Menu Toggle Button (Green) -->\n <div class=\"menu-container relative\">\n <!-- The Menu Popup -->\n @if (isMenuOpen) {\n <div class=\"menu-popup fade-in\">\n <ul class=\"menu-list\">\n <!-- Dark Mode -->\n <!-- Dark Mode -->\n @if (enableDarkMode) {\n <li (click)=\"toggleDarkMode = !toggleDarkMode; darkMode()\">\n <div class=\"menu-item\">\n <span class=\"icon moon-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M13.5 10C12.7 10.3 11.9 10.5 11 10.5C7.4 10.5 4.5 7.6 4.5 4C4.5 3.1 4.7 2.3 5 1.5C2.7 2.5 1 4.8 1 7.5C1 11.1 3.9 14 7.5 14C10.2 14 12.5 12.3 13.5 10Z\"\n stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>{{ toggleDarkMode ? 'Light Mode' : 'Dark Mode' }}</span>\n </div>\n </li>\n }\n\n <!-- Highlights & Notes -->\n <!-- Highlights & Notes -->\n @if (enableHighlights || enableNotes) {\n <li (click)=\"openCommonPopup(1); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon notes-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2 4H14M2 8H14M2 12H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>Highlights & Notes</span>\n </div>\n </li>\n }\n\n <!-- Search Book -->\n <!-- Search Book -->\n @if (enableSearch) {\n <li (click)=\"openCommonPopup(2); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon search-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14 14L10.5 10.5M10.5 10.5C11.4 9.6 12 8.4 12 7C12 4.2 9.8 2 7 2C4.2 2 2 4.2 2 7C2 9.8 4.2 12 7 12C8.4 12 9.6 11.4 10.5 10.5Z\"\n stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>Search Book</span>\n </div>\n </li>\n }\n\n <!-- Bookmark List -->\n <!-- Bookmark List -->\n @if (enableBookmarks) {\n <li (click)=\"getBookMarkList(); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon bookmark-list-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 1.33H4C3.26 1.33 2.66 1.93 2.66 2.66V13.33C2.66 14.06 3.26 14.66 4 14.66H12C12.73 14.66 13.33 14.06 13.33 13.33V2.66C13.33 1.93 12.73 1.33 12 1.33ZM6 2.66H7.33V6L6.66 5.5L6 6V2.66ZM12 13.33H4V2.66H4.66V8.66L6.66 7.16L8.66 8.66V2.66H12V13.33Z\"\n fill=\"currentColor\" />\n </svg>\n </span>\n <span>Bookmark List</span>\n </div>\n </li>\n }\n\n <!-- Chapters List -->\n <!-- Chapters List -->\n @if (enableChapterList) {\n <li (click)=\"showChapterPopup(); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon chapter-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 15.33H2.66C1.93 15.33 1.33 14.73 1.33 14V4.66H2.66V14H12V15.33ZM11 8.66H7V10H11V8.66ZM10 0.66H5.33C4.6 0.66 4 1.26 4 2L4 11.33C4 12.06 4.6 12.66 5.33 12.66H12.66C13.4 12.66 14 12.06 14 11.33V4.66L10 0.66ZM12.66 11.33H5.33V2H9.44L12.66 5.22V11.33Z\"\n fill=\"currentColor\" />\n </svg>\n </span>\n <span>Chapters List</span>\n </div>\n </li>\n }\n\n <!-- Divider Row for Quick Actions -->\n <!-- Divider Row for Quick Actions -->\n <li class=\"quick-actions-row\">\n @if (enableFontSize) {\n <div class=\"quick-action-btn\" (click)=\"changeFontSize('+')\">\n <span class=\"text-sm font-bold\">A+</span>\n </div>\n <div class=\"quick-action-btn\" (click)=\"changeFontSize('-')\">\n <span class=\"text-sm font-bold\">A-</span>\n </div>\n }\n @if (enableNotes) {\n <div class=\"quick-action-btn\" (click)=\"addNoteToPage(); isMenuOpen = false\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3 17.25V21H6.75L17.81 9.94L14.06 6.19L3 17.25ZM20.71 7.04C21.1 6.65 21.1 6.02 20.71 5.63L18.37 3.29C17.98 2.9 17.35 2.9 16.96 3.29L15.13 5.12L18.88 8.87L20.71 7.04Z\"\n fill=\"currentColor\" />\n </svg>\n </div>\n }\n @if (enableBookmarks) {\n <div class=\"quick-action-btn\" (click)=\"addBookMark(); isMenuOpen = false\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M17 3H7C5.9 3 5 3.9 5 5V21L12 18L19 21V5C19 3.9 18.1 3 17 3Z\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n }\n </li>\n </ul>\n </div>\n }\n\n <!-- Selection Menu Inside Footer Hub -->\n @if (freeSample === 'false') {\n @if (showHighlightOverlay) {\n <div class=\"custom-selection-toolbar selection-menu fade-in\">\n @if (enableNotes) {\n <div class=\"menu-item\" (click)=\"addNotes(); showHighlightOverlay = false\">\n <span class=\"menu-text\">Add Notes</span>\n </div>\n }\n @if (enableHighlights) {\n <div class=\"menu-item\" (click)=\"showhightLightColor = true; showHighlightOverlay = false\" title=\"Highlight\">\n <span class=\"menu-text\">Highlights</span>\n </div>\n }\n @if (enableHighlights) {\n <div class=\"menu-item\" (click)=\"addUnderline(); showHighlightOverlay = false\">\n <span class=\"menu-text\">Underline</span>\n </div>\n }\n @if (enableNotes || enableHighlights) {\n <!-- Definition often goes with these tools -->\n <div class=\"menu-item border-none\" (click)=\"openCommonPopup(4); showHighlightOverlay = false\">\n <span class=\"menu-text\">Definition</span>\n </div>\n }\n </div>\n }\n\n @if (showhightLightColor) {\n <div class=\"custom-selection-toolbar color-picker fade-in\">\n @for (color of colourCodeList; track color) {\n <div class=\"color-circle\" [style.background]=\"color\"\n (click)=\"addHighlight(color); showhightLightColor = false\"></div>\n }\n <button class=\"toolbar-btn close-colors\" (click)=\"showhightLightColor = false; showHighlightOverlay = true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M19 12H5\"></path>\n </svg>\n </button>\n </div>\n }\n }\n\n <!-- The Green Toggle Button -->\n <button class=\"menu-toggle-btn\" (click)=\"toggleAllMenus()\"\n [class.open]=\"isMenuOpen || showHighlightOverlay || showhightLightColor\">\n <!-- X Icon when open, Burger/Menu when closed -->\n @if (isMenuOpen || showHighlightOverlay || showhightLightColor) {\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n } @else {\n <!-- Menu Grid Icon -->\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6H20M4 12H20M4 18H20\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n }\n </button>\n </div>\n\n <!-- Next Button -->\n <button class=\"nav-btn next-btn\" (click)=\"nextClick()\" [class.ml-4]=\"true\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n</div>\n\n\n@if (showBookPageLoader) {\n<div class=\"fixed inset-0 z-[45] flex items-center justify-center bg-premium-loader fade-in\">\n <div class=\"text-center\">\n <div class=\"mb-8 relative inline-block\">\n <!-- Decorative Backdrop for Book -->\n <div class=\"absolute inset-0 bg-black/5 blur-2xl rounded-full transform scale-110\"></div>\n\n <!-- Larger, Premium Book Image -->\n <img [src]=\"coverImg ?? ''\" alt=\"Loading\"\n class=\"w-56 h-80 object-cover rounded-xl shadow-premium border-[6px] border-white relative z-10 animate-pulse\" />\n </div>\n\n <!-- Enhanced Loading Text Container -->\n <div class=\"flex flex-col items-center space-y-3\">\n <div class=\"flex items-center space-x-2 text-gray-400\">\n <span class=\"text-base font-medium\">Please wait a moment</span>\n <div class=\"flex space-x-1.5\">\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce\"></div>\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce [animation-delay:-0.15s]\"></div>\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce [animation-delay:-0.3s]\"></div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n@if (showOverlay) {\n<div class=\"screenshot-overlay\"></div>\n}\n\n<!-- Full-screen Preview End Modal -->\n@if (showPreviewModal) {\n<div class=\"fixed inset-0 z-40 bg-white dark:bg-gray-900 flex flex-col items-center justify-center text-center px-4\">\n <h2\n class=\"text-[1.375rem] sm:text-2xl font-medium leading-snug text-center text-gray-800 dark:text-white mb-6 max-w-xs sm:max-w-sm mx-auto\">\n You\u2019ve reached the end of the sample for\n </h2>\n\n <img [src]=\"coverImg ?? ''\" alt=\"Book Cover\" class=\"w-40 h-auto rounded-lg shadow-lg mb-6\" />\n</div>\n}\n\n\n<!-- Custom Chapter List Modal -->\n@if (showChapterList) {\n<div class=\"custom-modal-overlay fade-in\">\n <div class=\"custom-modal-content\">\n <app-chapterlist [chapterData]=\"chaptersData\" (chapterClick)=\"onChapterSelect($event)\"\n (closeDialog)=\"showChapterList = false\">\n </app-chapterlist>\n </div>\n</div>\n}\n<epub-notification-toast></epub-notification-toast>", styles: [":host{--bg-primary: #ffffff;--bg-secondary: #f8fafc;--text-primary: #0f172a;--text-secondary: #475569;--border-base: #edf2f7;--shadow-base: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06);--accent-color: #34C759;--modal-bg: #ffffff;--modal-text: #0f172a}:host-context(.dark-mode){--bg-primary: rgb(32 33 32);--bg-secondary: rgb(42 43 42);--text-primary: #f8fafc;--text-secondary: #94a3b8;--border-base: #2d3748;--shadow-base: 0 10px 15px -3px rgba(0, 0, 0, .5);--accent-color: #32d74b;--modal-bg: rgb(32 33 32);--modal-text: #f9fafb}#reader{width:100%;height:100%}.no-select{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:default}.screenshot-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#fff;z-index:9999}img,[draggable=true]{-webkit-user-drag:none}::ng-deep *{-webkit-user-drag:none}::ng-deep .textLayer span{-webkit-user-drag:none;pointer-events:auto}.fade-in{animation:fadeIn .5s ease-in forwards}.fade-out{animation:fadeOut .5s ease-out forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.7}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media print{#viewer{display:none!important}body:before{content:\"Printing is disabled.\";font-size:24px;color:red;text-align:center;display:block;margin-top:100px}}.progress-container{position:relative;height:4px}.range-overlay{position:absolute;top:0;left:0;width:100%;z-index:10;background:transparent;cursor:pointer;-webkit-appearance:none;appearance:none;touch-action:none}.range-overlay::-webkit-slider-thumb{-webkit-appearance:none;height:14px;width:14px;margin-top:-5px;border-radius:50%;background:#0ea951;border:2px solid #ffffff;box-shadow:0 1px 3px #0003;transition:background .2s ease,transform .2s ease}.range-overlay::-webkit-slider-thumb:hover{background:#0cb14f;transform:scale(1.1)}.range-overlay::-webkit-slider-thumb:active{background:#0ba046;transform:scale(1.15)}.range-overlay::-webkit-slider-runnable-track{background:transparent;height:4px}.range-overlay::-moz-range-thumb{height:16px;width:16px;border-radius:50%;background:#0ea951;border:2px solid white}.range-overlay::-moz-range-track{background:transparent;height:4px}.range-overlay::-ms-thumb{height:16px;width:16px;border-radius:50%;background:#0ea951;border:2px solid white}.range-overlay::-ms-track{background:transparent;height:4px;border-color:transparent;color:transparent}#reader-container:after{content:\"\";position:absolute;top:13%;bottom:10%;left:50%;transform:translate(-50%);width:2px;background:linear-gradient(to bottom,#06030300,#0d080833,#0000);box-shadow:0 0 10px #0000001a;z-index:1}@media (max-width: 767px){#reader-container:after{display:none!important}}@media (max-width: 991px){#reader-container:after{display:none!important}}::ng-deep nav{box-shadow:none!important}::ng-deep .highlightandNotes .ngneat-dialog-content{width:510px!important;padding:24px}::ng-deep .highlightandNotes .ngneat-close-dialog{top:1.2rem}::ng-deep .highlightandNotes.dark-mode .ngneat-dialog-content{background-color:#333;color:#fff!important}::ng-deep .highlightandNotes.dark-mode .ngneat-close-dialog{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .ngneat-dialog-content{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .text-\\[\\#272C47\\]{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .text-black{color:#fff!important}::ng-deep .addandeditNotepopup .ngneat-dialog-content{width:690px!important}::ng-deep .crop-popup .ngneat-dialog-content{width:420px!important}:host,app-notes{background-color:var(--bg-primary);display:flex;width:100%;justify-content:center;transition:background-color .3s ease}#reader-container{width:100%;height:98vh;background-color:var(--bg-primary);padding-top:0;display:flex;flex-direction:column;overflow:hidden;transition:background-color .3s ease}#reader-content{flex:1;overflow:hidden;position:relative}#reader-footer{position:relative;width:60vw;margin:0 auto;padding:10px 38px 20px;background:var(--bg-primary);z-index:50;transition:background-color .3s ease}#reader-footer .footer-container{display:flex;justify-content:space-between;align-items:flex-end;gap:20px}#reader-footer .nav-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;cursor:pointer;transition:background .2s;background:transparent;border:none;color:var(--text-primary)}#reader-footer .nav-btn:hover{background:#f5f5f5}#reader-footer .nav-btn svg{width:20px;height:20px}#reader-footer .progress-section{flex:1;display:flex;flex-direction:column;align-items:center;max-width:600px;margin:0 auto;padding-bottom:5px}#reader-footer .progress-section .progress-label{font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:#666;margin-bottom:6px}#reader-footer .progress-section .progress-bar-container{position:relative;width:100%;height:14px;display:flex;align-items:center}#reader-footer .progress-section .progress-bar-container .progress-track{flex:1;height:4px;background:#e7ebeb;border-radius:2px;overflow:hidden;position:relative}#reader-footer .progress-section .progress-bar-container .progress-fill{height:100%;background:#34c759;transition:width .2s ease-out;border-radius:2px}#reader-footer .progress-section .progress-bar-container .progress-slider{position:absolute;width:100%;height:100%;opacity:0;cursor:pointer;top:0;left:0;z-index:2}#reader-footer .progress-section .progress-bar-container .progress-text{margin-left:12px;font-size:12px;font-weight:600;min-width:35px;color:var(--text-primary)}#reader-footer .right-controls{display:flex;align-items:center;gap:16px}#reader-footer .menu-toggle-btn{width:48px;height:48px;border-radius:50%;background:#34c759;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);box-shadow:0 4px 10px #34c7594d;border:none}#reader-footer .menu-toggle-btn.open{background:#34c759;transform:rotate(90deg)}#reader-footer .menu-toggle-btn:hover{transform:scale(1.05);background:#2ebd50}#reader-footer .menu-popup{position:absolute;bottom:70px;right:0;width:280px;background:var(--bg-primary);border-radius:16px;box-shadow:var(--shadow-base);padding:8px 0;z-index:100;border:1px solid var(--border-base);transform-origin:bottom right}#reader-footer .menu-popup .menu-list{list-style:none;padding:0;margin:0}#reader-footer .menu-popup .menu-list li{padding:0 8px;cursor:pointer}#reader-footer .menu-popup .menu-list .menu-item{display:flex;align-items:center;padding:12px;font-size:14px;font-weight:500;color:var(--text-primary);border-radius:8px;transition:background .1s}#reader-footer .menu-popup .menu-list .menu-item:hover{background:var(--bg-secondary)}#reader-footer .menu-popup .menu-list .menu-item .icon{width:32px;display:flex;align-items:center;justify-content:flex-start;color:var(--text-secondary)}#reader-footer .menu-popup .menu-list .menu-item .icon svg{width:18px;height:18px}#reader-footer .menu-popup .quick-actions-row{display:flex;justify-content:space-between;padding:12px 16px;margin-top:8px;border-top:1px solid #f0f0f0;gap:8px}#reader-footer .menu-popup .quick-actions-row .quick-action-btn{flex:1;height:40px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:var(--bg-secondary);cursor:pointer;color:var(--text-primary);transition:all .2s}#reader-footer .menu-popup .quick-actions-row .quick-action-btn:hover{background:var(--border-base)}.calibre{padding:0!important}.hightlight-overlay ::ng-deep .p-overlay{top:-232px!important}app-chapterlist ::ng-deep #reader-content{padding:0!important}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;backdrop-filter:blur(4px);z-index:200;display:flex;align-items:center;justify-content:center}.custom-modal-content{background:var(--modal-bg);color:var(--modal-text);width:90%;max-width:500px;border-radius:12px;box-shadow:var(--shadow-base);overflow:hidden;animation:modalEnter .2s ease-out;transition:background-color .3s ease,color .3s ease}@keyframes modalEnter{0%{opacity:0;transform:scale(.95) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}.animate-bounce{animation:bounce .6s infinite}.fixed{position:fixed}.inset-0{inset:0}.z-40{z-index:40}.z-45{z-index:45}.flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.text-center{text-align:center}.bg-white{background-color:#fff}.bg-white\\/95{background-color:#fffffff2!important}.bg-black\\/5{background-color:#0000000d}.bg-accent-color{background-color:var(--accent-color)}.bg-premium-loader{background:var(--bg-primary)}.blur-2xl{filter:blur(40px)}.transform{--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1}.relative{position:relative}.absolute{position:absolute}.inline-block{display:inline-block}.z-10{z-index:10}.mb-8{margin-bottom:2rem}.space-y-3>*+*{margin-top:.75rem}.space-x-1\\.5>*+*{margin-left:.375rem}.tracking-tight{letter-spacing:-.025em}.text-gray-800{color:#1f2937}.border-\\[6px\\]{border-width:6px}.backdrop-blur-sm{backdrop-filter:blur(4px)}.w-full{width:100%}.px-4{padding-left:1rem;padding-right:1rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-\\[-1\\.5rem\\]{margin-top:-1.5rem}.ml-1{margin-left:.25rem}.space-x-1>*+*{margin-left:.25rem}.space-x-2>*+*{margin-left:.5rem}.inline-flex{display:inline-flex}.text-gray-700{color:#374151}.text-gray-400{color:#9ca3af}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.w-40{width:10rem}.h-56{height:14rem}.w-56{width:14rem}.h-80{height:20rem}.w-32{width:8rem}.h-44{height:11rem}.object-cover{object-fit:cover}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.shadow-2xl{box-shadow:0 25px 50px -12px #00000040}.shadow-premium{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a,0 0 0 1px #0000000d}.mx-auto{margin-left:auto;margin-right:auto}.border-4{border-width:4px}.border-white{border-color:#fff}.border-gray-50{border-color:#f9fafb}.w-1\\.5{width:.375rem}.h-1\\.5{height:.375rem}.bg-gray-400{background-color:#9ca3af}.rounded-full{border-radius:9999px}.custom-selection-toolbar{position:absolute;bottom:70px;right:0;z-index:100;width:280px;background:var(--bg-primary);border-radius:16px;box-shadow:var(--shadow-base);display:flex;flex-direction:column;overflow:hidden;border:1px solid var(--border-base);padding:8px 0;transform-origin:bottom right}.custom-selection-toolbar .menu-item{padding:12px 20px;border-bottom:1px solid #f1f5f9;cursor:pointer;transition:all .2s ease;display:flex;align-items:center}.custom-selection-toolbar .menu-item:hover{background:#f8fafc}.custom-selection-toolbar .menu-item:hover .menu-text{color:var(--accent-color)}.custom-selection-toolbar .menu-item.border-none{border-bottom:none}.custom-selection-toolbar .menu-item .menu-text{font-size:15px;font-weight:500;color:#334155}.custom-selection-toolbar.color-picker{width:auto;flex-direction:row;padding:8px 12px;gap:12px;align-items:center}.custom-selection-toolbar.color-picker .color-circle{width:24px;height:24px;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0000001a;transition:transform .2s ease}.custom-selection-toolbar.color-picker .color-circle:hover{transform:scale(1.2)}.custom-selection-toolbar.color-picker .toolbar-btn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;border:none;background:#f1f5f9;color:#64748b;cursor:pointer;margin-left:4px}.custom-selection-toolbar.color-picker .toolbar-btn:hover{background:#e2e8f0}:host-context(.dark-mode) .custom-selection-toolbar{background:#1e293b;border-color:#334155}:host-context(.dark-mode) .custom-selection-toolbar .menu-item{border-bottom-color:#334155}:host-context(.dark-mode) .custom-selection-toolbar .menu-item:hover{background:#0f172a}:host-context(.dark-mode) .custom-selection-toolbar .menu-item .menu-text{color:#f1f5f9}:host-context(.dark-mode) .custom-selection-toolbar.color-picker .toolbar-btn{background:#334155;color:#f1f5f9}\n"], dependencies: [{ kind: "component", type: NotificationToastComponent, selector: "epub-notification-toast" }, { kind: "component", type: ChapterlistComponent, selector: "app-chapterlist", inputs: ["chapterData"], outputs: ["chapterClick", "closeDialog"] }] });
2105
2181
  }
2106
2182
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: ReaderMainComponent, decorators: [{
2107
2183
  type: Component,
2108
- args: [{ selector: 'epub-flow', standalone: false, template: "<div id=\"reader-container\" [hidden]=\"showBookPageLoader || showDwndLoader\">\n <div id=\"reader-content\" style=\"overflow: hidden;\">\n <div id=\"reader\"></div>\n </div>\n\n <div id=\"reader-footer\">\n <div class=\"footer-container\">\n <!-- Left: Previous Button -->\n <button class=\"nav-btn prev-btn\" (click)=\"prevClick()\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <!-- Center: Progress Bar -->\n <div class=\"progress-section\">\n <div class=\"progress-label\">Read Progress</div>\n <div class=\"progress-bar-container\">\n <div class=\"progress-track\">\n <div class=\"progress-fill\" [style.width.%]=\"readPercentage.roudedOff\"></div>\n </div>\n <input type=\"range\" class=\"progress-slider\" min=\"0\" max=\"100\" [value]=\"readPercentage.roudedOff\"\n (input)=\"onProgressChange($event)\" />\n <span class=\"progress-text\">{{ readPercentage.roudedOff }}%</span>\n </div>\n </div>\n\n <!-- Right: Menu Toggle & Next Button -->\n <div class=\"right-controls\">\n <!-- Menu Toggle Button (Green) -->\n <div class=\"menu-container relative\">\n <!-- The Menu Popup -->\n @if (isMenuOpen) {\n <div class=\"menu-popup fade-in\">\n <ul class=\"menu-list\">\n <!-- Dark Mode -->\n <!-- Dark Mode -->\n @if (enableDarkMode) {\n <li (click)=\"toggleDarkMode = !toggleDarkMode; darkMode()\">\n <div class=\"menu-item\">\n <span class=\"icon moon-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M13.5 10C12.7 10.3 11.9 10.5 11 10.5C7.4 10.5 4.5 7.6 4.5 4C4.5 3.1 4.7 2.3 5 1.5C2.7 2.5 1 4.8 1 7.5C1 11.1 3.9 14 7.5 14C10.2 14 12.5 12.3 13.5 10Z\"\n stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>{{ toggleDarkMode ? 'Light Mode' : 'Dark Mode' }}</span>\n </div>\n </li>\n }\n\n <!-- Highlights & Notes -->\n <!-- Highlights & Notes -->\n @if (enableHighlights || enableNotes) {\n <li (click)=\"openCommonPopup(1); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon notes-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2 4H14M2 8H14M2 12H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>Highlights & Notes</span>\n </div>\n </li>\n }\n\n <!-- Search Book -->\n <!-- Search Book -->\n @if (enableSearch) {\n <li (click)=\"openCommonPopup(2); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon search-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14 14L10.5 10.5M10.5 10.5C11.4 9.6 12 8.4 12 7C12 4.2 9.8 2 7 2C4.2 2 2 4.2 2 7C2 9.8 4.2 12 7 12C8.4 12 9.6 11.4 10.5 10.5Z\"\n stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>Search Book</span>\n </div>\n </li>\n }\n\n <!-- Bookmark List -->\n <!-- Bookmark List -->\n @if (enableBookmarks) {\n <li (click)=\"getBookMarkList(); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon bookmark-list-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 1.33H4C3.26 1.33 2.66 1.93 2.66 2.66V13.33C2.66 14.06 3.26 14.66 4 14.66H12C12.73 14.66 13.33 14.06 13.33 13.33V2.66C13.33 1.93 12.73 1.33 12 1.33ZM6 2.66H7.33V6L6.66 5.5L6 6V2.66ZM12 13.33H4V2.66H4.66V8.66L6.66 7.16L8.66 8.66V2.66H12V13.33Z\"\n fill=\"currentColor\" />\n </svg>\n </span>\n <span>Bookmark List</span>\n </div>\n </li>\n }\n\n <!-- Chapters List -->\n <!-- Chapters List -->\n @if (enableChapterList) {\n <li (click)=\"showChapterPopup(); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon chapter-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 15.33H2.66C1.93 15.33 1.33 14.73 1.33 14V4.66H2.66V14H12V15.33ZM11 8.66H7V10H11V8.66ZM10 0.66H5.33C4.6 0.66 4 1.26 4 2L4 11.33C4 12.06 4.6 12.66 5.33 12.66H12.66C13.4 12.66 14 12.06 14 11.33V4.66L10 0.66ZM12.66 11.33H5.33V2H9.44L12.66 5.22V11.33Z\"\n fill=\"currentColor\" />\n </svg>\n </span>\n <span>Chapters List</span>\n </div>\n </li>\n }\n\n <!-- Divider Row for Quick Actions -->\n <!-- Divider Row for Quick Actions -->\n <li class=\"quick-actions-row\">\n @if (enableFontSize) {\n <div class=\"quick-action-btn\" (click)=\"changeFontSize('+')\">\n <span class=\"text-sm font-bold\">A+</span>\n </div>\n <div class=\"quick-action-btn\" (click)=\"changeFontSize('-')\">\n <span class=\"text-sm font-bold\">A-</span>\n </div>\n }\n @if (enableNotes) {\n <div class=\"quick-action-btn\" (click)=\"addNoteToPage(); isMenuOpen = false\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3 17.25V21H6.75L17.81 9.94L14.06 6.19L3 17.25ZM20.71 7.04C21.1 6.65 21.1 6.02 20.71 5.63L18.37 3.29C17.98 2.9 17.35 2.9 16.96 3.29L15.13 5.12L18.88 8.87L20.71 7.04Z\"\n fill=\"currentColor\" />\n </svg>\n </div>\n }\n @if (enableBookmarks) {\n <div class=\"quick-action-btn\" (click)=\"addBookMark(); isMenuOpen = false\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M17 3H7C5.9 3 5 3.9 5 5V21L12 18L19 21V5C19 3.9 18.1 3 17 3Z\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n }\n </li>\n </ul>\n </div>\n }\n\n <!-- Selection Menu Inside Footer Hub -->\n @if (freeSample === 'false') {\n @if (showHighlightOverlay) {\n <div class=\"custom-selection-toolbar selection-menu fade-in\">\n @if (enableNotes) {\n <div class=\"menu-item\" (click)=\"addNotes(); showHighlightOverlay = false\">\n <span class=\"menu-text\">Add Notes</span>\n </div>\n }\n @if (enableHighlights) {\n <div class=\"menu-item\" (click)=\"showhightLightColor = true; showHighlightOverlay = false\" title=\"Highlight\">\n <span class=\"menu-text\">Highlights</span>\n </div>\n }\n @if (enableHighlights) {\n <div class=\"menu-item\" (click)=\"addUnderline(); showHighlightOverlay = false\">\n <span class=\"menu-text\">Underline</span>\n </div>\n }\n @if (enableNotes || enableHighlights) {\n <!-- Definition often goes with these tools -->\n <div class=\"menu-item border-none\" (click)=\"openCommonPopup(4); showHighlightOverlay = false\">\n <span class=\"menu-text\">Definition</span>\n </div>\n }\n </div>\n }\n\n @if (showhightLightColor) {\n <div class=\"custom-selection-toolbar color-picker fade-in\">\n @for (color of colourCodeList; track color) {\n <div class=\"color-circle\" [style.background]=\"color\"\n (click)=\"addHighlight(color); showhightLightColor = false\"></div>\n }\n <button class=\"toolbar-btn close-colors\" (click)=\"showhightLightColor = false; showHighlightOverlay = true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M19 12H5\"></path>\n </svg>\n </button>\n </div>\n }\n }\n\n <!-- The Green Toggle Button -->\n <button class=\"menu-toggle-btn\" (click)=\"toggleAllMenus()\"\n [class.open]=\"isMenuOpen || showHighlightOverlay || showhightLightColor\">\n <!-- X Icon when open, Burger/Menu when closed -->\n @if (isMenuOpen || showHighlightOverlay || showhightLightColor) {\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n } @else {\n <!-- Menu Grid Icon -->\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6H20M4 12H20M4 18H20\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n }\n </button>\n </div>\n\n <!-- Next Button -->\n <button class=\"nav-btn next-btn\" (click)=\"nextClick()\" [class.ml-4]=\"true\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n</div>\n\n\n@if (showBookPageLoader) {\n<div class=\"fixed inset-0 z-[45] flex items-center justify-center bg-premium-loader fade-in\">\n <div class=\"text-center\">\n <div class=\"mb-8 relative inline-block\">\n <!-- Decorative Backdrop for Book -->\n <div class=\"absolute inset-0 bg-black/5 blur-2xl rounded-full transform scale-110\"></div>\n\n <!-- Larger, Premium Book Image -->\n <img [src]=\"coverImg ?? ''\" alt=\"Loading\"\n class=\"w-56 h-80 object-cover rounded-xl shadow-premium border-[6px] border-white relative z-10 animate-pulse\" />\n </div>\n\n <!-- Enhanced Loading Text Container -->\n <div class=\"flex flex-col items-center space-y-3\">\n <div class=\"flex items-center space-x-2 text-gray-400\">\n <span class=\"text-base font-medium\">Please wait a moment</span>\n <div class=\"flex space-x-1.5\">\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce\"></div>\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce [animation-delay:-0.15s]\"></div>\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce [animation-delay:-0.3s]\"></div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n@if (showOverlay) {\n<div class=\"screenshot-overlay\"></div>\n}\n\n<!-- Full-screen Preview End Modal -->\n@if (showPreviewModal) {\n<div class=\"fixed inset-0 z-40 bg-white dark:bg-gray-900 flex flex-col items-center justify-center text-center px-4\">\n <h2\n class=\"text-[1.375rem] sm:text-2xl font-medium leading-snug text-center text-gray-800 dark:text-white mb-6 max-w-xs sm:max-w-sm mx-auto\">\n You\u2019ve reached the end of the sample for\n </h2>\n\n <img [src]=\"coverImg ?? ''\" alt=\"Book Cover\" class=\"w-40 h-auto rounded-lg shadow-lg mb-6\" />\n</div>\n}\n\n\n<!-- Custom Chapter List Modal -->\n@if (showChapterList) {\n<div class=\"custom-modal-overlay fade-in\">\n <div class=\"custom-modal-content\">\n <app-chapterlist [chapterData]=\"chaptersData\" (chapterClick)=\"onChapterSelect($event)\"\n (closeDialog)=\"showChapterList = false\">\n </app-chapterlist>\n </div>\n</div>\n}", styles: [":host{--bg-primary: #ffffff;--bg-secondary: #f8fafc;--text-primary: #0f172a;--text-secondary: #475569;--border-base: #edf2f7;--shadow-base: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06);--accent-color: #34C759;--modal-bg: #ffffff;--modal-text: #0f172a}:host-context(.dark-mode){--bg-primary: rgb(32 33 32);--bg-secondary: rgb(42 43 42);--text-primary: #f8fafc;--text-secondary: #94a3b8;--border-base: #2d3748;--shadow-base: 0 10px 15px -3px rgba(0, 0, 0, .5);--accent-color: #32d74b;--modal-bg: rgb(32 33 32);--modal-text: #f9fafb}#reader{width:100%;height:100%}.no-select{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:default}.screenshot-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#fff;z-index:9999}img,[draggable=true]{-webkit-user-drag:none}::ng-deep *{-webkit-user-drag:none}::ng-deep .textLayer span{-webkit-user-drag:none;pointer-events:auto}.fade-in{animation:fadeIn .5s ease-in forwards}.fade-out{animation:fadeOut .5s ease-out forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.7}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media print{#viewer{display:none!important}body:before{content:\"Printing is disabled.\";font-size:24px;color:red;text-align:center;display:block;margin-top:100px}}.progress-container{position:relative;height:4px}.range-overlay{position:absolute;top:0;left:0;width:100%;z-index:10;background:transparent;cursor:pointer;-webkit-appearance:none;appearance:none;touch-action:none}.range-overlay::-webkit-slider-thumb{-webkit-appearance:none;height:14px;width:14px;margin-top:-5px;border-radius:50%;background:#0ea951;border:2px solid #ffffff;box-shadow:0 1px 3px #0003;transition:background .2s ease,transform .2s ease}.range-overlay::-webkit-slider-thumb:hover{background:#0cb14f;transform:scale(1.1)}.range-overlay::-webkit-slider-thumb:active{background:#0ba046;transform:scale(1.15)}.range-overlay::-webkit-slider-runnable-track{background:transparent;height:4px}.range-overlay::-moz-range-thumb{height:16px;width:16px;border-radius:50%;background:#0ea951;border:2px solid white}.range-overlay::-moz-range-track{background:transparent;height:4px}.range-overlay::-ms-thumb{height:16px;width:16px;border-radius:50%;background:#0ea951;border:2px solid white}.range-overlay::-ms-track{background:transparent;height:4px;border-color:transparent;color:transparent}#reader-container:after{content:\"\";position:absolute;top:13%;bottom:10%;left:50%;transform:translate(-50%);width:2px;background:linear-gradient(to bottom,#06030300,#0d080833,#0000);box-shadow:0 0 10px #0000001a;z-index:1}@media (max-width: 767px){#reader-container:after{display:none!important}}@media (max-width: 991px){#reader-container:after{display:none!important}}::ng-deep nav{box-shadow:none!important}::ng-deep .highlightandNotes .ngneat-dialog-content{width:510px!important;padding:24px}::ng-deep .highlightandNotes .ngneat-close-dialog{top:1.2rem}::ng-deep .highlightandNotes.dark-mode .ngneat-dialog-content{background-color:#333;color:#fff!important}::ng-deep .highlightandNotes.dark-mode .ngneat-close-dialog{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .ngneat-dialog-content{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .text-\\[\\#272C47\\]{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .text-black{color:#fff!important}::ng-deep .addandeditNotepopup .ngneat-dialog-content{width:690px!important}::ng-deep .crop-popup .ngneat-dialog-content{width:420px!important}:host,app-notes{background-color:var(--bg-primary);display:flex;width:100%;justify-content:center;transition:background-color .3s ease}#reader-container{width:100%;height:98vh;background-color:var(--bg-primary);padding-top:0;display:flex;flex-direction:column;overflow:hidden;transition:background-color .3s ease}#reader-content{flex:1;overflow:hidden;position:relative}#reader-footer{position:relative;width:60vw;margin:0 auto;padding:10px 38px 20px;background:var(--bg-primary);z-index:50;transition:background-color .3s ease}#reader-footer .footer-container{display:flex;justify-content:space-between;align-items:flex-end;gap:20px}#reader-footer .nav-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;cursor:pointer;transition:background .2s;background:transparent;border:none;color:var(--text-primary)}#reader-footer .nav-btn:hover{background:#f5f5f5}#reader-footer .nav-btn svg{width:20px;height:20px}#reader-footer .progress-section{flex:1;display:flex;flex-direction:column;align-items:center;max-width:600px;margin:0 auto;padding-bottom:5px}#reader-footer .progress-section .progress-label{font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:#666;margin-bottom:6px}#reader-footer .progress-section .progress-bar-container{position:relative;width:100%;height:14px;display:flex;align-items:center}#reader-footer .progress-section .progress-bar-container .progress-track{flex:1;height:4px;background:#e7ebeb;border-radius:2px;overflow:hidden;position:relative}#reader-footer .progress-section .progress-bar-container .progress-fill{height:100%;background:#34c759;transition:width .2s ease-out;border-radius:2px}#reader-footer .progress-section .progress-bar-container .progress-slider{position:absolute;width:100%;height:100%;opacity:0;cursor:pointer;top:0;left:0;z-index:2}#reader-footer .progress-section .progress-bar-container .progress-text{margin-left:12px;font-size:12px;font-weight:600;min-width:35px;color:var(--text-primary)}#reader-footer .right-controls{display:flex;align-items:center;gap:16px}#reader-footer .menu-toggle-btn{width:48px;height:48px;border-radius:50%;background:#34c759;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);box-shadow:0 4px 10px #34c7594d;border:none}#reader-footer .menu-toggle-btn.open{background:#34c759;transform:rotate(90deg)}#reader-footer .menu-toggle-btn:hover{transform:scale(1.05);background:#2ebd50}#reader-footer .menu-popup{position:absolute;bottom:70px;right:0;width:280px;background:var(--bg-primary);border-radius:16px;box-shadow:var(--shadow-base);padding:8px 0;z-index:100;border:1px solid var(--border-base);transform-origin:bottom right}#reader-footer .menu-popup .menu-list{list-style:none;padding:0;margin:0}#reader-footer .menu-popup .menu-list li{padding:0 8px;cursor:pointer}#reader-footer .menu-popup .menu-list .menu-item{display:flex;align-items:center;padding:12px;font-size:14px;font-weight:500;color:var(--text-primary);border-radius:8px;transition:background .1s}#reader-footer .menu-popup .menu-list .menu-item:hover{background:var(--bg-secondary)}#reader-footer .menu-popup .menu-list .menu-item .icon{width:32px;display:flex;align-items:center;justify-content:flex-start;color:var(--text-secondary)}#reader-footer .menu-popup .menu-list .menu-item .icon svg{width:18px;height:18px}#reader-footer .menu-popup .quick-actions-row{display:flex;justify-content:space-between;padding:12px 16px;margin-top:8px;border-top:1px solid #f0f0f0;gap:8px}#reader-footer .menu-popup .quick-actions-row .quick-action-btn{flex:1;height:40px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:var(--bg-secondary);cursor:pointer;color:var(--text-primary);transition:all .2s}#reader-footer .menu-popup .quick-actions-row .quick-action-btn:hover{background:var(--border-base)}.calibre{padding:0!important}.hightlight-overlay ::ng-deep .p-overlay{top:-232px!important}app-chapterlist ::ng-deep #reader-content{padding:0!important}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;backdrop-filter:blur(4px);z-index:200;display:flex;align-items:center;justify-content:center}.custom-modal-content{background:var(--modal-bg);color:var(--modal-text);width:90%;max-width:500px;border-radius:12px;box-shadow:var(--shadow-base);overflow:hidden;animation:modalEnter .2s ease-out;transition:background-color .3s ease,color .3s ease}@keyframes modalEnter{0%{opacity:0;transform:scale(.95) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}.animate-bounce{animation:bounce .6s infinite}.fixed{position:fixed}.inset-0{inset:0}.z-40{z-index:40}.z-45{z-index:45}.flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.text-center{text-align:center}.bg-white{background-color:#fff}.bg-white\\/95{background-color:#fffffff2!important}.bg-black\\/5{background-color:#0000000d}.bg-accent-color{background-color:var(--accent-color)}.bg-premium-loader{background:var(--bg-primary)}.blur-2xl{filter:blur(40px)}.transform{--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1}.relative{position:relative}.absolute{position:absolute}.inline-block{display:inline-block}.z-10{z-index:10}.mb-8{margin-bottom:2rem}.space-y-3>*+*{margin-top:.75rem}.space-x-1\\.5>*+*{margin-left:.375rem}.tracking-tight{letter-spacing:-.025em}.text-gray-800{color:#1f2937}.border-\\[6px\\]{border-width:6px}.backdrop-blur-sm{backdrop-filter:blur(4px)}.w-full{width:100%}.px-4{padding-left:1rem;padding-right:1rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-\\[-1\\.5rem\\]{margin-top:-1.5rem}.ml-1{margin-left:.25rem}.space-x-1>*+*{margin-left:.25rem}.space-x-2>*+*{margin-left:.5rem}.inline-flex{display:inline-flex}.text-gray-700{color:#374151}.text-gray-400{color:#9ca3af}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.w-40{width:10rem}.h-56{height:14rem}.w-56{width:14rem}.h-80{height:20rem}.w-32{width:8rem}.h-44{height:11rem}.object-cover{object-fit:cover}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.shadow-2xl{box-shadow:0 25px 50px -12px #00000040}.shadow-premium{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a,0 0 0 1px #0000000d}.mx-auto{margin-left:auto;margin-right:auto}.border-4{border-width:4px}.border-white{border-color:#fff}.border-gray-50{border-color:#f9fafb}.w-1\\.5{width:.375rem}.h-1\\.5{height:.375rem}.bg-gray-400{background-color:#9ca3af}.rounded-full{border-radius:9999px}.custom-selection-toolbar{position:absolute;bottom:70px;right:0;z-index:100;width:280px;background:var(--bg-primary);border-radius:16px;box-shadow:var(--shadow-base);display:flex;flex-direction:column;overflow:hidden;border:1px solid var(--border-base);padding:8px 0;transform-origin:bottom right}.custom-selection-toolbar .menu-item{padding:12px 20px;border-bottom:1px solid #f1f5f9;cursor:pointer;transition:all .2s ease;display:flex;align-items:center}.custom-selection-toolbar .menu-item:hover{background:#f8fafc}.custom-selection-toolbar .menu-item:hover .menu-text{color:var(--accent-color)}.custom-selection-toolbar .menu-item.border-none{border-bottom:none}.custom-selection-toolbar .menu-item .menu-text{font-size:15px;font-weight:500;color:#334155}.custom-selection-toolbar.color-picker{width:auto;flex-direction:row;padding:8px 12px;gap:12px;align-items:center}.custom-selection-toolbar.color-picker .color-circle{width:24px;height:24px;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0000001a;transition:transform .2s ease}.custom-selection-toolbar.color-picker .color-circle:hover{transform:scale(1.2)}.custom-selection-toolbar.color-picker .toolbar-btn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;border:none;background:#f1f5f9;color:#64748b;cursor:pointer;margin-left:4px}.custom-selection-toolbar.color-picker .toolbar-btn:hover{background:#e2e8f0}:host-context(.dark-mode) .custom-selection-toolbar{background:#1e293b;border-color:#334155}:host-context(.dark-mode) .custom-selection-toolbar .menu-item{border-bottom-color:#334155}:host-context(.dark-mode) .custom-selection-toolbar .menu-item:hover{background:#0f172a}:host-context(.dark-mode) .custom-selection-toolbar .menu-item .menu-text{color:#f1f5f9}:host-context(.dark-mode) .custom-selection-toolbar.color-picker .toolbar-btn{background:#334155;color:#f1f5f9}\n"] }]
2109
- }], ctorParameters: () => [{ type: i0.NgZone }, { type: HttpApiService }, { type: SharedService }, { type: EpubReaderService }, { type: i0.ChangeDetectorRef }, { type: i3.ActivatedRoute }, { type: CustomDialogService }, { type: i4.MessageService }, { type: i1$2.Location }, { type: Object, decorators: [{
2184
+ args: [{ selector: 'epub-flow', standalone: false, template: "<div id=\"reader-container\" [hidden]=\"showBookPageLoader || showDwndLoader\">\n <div id=\"reader-content\" style=\"overflow: hidden;\">\n <div id=\"reader\"></div>\n </div>\n\n <div id=\"reader-footer\">\n <div class=\"footer-container\">\n <!-- Left: Previous Button -->\n <button class=\"nav-btn prev-btn\" (click)=\"prevClick()\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n\n <!-- Center: Progress Bar -->\n <div class=\"progress-section\">\n <div class=\"progress-label\">Read Progress</div>\n <div class=\"progress-bar-container\">\n <div class=\"progress-track\">\n <div class=\"progress-fill\" [style.width.%]=\"readPercentage.roudedOff\"></div>\n </div>\n <input type=\"range\" class=\"progress-slider\" min=\"0\" max=\"100\" [value]=\"readPercentage.roudedOff\"\n (input)=\"onProgressChange($event)\" />\n <span class=\"progress-text\">{{ readPercentage.roudedOff }}%</span>\n </div>\n </div>\n\n <!-- Right: Menu Toggle & Next Button -->\n <div class=\"right-controls\">\n <!-- Menu Toggle Button (Green) -->\n <div class=\"menu-container relative\">\n <!-- The Menu Popup -->\n @if (isMenuOpen) {\n <div class=\"menu-popup fade-in\">\n <ul class=\"menu-list\">\n <!-- Dark Mode -->\n <!-- Dark Mode -->\n @if (enableDarkMode) {\n <li (click)=\"toggleDarkMode = !toggleDarkMode; darkMode()\">\n <div class=\"menu-item\">\n <span class=\"icon moon-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M13.5 10C12.7 10.3 11.9 10.5 11 10.5C7.4 10.5 4.5 7.6 4.5 4C4.5 3.1 4.7 2.3 5 1.5C2.7 2.5 1 4.8 1 7.5C1 11.1 3.9 14 7.5 14C10.2 14 12.5 12.3 13.5 10Z\"\n stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>{{ toggleDarkMode ? 'Light Mode' : 'Dark Mode' }}</span>\n </div>\n </li>\n }\n\n <!-- Highlights & Notes -->\n <!-- Highlights & Notes -->\n @if (enableHighlights || enableNotes) {\n <li (click)=\"openCommonPopup(1); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon notes-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M2 4H14M2 8H14M2 12H8\" stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>Highlights & Notes</span>\n </div>\n </li>\n }\n\n <!-- Search Book -->\n <!-- Search Book -->\n @if (enableSearch) {\n <li (click)=\"openCommonPopup(2); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon search-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M14 14L10.5 10.5M10.5 10.5C11.4 9.6 12 8.4 12 7C12 4.2 9.8 2 7 2C4.2 2 2 4.2 2 7C2 9.8 4.2 12 7 12C8.4 12 9.6 11.4 10.5 10.5Z\"\n stroke=\"currentColor\" stroke-width=\"1.5\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </span>\n <span>Search Book</span>\n </div>\n </li>\n }\n\n <!-- Bookmark List -->\n <!-- Bookmark List -->\n @if (enableBookmarks) {\n <li (click)=\"getBookMarkList(); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon bookmark-list-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 1.33H4C3.26 1.33 2.66 1.93 2.66 2.66V13.33C2.66 14.06 3.26 14.66 4 14.66H12C12.73 14.66 13.33 14.06 13.33 13.33V2.66C13.33 1.93 12.73 1.33 12 1.33ZM6 2.66H7.33V6L6.66 5.5L6 6V2.66ZM12 13.33H4V2.66H4.66V8.66L6.66 7.16L8.66 8.66V2.66H12V13.33Z\"\n fill=\"currentColor\" />\n </svg>\n </span>\n <span>Bookmark List</span>\n </div>\n </li>\n }\n\n <!-- Chapters List -->\n <!-- Chapters List -->\n @if (enableChapterList) {\n <li (click)=\"showChapterPopup(); isMenuOpen = false\">\n <div class=\"menu-item\">\n <span class=\"icon chapter-icon\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M12 15.33H2.66C1.93 15.33 1.33 14.73 1.33 14V4.66H2.66V14H12V15.33ZM11 8.66H7V10H11V8.66ZM10 0.66H5.33C4.6 0.66 4 1.26 4 2L4 11.33C4 12.06 4.6 12.66 5.33 12.66H12.66C13.4 12.66 14 12.06 14 11.33V4.66L10 0.66ZM12.66 11.33H5.33V2H9.44L12.66 5.22V11.33Z\"\n fill=\"currentColor\" />\n </svg>\n </span>\n <span>Chapters List</span>\n </div>\n </li>\n }\n\n <!-- Divider Row for Quick Actions -->\n <!-- Divider Row for Quick Actions -->\n <li class=\"quick-actions-row\">\n @if (enableFontSize) {\n <div class=\"quick-action-btn\" (click)=\"changeFontSize('+')\">\n <span class=\"text-sm font-bold\">A+</span>\n </div>\n <div class=\"quick-action-btn\" (click)=\"changeFontSize('-')\">\n <span class=\"text-sm font-bold\">A-</span>\n </div>\n }\n @if (enableNotes) {\n <div class=\"quick-action-btn\" (click)=\"addNoteToPage(); isMenuOpen = false\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path\n d=\"M3 17.25V21H6.75L17.81 9.94L14.06 6.19L3 17.25ZM20.71 7.04C21.1 6.65 21.1 6.02 20.71 5.63L18.37 3.29C17.98 2.9 17.35 2.9 16.96 3.29L15.13 5.12L18.88 8.87L20.71 7.04Z\"\n fill=\"currentColor\" />\n </svg>\n </div>\n }\n @if (enableBookmarks) {\n <div class=\"quick-action-btn\" (click)=\"addBookMark(); isMenuOpen = false\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M17 3H7C5.9 3 5 3.9 5 5V21L12 18L19 21V5C19 3.9 18.1 3 17 3Z\" fill=\"none\"\n stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" />\n </svg>\n </div>\n }\n </li>\n </ul>\n </div>\n }\n\n <!-- Selection Menu Inside Footer Hub -->\n @if (freeSample === 'false') {\n @if (showHighlightOverlay) {\n <div class=\"custom-selection-toolbar selection-menu fade-in\">\n @if (enableNotes) {\n <div class=\"menu-item\" (click)=\"addNotes(); showHighlightOverlay = false\">\n <span class=\"menu-text\">Add Notes</span>\n </div>\n }\n @if (enableHighlights) {\n <div class=\"menu-item\" (click)=\"showhightLightColor = true; showHighlightOverlay = false\" title=\"Highlight\">\n <span class=\"menu-text\">Highlights</span>\n </div>\n }\n @if (enableHighlights) {\n <div class=\"menu-item\" (click)=\"addUnderline(); showHighlightOverlay = false\">\n <span class=\"menu-text\">Underline</span>\n </div>\n }\n @if (enableNotes || enableHighlights) {\n <!-- Definition often goes with these tools -->\n <div class=\"menu-item border-none\" (click)=\"openCommonPopup(4); showHighlightOverlay = false\">\n <span class=\"menu-text\">Definition</span>\n </div>\n }\n </div>\n }\n\n @if (showhightLightColor) {\n <div class=\"custom-selection-toolbar color-picker fade-in\">\n @for (color of colourCodeList; track color) {\n <div class=\"color-circle\" [style.background]=\"color\"\n (click)=\"addHighlight(color); showhightLightColor = false\"></div>\n }\n <button class=\"toolbar-btn close-colors\" (click)=\"showhightLightColor = false; showHighlightOverlay = true\">\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\">\n <path d=\"M19 12H5\"></path>\n </svg>\n </button>\n </div>\n }\n }\n\n <!-- The Green Toggle Button -->\n <button class=\"menu-toggle-btn\" (click)=\"toggleAllMenus()\"\n [class.open]=\"isMenuOpen || showHighlightOverlay || showhightLightColor\">\n <!-- X Icon when open, Burger/Menu when closed -->\n @if (isMenuOpen || showHighlightOverlay || showhightLightColor) {\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M18 6L6 18M6 6L18 18\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n } @else {\n <!-- Menu Grid Icon -->\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M4 6H20M4 12H20M4 18H20\" stroke=\"white\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n }\n </button>\n </div>\n\n <!-- Next Button -->\n <button class=\"nav-btn next-btn\" (click)=\"nextClick()\" [class.ml-4]=\"true\">\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\n <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\n stroke-linejoin=\"round\" />\n </svg>\n </button>\n </div>\n </div>\n </div>\n</div>\n\n\n@if (showBookPageLoader) {\n<div class=\"fixed inset-0 z-[45] flex items-center justify-center bg-premium-loader fade-in\">\n <div class=\"text-center\">\n <div class=\"mb-8 relative inline-block\">\n <!-- Decorative Backdrop for Book -->\n <div class=\"absolute inset-0 bg-black/5 blur-2xl rounded-full transform scale-110\"></div>\n\n <!-- Larger, Premium Book Image -->\n <img [src]=\"coverImg ?? ''\" alt=\"Loading\"\n class=\"w-56 h-80 object-cover rounded-xl shadow-premium border-[6px] border-white relative z-10 animate-pulse\" />\n </div>\n\n <!-- Enhanced Loading Text Container -->\n <div class=\"flex flex-col items-center space-y-3\">\n <div class=\"flex items-center space-x-2 text-gray-400\">\n <span class=\"text-base font-medium\">Please wait a moment</span>\n <div class=\"flex space-x-1.5\">\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce\"></div>\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce [animation-delay:-0.15s]\"></div>\n <div class=\"w-1.5 h-1.5 bg-accent-color rounded-full animate-bounce [animation-delay:-0.3s]\"></div>\n </div>\n </div>\n </div>\n </div>\n</div>\n}\n@if (showOverlay) {\n<div class=\"screenshot-overlay\"></div>\n}\n\n<!-- Full-screen Preview End Modal -->\n@if (showPreviewModal) {\n<div class=\"fixed inset-0 z-40 bg-white dark:bg-gray-900 flex flex-col items-center justify-center text-center px-4\">\n <h2\n class=\"text-[1.375rem] sm:text-2xl font-medium leading-snug text-center text-gray-800 dark:text-white mb-6 max-w-xs sm:max-w-sm mx-auto\">\n You\u2019ve reached the end of the sample for\n </h2>\n\n <img [src]=\"coverImg ?? ''\" alt=\"Book Cover\" class=\"w-40 h-auto rounded-lg shadow-lg mb-6\" />\n</div>\n}\n\n\n<!-- Custom Chapter List Modal -->\n@if (showChapterList) {\n<div class=\"custom-modal-overlay fade-in\">\n <div class=\"custom-modal-content\">\n <app-chapterlist [chapterData]=\"chaptersData\" (chapterClick)=\"onChapterSelect($event)\"\n (closeDialog)=\"showChapterList = false\">\n </app-chapterlist>\n </div>\n</div>\n}\n<epub-notification-toast></epub-notification-toast>", styles: [":host{--bg-primary: #ffffff;--bg-secondary: #f8fafc;--text-primary: #0f172a;--text-secondary: #475569;--border-base: #edf2f7;--shadow-base: 0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06);--accent-color: #34C759;--modal-bg: #ffffff;--modal-text: #0f172a}:host-context(.dark-mode){--bg-primary: rgb(32 33 32);--bg-secondary: rgb(42 43 42);--text-primary: #f8fafc;--text-secondary: #94a3b8;--border-base: #2d3748;--shadow-base: 0 10px 15px -3px rgba(0, 0, 0, .5);--accent-color: #32d74b;--modal-bg: rgb(32 33 32);--modal-text: #f9fafb}#reader{width:100%;height:100%}.no-select{user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;cursor:default}.screenshot-overlay{position:fixed;top:0;left:0;width:100vw;height:100vh;background-color:#fff;z-index:9999}img,[draggable=true]{-webkit-user-drag:none}::ng-deep *{-webkit-user-drag:none}::ng-deep .textLayer span{-webkit-user-drag:none;pointer-events:auto}.fade-in{animation:fadeIn .5s ease-in forwards}.fade-out{animation:fadeOut .5s ease-out forwards}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes pulse{0%,to{opacity:1}50%{opacity:.7}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@media print{#viewer{display:none!important}body:before{content:\"Printing is disabled.\";font-size:24px;color:red;text-align:center;display:block;margin-top:100px}}.progress-container{position:relative;height:4px}.range-overlay{position:absolute;top:0;left:0;width:100%;z-index:10;background:transparent;cursor:pointer;-webkit-appearance:none;appearance:none;touch-action:none}.range-overlay::-webkit-slider-thumb{-webkit-appearance:none;height:14px;width:14px;margin-top:-5px;border-radius:50%;background:#0ea951;border:2px solid #ffffff;box-shadow:0 1px 3px #0003;transition:background .2s ease,transform .2s ease}.range-overlay::-webkit-slider-thumb:hover{background:#0cb14f;transform:scale(1.1)}.range-overlay::-webkit-slider-thumb:active{background:#0ba046;transform:scale(1.15)}.range-overlay::-webkit-slider-runnable-track{background:transparent;height:4px}.range-overlay::-moz-range-thumb{height:16px;width:16px;border-radius:50%;background:#0ea951;border:2px solid white}.range-overlay::-moz-range-track{background:transparent;height:4px}.range-overlay::-ms-thumb{height:16px;width:16px;border-radius:50%;background:#0ea951;border:2px solid white}.range-overlay::-ms-track{background:transparent;height:4px;border-color:transparent;color:transparent}#reader-container:after{content:\"\";position:absolute;top:13%;bottom:10%;left:50%;transform:translate(-50%);width:2px;background:linear-gradient(to bottom,#06030300,#0d080833,#0000);box-shadow:0 0 10px #0000001a;z-index:1}@media (max-width: 767px){#reader-container:after{display:none!important}}@media (max-width: 991px){#reader-container:after{display:none!important}}::ng-deep nav{box-shadow:none!important}::ng-deep .highlightandNotes .ngneat-dialog-content{width:510px!important;padding:24px}::ng-deep .highlightandNotes .ngneat-close-dialog{top:1.2rem}::ng-deep .highlightandNotes.dark-mode .ngneat-dialog-content{background-color:#333;color:#fff!important}::ng-deep .highlightandNotes.dark-mode .ngneat-close-dialog{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .ngneat-dialog-content{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .text-\\[\\#272C47\\]{color:#fff!important}::ng-deep .highlightandNotes.dark-mode .text-black{color:#fff!important}::ng-deep .addandeditNotepopup .ngneat-dialog-content{width:690px!important}::ng-deep .crop-popup .ngneat-dialog-content{width:420px!important}:host,app-notes{background-color:var(--bg-primary);display:flex;width:100%;justify-content:center;transition:background-color .3s ease}#reader-container{width:100%;height:98vh;background-color:var(--bg-primary);padding-top:0;display:flex;flex-direction:column;overflow:hidden;transition:background-color .3s ease}#reader-content{flex:1;overflow:hidden;position:relative}#reader-footer{position:relative;width:60vw;margin:0 auto;padding:10px 38px 20px;background:var(--bg-primary);z-index:50;transition:background-color .3s ease}#reader-footer .footer-container{display:flex;justify-content:space-between;align-items:flex-end;gap:20px}#reader-footer .nav-btn{display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:50%;cursor:pointer;transition:background .2s;background:transparent;border:none;color:var(--text-primary)}#reader-footer .nav-btn:hover{background:#f5f5f5}#reader-footer .nav-btn svg{width:20px;height:20px}#reader-footer .progress-section{flex:1;display:flex;flex-direction:column;align-items:center;max-width:600px;margin:0 auto;padding-bottom:5px}#reader-footer .progress-section .progress-label{font-size:11px;font-weight:500;text-transform:uppercase;letter-spacing:.5px;color:#666;margin-bottom:6px}#reader-footer .progress-section .progress-bar-container{position:relative;width:100%;height:14px;display:flex;align-items:center}#reader-footer .progress-section .progress-bar-container .progress-track{flex:1;height:4px;background:#e7ebeb;border-radius:2px;overflow:hidden;position:relative}#reader-footer .progress-section .progress-bar-container .progress-fill{height:100%;background:#34c759;transition:width .2s ease-out;border-radius:2px}#reader-footer .progress-section .progress-bar-container .progress-slider{position:absolute;width:100%;height:100%;opacity:0;cursor:pointer;top:0;left:0;z-index:2}#reader-footer .progress-section .progress-bar-container .progress-text{margin-left:12px;font-size:12px;font-weight:600;min-width:35px;color:var(--text-primary)}#reader-footer .right-controls{display:flex;align-items:center;gap:16px}#reader-footer .menu-toggle-btn{width:48px;height:48px;border-radius:50%;background:#34c759;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .3s cubic-bezier(.4,0,.2,1);box-shadow:0 4px 10px #34c7594d;border:none}#reader-footer .menu-toggle-btn.open{background:#34c759;transform:rotate(90deg)}#reader-footer .menu-toggle-btn:hover{transform:scale(1.05);background:#2ebd50}#reader-footer .menu-popup{position:absolute;bottom:70px;right:0;width:280px;background:var(--bg-primary);border-radius:16px;box-shadow:var(--shadow-base);padding:8px 0;z-index:100;border:1px solid var(--border-base);transform-origin:bottom right}#reader-footer .menu-popup .menu-list{list-style:none;padding:0;margin:0}#reader-footer .menu-popup .menu-list li{padding:0 8px;cursor:pointer}#reader-footer .menu-popup .menu-list .menu-item{display:flex;align-items:center;padding:12px;font-size:14px;font-weight:500;color:var(--text-primary);border-radius:8px;transition:background .1s}#reader-footer .menu-popup .menu-list .menu-item:hover{background:var(--bg-secondary)}#reader-footer .menu-popup .menu-list .menu-item .icon{width:32px;display:flex;align-items:center;justify-content:flex-start;color:var(--text-secondary)}#reader-footer .menu-popup .menu-list .menu-item .icon svg{width:18px;height:18px}#reader-footer .menu-popup .quick-actions-row{display:flex;justify-content:space-between;padding:12px 16px;margin-top:8px;border-top:1px solid #f0f0f0;gap:8px}#reader-footer .menu-popup .quick-actions-row .quick-action-btn{flex:1;height:40px;display:flex;align-items:center;justify-content:center;border-radius:8px;background:var(--bg-secondary);cursor:pointer;color:var(--text-primary);transition:all .2s}#reader-footer .menu-popup .quick-actions-row .quick-action-btn:hover{background:var(--border-base)}.calibre{padding:0!important}.hightlight-overlay ::ng-deep .p-overlay{top:-232px!important}app-chapterlist ::ng-deep #reader-content{padding:0!important}.custom-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:#0006;backdrop-filter:blur(4px);z-index:200;display:flex;align-items:center;justify-content:center}.custom-modal-content{background:var(--modal-bg);color:var(--modal-text);width:90%;max-width:500px;border-radius:12px;box-shadow:var(--shadow-base);overflow:hidden;animation:modalEnter .2s ease-out;transition:background-color .3s ease,color .3s ease}@keyframes modalEnter{0%{opacity:0;transform:scale(.95) translateY(10px)}to{opacity:1;transform:scale(1) translateY(0)}}@keyframes bounce{0%,to{transform:translateY(0)}50%{transform:translateY(-4px)}}.animate-bounce{animation:bounce .6s infinite}.fixed{position:fixed}.inset-0{inset:0}.z-40{z-index:40}.z-45{z-index:45}.flex{display:flex}.items-center{align-items:center}.justify-center{justify-content:center}.text-center{text-align:center}.bg-white{background-color:#fff}.bg-white\\/95{background-color:#fffffff2!important}.bg-black\\/5{background-color:#0000000d}.bg-accent-color{background-color:var(--accent-color)}.bg-premium-loader{background:var(--bg-primary)}.blur-2xl{filter:blur(40px)}.transform{--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x)) translateY(var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-110{--tw-scale-x: 1.1;--tw-scale-y: 1.1}.relative{position:relative}.absolute{position:absolute}.inline-block{display:inline-block}.z-10{z-index:10}.mb-8{margin-bottom:2rem}.space-y-3>*+*{margin-top:.75rem}.space-x-1\\.5>*+*{margin-left:.375rem}.tracking-tight{letter-spacing:-.025em}.text-gray-800{color:#1f2937}.border-\\[6px\\]{border-width:6px}.backdrop-blur-sm{backdrop-filter:blur(4px)}.w-full{width:100%}.px-4{padding-left:1rem;padding-right:1rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-\\[-1\\.5rem\\]{margin-top:-1.5rem}.ml-1{margin-left:.25rem}.space-x-1>*+*{margin-left:.25rem}.space-x-2>*+*{margin-left:.5rem}.inline-flex{display:inline-flex}.text-gray-700{color:#374151}.text-gray-400{color:#9ca3af}.text-lg{font-size:1.125rem}.text-xl{font-size:1.25rem}.font-medium{font-weight:500}.font-semibold{font-weight:600}.w-40{width:10rem}.h-56{height:14rem}.w-56{width:14rem}.h-80{height:20rem}.w-32{width:8rem}.h-44{height:11rem}.object-cover{object-fit:cover}.rounded-lg{border-radius:.5rem}.rounded-xl{border-radius:.75rem}.shadow-2xl{box-shadow:0 25px 50px -12px #00000040}.shadow-premium{box-shadow:0 20px 25px -5px #0000001a,0 10px 10px -5px #0000000a,0 0 0 1px #0000000d}.mx-auto{margin-left:auto;margin-right:auto}.border-4{border-width:4px}.border-white{border-color:#fff}.border-gray-50{border-color:#f9fafb}.w-1\\.5{width:.375rem}.h-1\\.5{height:.375rem}.bg-gray-400{background-color:#9ca3af}.rounded-full{border-radius:9999px}.custom-selection-toolbar{position:absolute;bottom:70px;right:0;z-index:100;width:280px;background:var(--bg-primary);border-radius:16px;box-shadow:var(--shadow-base);display:flex;flex-direction:column;overflow:hidden;border:1px solid var(--border-base);padding:8px 0;transform-origin:bottom right}.custom-selection-toolbar .menu-item{padding:12px 20px;border-bottom:1px solid #f1f5f9;cursor:pointer;transition:all .2s ease;display:flex;align-items:center}.custom-selection-toolbar .menu-item:hover{background:#f8fafc}.custom-selection-toolbar .menu-item:hover .menu-text{color:var(--accent-color)}.custom-selection-toolbar .menu-item.border-none{border-bottom:none}.custom-selection-toolbar .menu-item .menu-text{font-size:15px;font-weight:500;color:#334155}.custom-selection-toolbar.color-picker{width:auto;flex-direction:row;padding:8px 12px;gap:12px;align-items:center}.custom-selection-toolbar.color-picker .color-circle{width:24px;height:24px;border-radius:50%;cursor:pointer;border:2px solid white;box-shadow:0 2px 4px #0000001a;transition:transform .2s ease}.custom-selection-toolbar.color-picker .color-circle:hover{transform:scale(1.2)}.custom-selection-toolbar.color-picker .toolbar-btn{display:flex;align-items:center;justify-content:center;width:30px;height:30px;border-radius:50%;border:none;background:#f1f5f9;color:#64748b;cursor:pointer;margin-left:4px}.custom-selection-toolbar.color-picker .toolbar-btn:hover{background:#e2e8f0}:host-context(.dark-mode) .custom-selection-toolbar{background:#1e293b;border-color:#334155}:host-context(.dark-mode) .custom-selection-toolbar .menu-item{border-bottom-color:#334155}:host-context(.dark-mode) .custom-selection-toolbar .menu-item:hover{background:#0f172a}:host-context(.dark-mode) .custom-selection-toolbar .menu-item .menu-text{color:#f1f5f9}:host-context(.dark-mode) .custom-selection-toolbar.color-picker .toolbar-btn{background:#334155;color:#f1f5f9}\n"] }]
2185
+ }], ctorParameters: () => [{ type: i0.NgZone }, { type: HttpApiService }, { type: SharedService }, { type: EpubReaderService }, { type: i0.ChangeDetectorRef }, { type: i3.ActivatedRoute }, { type: CustomDialogService }, { type: NotificationService }, { type: i1$2.Location }, { type: Object, decorators: [{
2110
2186
  type: Inject,
2111
2187
  args: [PLATFORM_ID]
2112
2188
  }] }, { type: i3.Router }, { type: i1$1.Overlay }], propDecorators: { epubUrl: [{
@@ -2133,6 +2209,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
2133
2209
  type: Input
2134
2210
  }], underlineRemoveRequest: [{
2135
2211
  type: Output
2212
+ }], bookId: [{
2213
+ type: Input
2136
2214
  }], handleKeyUp: [{
2137
2215
  type: HostListener,
2138
2216
  args: ['document:keyup', ['$event']]
@@ -2144,7 +2222,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
2144
2222
  class EpubLoaderComponent {
2145
2223
  loadPercentage = input(null);
2146
2224
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EpubLoaderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
2147
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.17", type: EpubLoaderComponent, isStandalone: false, selector: "app-epub-loader", inputs: { loadPercentage: { classPropertyName: "loadPercentage", publicName: "loadPercentage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"page-loader\">\n <div class=\"flex flex-col w-full loader-container\">\n <div class=\"text-black text-2xl font-bold mb-2\">Reader Loading</div>\n <p-progressBar\n [value]=\"loadPercentage()\"\n class=\"reader-progress w-full\"\n />\n <div class=\"text-percentage text-base font-normal inline-flex m-auto mt-3\">\n {{ loadPercentage() ? loadPercentage() : '0' }}\n </div>\n </div>\n</div>\n", styles: [".page-loader{position:fixed;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;top:0;background:#fff;z-index:99}.page-loader .loader-container{max-width:80%}@media (min-width: 768px){.page-loader .loader-container{max-width:410px}}\n"], dependencies: [{ kind: "component", type: i1$4.ProgressBar, selector: "p-progressBar", inputs: ["value", "showValue", "styleClass", "style", "unit", "mode", "color"] }] });
2225
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.2.17", type: EpubLoaderComponent, isStandalone: false, selector: "app-epub-loader", inputs: { loadPercentage: { classPropertyName: "loadPercentage", publicName: "loadPercentage", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"page-loader\">\n <div class=\"flex flex-col w-full loader-container\">\n <div class=\"text-black text-2xl font-bold mb-2\">Reader Loading</div>\n <p-progressBar\n [value]=\"loadPercentage()\"\n class=\"reader-progress w-full\"\n />\n <div class=\"text-percentage text-base font-normal inline-flex m-auto mt-3\">\n {{ loadPercentage() ? loadPercentage() : '0' }}\n </div>\n </div>\n</div>\n", styles: [".page-loader{position:fixed;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center;top:0;background:#fff;z-index:99}.page-loader .loader-container{max-width:80%}@media (min-width: 768px){.page-loader .loader-container{max-width:410px}}\n"] });
2148
2226
  }
2149
2227
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EpubLoaderComponent, decorators: [{
2150
2228
  type: Component,
@@ -2171,18 +2249,17 @@ class EpubReaderModule {
2171
2249
  EpubLoaderComponent], imports: [CommonModule, i3.RouterModule, NgxEditorModule,
2172
2250
  FormsModule,
2173
2251
  ReactiveFormsModule,
2174
- TabViewModule,
2175
- ProgressBarModule,
2176
- TableModule,
2177
- ButtonModule,
2252
+ ReactiveFormsModule,
2178
2253
  NoDataFoundComponent,
2179
2254
  HttpClientModule,
2180
- SkeletonLoaderComponent], exports: [ReaderMainComponent,
2255
+ SkeletonLoaderComponent,
2256
+ NotificationToastComponent], exports: [ReaderMainComponent,
2181
2257
  AddNotesComponent,
2182
2258
  EpubCommonPopupComponent,
2183
2259
  ChapterlistComponent,
2184
2260
  EpubLoaderComponent,
2185
- SkeletonLoaderComponent] });
2261
+ SkeletonLoaderComponent,
2262
+ NotificationToastComponent] });
2186
2263
  static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EpubReaderModule, providers: [
2187
2264
  CustomDialogService,
2188
2265
  EpubReaderService
@@ -2191,13 +2268,11 @@ class EpubReaderModule {
2191
2268
  NgxEditorModule,
2192
2269
  FormsModule,
2193
2270
  ReactiveFormsModule,
2194
- TabViewModule,
2195
- ProgressBarModule,
2196
- TableModule,
2197
- ButtonModule,
2271
+ ReactiveFormsModule,
2198
2272
  NoDataFoundComponent,
2199
2273
  HttpClientModule,
2200
- SkeletonLoaderComponent] });
2274
+ SkeletonLoaderComponent,
2275
+ NotificationToastComponent] });
2201
2276
  }
2202
2277
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImport: i0, type: EpubReaderModule, decorators: [{
2203
2278
  type: NgModule,
@@ -2215,13 +2290,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
2215
2290
  NgxEditorModule,
2216
2291
  FormsModule,
2217
2292
  ReactiveFormsModule,
2218
- TabViewModule,
2219
- ProgressBarModule,
2220
- TableModule,
2221
- ButtonModule,
2293
+ ReactiveFormsModule,
2222
2294
  NoDataFoundComponent,
2223
2295
  HttpClientModule,
2224
2296
  SkeletonLoaderComponent,
2297
+ NotificationToastComponent,
2225
2298
  ],
2226
2299
  providers: [
2227
2300
  CustomDialogService,
@@ -2233,7 +2306,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
2233
2306
  EpubCommonPopupComponent,
2234
2307
  ChapterlistComponent,
2235
2308
  EpubLoaderComponent,
2236
- SkeletonLoaderComponent
2309
+ SkeletonLoaderComponent,
2310
+ NotificationToastComponent
2237
2311
  ],
2238
2312
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
2239
2313
  }]
@@ -2245,5 +2319,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.17", ngImpo
2245
2319
  * Generated bundle index. Do not edit.
2246
2320
  */
2247
2321
 
2248
- export { AddNotesComponent, ChapterlistComponent, EpubCommonPopupComponent, EpubLoaderComponent, EpubReaderModule, EpubReaderService, ReaderMainComponent, SkeletonLoaderComponent };
2322
+ export { AddNotesComponent, ChapterlistComponent, EpubCommonPopupComponent, EpubLoaderComponent, EpubReaderModule, EpubReaderService, NotificationService, NotificationToastComponent, ReaderMainComponent, SkeletonLoaderComponent };
2249
2323
  //# sourceMappingURL=epub-flow.mjs.map