UNPKG

@hmcts/annotation-ui-lib

Version:

PDF Viewer and ability to highlight text with and comment tracking

2,776 lines 96.2 kB
import { v4 } from 'uuid';
import { isPlatformServer, CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { __awaiter } from 'tslib';
import { WINDOW, NgtUniversalModule } from '@ng-toolkit/universal';
import { Injectable, Inject, PLATFORM_ID, Component, ViewChildren, Input, Output, EventEmitter, ViewChild, ChangeDetectorRef, Renderer2, ComponentFactoryResolver, Injector, ApplicationRef, Directive, ViewContainerRef, NgModule, defineInjectable, inject } from '@angular/core';
import { HttpClient, HttpErrorResponse, HttpClientModule } from '@angular/common/http';
import { BehaviorSubject, Subject, of, throwError } from 'rxjs';
import { TransferState, makeStateKey } from '@angular/platform-browser';
import { tap, catchError, map } from 'rxjs/operators';

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class Comment {
    /**
     * @param {?} id
     * @param {?} annotationId
     * @param {?} createdBy
     * @param {?} createdByDetails
     * @param {?} createdDate
     * @param {?} lastModifiedBy
     * @param {?} lastModifiedByDetails
     * @param {?} lastModifiedDate
     * @param {?} content
     */
    constructor(id, annotationId, createdBy, createdByDetails, createdDate, lastModifiedBy, lastModifiedByDetails, lastModifiedDate, content) {
        this.id = id;
        this.annotationId = annotationId;
        this.createdBy = createdBy;
        this.createdByDetails = createdByDetails;
        this.createdDate = createdDate;
        this.lastModifiedBy = lastModifiedBy;
        this.lastModifiedByDetails = lastModifiedByDetails;
        this.lastModifiedDate = lastModifiedDate;
        this.content = content;
    }
}
class Annotation {
    /**
     * @param {?=} id
     * @param {?=} annotationSetId
     * @param {?=} createdBy
     * @param {?=} createdDate
     * @param {?=} createdByDetails
     * @param {?=} lastModifiedBy
     * @param {?=} lastModifiedByDetails
     * @param {?=} lastModifiedDate
     * @param {?=} documentId
     * @param {?=} page
     * @param {?=} color
     * @param {?=} comments
     * @param {?=} rectangles
     * @param {?=} type
     */
    constructor(id, annotationSetId, createdBy, createdDate, createdByDetails, lastModifiedBy, lastModifiedByDetails, lastModifiedDate, documentId, page, color, comments, rectangles, type) {
        this.id = id;
        this.annotationSetId = annotationSetId;
        this.createdBy = createdBy;
        this.createdDate = createdDate;
        this.createdByDetails = createdByDetails;
        this.lastModifiedBy = lastModifiedBy;
        this.lastModifiedByDetails = lastModifiedByDetails;
        this.lastModifiedDate = lastModifiedDate;
        this.documentId = documentId;
        this.page = page;
        this.color = color;
        this.comments = comments;
        this.rectangles = rectangles;
        this.type = type;
    }
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class PdfAnnotateWrapper {
    /**
     * @param {?} pageNumber
     * @return {?}
     */
    createPage(pageNumber) {
        return PDFAnnotate.UI.createPage(pageNumber);
    }
    /**
     * @param {?} pageNumber
     * @param {?} RENDER_OPTIONS
     * @return {?}
     */
    renderPage(pageNumber, RENDER_OPTIONS) {
        return PDFAnnotate.UI.renderPage(pageNumber, RENDER_OPTIONS);
    }
    /**
     * @param {?} type
     * @return {?}
     */
    enableRect(type) {
        PDFAnnotate.UI.enableRect(type);
    }
    /**
     * @return {?}
     */
    disableRect() {
        PDFAnnotate.UI.disableRect();
    }
    /**
     * @param {?=} storeAdapter
     * @return {?}
     */
    setStoreAdapter(storeAdapter) {
        if (storeAdapter) {
            PDFAnnotate.setStoreAdapter(storeAdapter);
        }
        else {
            PDFAnnotate.setStoreAdapter(new PDFAnnotate.LocalStoreAdapter());
        }
    }
    /**
     * @return {?}
     */
    getStoreAdapter() {
        return PDFAnnotate.getStoreAdapter();
    }
    /**
     * @return {?}
     */
    getUi() {
        return PDFAnnotate.UI;
    }
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class EmLoggerService {
    /**
     * @param {?} loggingClass
     * @return {?}
     */
    setClass(loggingClass) {
        this.loggingClass = loggingClass;
    }
    /**
     * @param {?} message
     * @return {?}
     */
    error(message) {
        this.buildLog('error-' + JSON.stringify(message));
    }
    /**
     * @param {?} message
     * @return {?}
     */
    info(message) {
        this.buildLog('info-' + JSON.stringify(message));
    }
    /**
     * @param {?} message
     * @return {?}
     */
    buildLog(message) {
        console.log(`${this.loggingClass}-${message}`);
    }
}
EmLoggerService.decorators = [
    { type: Injectable }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class PdfService {
    /**
     * @param {?} log
     * @param {?} pdfAnnotateWrapper
     */
    constructor(log, pdfAnnotateWrapper) {
        this.log = log;
        this.pdfAnnotateWrapper = pdfAnnotateWrapper;
        log.setClass('PdfService');
    }
    /**
     * @return {?}
     */
    preRun() {
        this.pageNumber = new BehaviorSubject(1);
    }
    /**
     * @return {?}
     */
    getAnnotationWrapper() {
        return this.annotationWrapper;
    }
    /**
     * @param {?} annotationWrapper
     * @return {?}
     */
    setAnnotationWrapper(annotationWrapper) {
        this.annotationWrapper = annotationWrapper;
    }
    /**
     * @return {?}
     */
    getPageNumber() {
        return this.pageNumber;
    }
    /**
     * @param {?} pageNumber
     * @return {?}
     */
    setPageNumber(pageNumber) {
        this.pageNumber.next(pageNumber);
    }
    /**
     * @return {?}
     */
    setHighlightTool() {
        this.log.info('Highlight cursor is enabled');
        this.pdfAnnotateWrapper.enableRect('highlight');
    }
    /**
     * @return {?}
     */
    setCursorTool() {
        this.pdfAnnotateWrapper.disableRect();
    }
}
PdfService.decorators = [
    { type: Injectable }
];
PdfService.ctorParameters = () => [
    { type: EmLoggerService },
    { type: PdfAnnotateWrapper }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class Utils {
    /**
     * @param {?} rectangles
     * @return {?}
     */
    buildLineRectangle(rectangles) {
        this.sortByY(rectangles);
        /** @type {?} */
        const lowestY = rectangles[0].y;
        /** @type {?} */
        const lineHeight = rectangles[0].height;
        this.sortByX(rectangles);
        /** @type {?} */
        const lowestX = rectangles[0].x;
        /** @type {?} */
        const upperX = rectangles[rectangles.length - 1].x;
        /** @type {?} */
        const width = rectangles[rectangles.length - 1].width;
        /** @type {?} */
        const rectangle = {
            y: lowestY,
            x: lowestX,
            width: (upperX - lowestX) + width,
            height: lineHeight
        };
        return rectangle;
    }
    /**
     * @param {?} annotationRectangles
     * @param {?} generatedRectangles
     * @return {?}
     */
    generateRectanglePerLine(annotationRectangles, generatedRectangles) {
        this.sortByY(annotationRectangles);
        /** @type {?} */
        const highestY = annotationRectangles[annotationRectangles.length - 1].y;
        /** @type {?} */
        const lowestY = annotationRectangles[0].y;
        /** @type {?} */
        const lineHeight = this.getAnnotationLineHeight(annotationRectangles);
        if (this.difference(highestY, lowestY) > lineHeight) {
            /** @type {?} */
            const currentLineRectangles = annotationRectangles.filter(rectangle => rectangle.y <= (lowestY + lineHeight));
            /** @type {?} */
            const nextLineRectangles = annotationRectangles.filter(rectangle => rectangle.y > (lowestY + lineHeight));
            generatedRectangles.push(this.buildLineRectangle(currentLineRectangles));
            this.generateRectanglePerLine(nextLineRectangles, generatedRectangles);
        }
        else {
            generatedRectangles.push(this.buildLineRectangle(annotationRectangles));
        }
    }
    /**
     * @param {?} rectangles
     * @return {?}
     */
    getAnnotationLineHeight(rectangles) {
        return rectangles[0].height;
    }
    /**
     * @param {?} rectangles
     * @param {?=} lowest
     * @return {?}
     */
    sortByY(rectangles, lowest = true) {
        rectangles.sort(function (a, b) {
            /** @type {?} */
            const keyA = a.y;
            /** @type {?} */
            const keyB = b.y;
            if (keyA < keyB) {
                return lowest ? -1 : 1;
            }
            if (keyA > keyB) {
                return lowest ? 1 : -1;
            }
            return 0;
        });
    }
    /**
     * @param {?} rectangles
     * @param {?=} lowest
     * @return {?}
     */
    sortByX(rectangles, lowest = true) {
        rectangles.sort(function (a, b) {
            /** @type {?} */
            const keyA = a.x;
            /** @type {?} */
            const keyB = b.x;
            if (keyA < keyB) {
                return lowest ? -1 : 1;
            }
            if (keyA > keyB) {
                return lowest ? 1 : -1;
            }
            return 0;
        });
    }
    /**
     * @param {?} a
     * @param {?} b
     * @return {?}
     */
    sortByLinePosition(a, b) {
        this.sortByX(a);
        this.sortByX(b);
        return (a[0].x > b[0].x) ? 1 : -1;
    }
    /**
     * @param {?} a
     * @param {?} b
     * @return {?}
     */
    difference(a, b) { return Math.abs(a - b); }
    /**
     * @param {?} event
     * @return {?}
     */
    clickIsHighlight(event) {
        /** @type {?} */
        const target = (/** @type {?} */ (event.target));
        /** @type {?} */
        const isHighlight = target.firstElementChild;
        if (isHighlight == null) {
            return false;
        }
        else if (isHighlight.id.includes('pdf-annotate-screenreader')) {
            return true;
        }
        else {
            return false;
        }
    }
    /**
     * @param {?} event
     * @return {?}
     */
    getClickedPage(event) {
        /** @type {?} */
        let currentParent = event.target;
        for (let step = 0; step < 5; step++) {
            if (currentParent.parentNode != null) {
                /** @type {?} */
                const pageNumber = currentParent.parentNode.getAttribute('data-page-number');
                if (pageNumber != null) {
                    return parseInt(pageNumber, null);
                }
                currentParent = currentParent.parentNode;
            }
        }
    }
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class PdfAdapter {
    /**
     * @param {?} log
     * @param {?} utils
     * @param {?} window
     */
    constructor(log, utils, window) {
        this.log = log;
        this.utils = utils;
        this.window = window;
        this.annotationChangeSubject = new Subject();
        log.setClass('PdfAdapter');
    }
    /**
     * @return {?}
     */
    getAnnotationChangeSubject() {
        return this.annotationChangeSubject;
    }
    /**
     * @param {?} annotationSet
     * @return {?}
     */
    setStoreData(annotationSet) {
        this.annotationSet = annotationSet;
        this.annotations = annotationSet.annotations;
        this.commentData = [];
        this.annotations.forEach((annotation) => {
            annotation.comments.forEach((comment) => {
                this.commentData.push(comment);
            });
        });
        this.annotationSetId = annotationSet.id;
    }
    /**
     * @param {?} comment
     * @return {?}
     */
    editComment(comment) {
        this.annotations.forEach((annotation) => {
            annotation.comments
                .filter(storeComment => storeComment.id === comment.id)
                .map(storeComment => {
                this.log.info('Editing comment:' + comment.id);
                storeComment.content = comment.content;
                this.annotationChangeSubject.next({ 'type': 'editComment', 'annotation': annotation });
            });
        });
    }
    /**
     * @param {?} documentId
     * @param {?} comment
     * @return {?}
     */
    updateComments(documentId, comment) {
        this.commentData.push(comment);
    }
    /**
     * @param {?} documentId
     * @return {?}
     */
    _getAnnotations(documentId) {
        return this.annotations || [];
    }
    /**
     * @param {?} documentId
     * @return {?}
     */
    _getComments(documentId) {
        return this.commentData || [];
    }
    /**
     * @return {?}
     */
    clearSelection() {
        /** @type {?} */
        const sel = this.window.getSelection();
        if (sel) {
            if (sel.removeAllRanges) {
                sel.removeAllRanges();
            }
            else if (sel.empty) {
                sel.empty();
            }
        }
    }
    /**
     * @param {?} comment
     * @return {?}
     */
    isDraftComment(comment) {
        return (comment.content === null || comment.content === '');
    }
    /**
     * @return {?}
     */
    getStoreAdapter() {
        /** @type {?} */
        const getAnnotations = (documentId, pageNumber) => {
            return new Promise((resolve, reject) => {
                /** @type {?} */
                const annotations = this._getAnnotations(documentId).filter(function (i) {
                    return i.page === pageNumber;
                });
                resolve({
                    documentId: documentId,
                    pageNumber: pageNumber,
                    annotations: annotations
                });
            });
        };
        /** @type {?} */
        const getComments = (documentId, annotationId) => {
            return new Promise((resolve, reject) => {
                resolve(this._getComments(documentId).filter(function (i) {
                    return i.annotationId === annotationId;
                }));
            });
        };
        /** @type {?} */
        const getAnnotation = (documentId, annotationId) => {
            return new Promise((resolve, reject) => {
                /** @type {?} */
                const annotation = this._getAnnotations(documentId).find(function (i) {
                    return i.id === annotationId;
                });
                resolve(annotation);
            });
        };
        /** @type {?} */
        const addAnnotation = (documentId, pageNumber, annotation) => {
            return new Promise((resolve, reject) => {
                this.clearSelection();
                /** @type {?} */
                const persistAnnotation = new Annotation();
                persistAnnotation.id = v4();
                persistAnnotation.page = pageNumber;
                persistAnnotation.color = annotation.color;
                persistAnnotation.type = annotation.type;
                persistAnnotation.comments = [];
                persistAnnotation.annotationSetId = this.annotationSetId;
                /** @type {?} */
                const rectangles = [];
                this.log.info('Generating efficient rectangles for new annotation:' + persistAnnotation.id);
                this.utils.generateRectanglePerLine(annotation.rectangles, rectangles);
                rectangles.forEach((rectangle) => {
                    rectangle.id = v4();
                });
                persistAnnotation.rectangles = rectangles;
                /** @type {?} */
                const annotations = this._getAnnotations(documentId);
                annotations.push(persistAnnotation);
                this.log.info('Added annotation:' + annotation.id);
                this.annotationChangeSubject.next({ 'type': 'addAnnotation', 'annotation': persistAnnotation });
                resolve(persistAnnotation);
            });
        };
        /** @type {?} */
        const deleteAnnotation = (documentId, annotationId) => {
            return new Promise((resolve, reject) => {
                /** @type {?} */
                const annotation = this.findById(this.annotations, annotationId);
                this.remove(this.annotations, annotationId);
                this.log.info('Deleted annotation:' + annotationId);
                this.annotationChangeSubject.next({ 'type': 'deleteAnnotation', 'annotation': annotation });
                resolve(this.annotations);
            });
        };
        /** @type {?} */
        const addComment = (documentId, annotationId, content) => {
            return new Promise((resolve, reject) => {
                /** @type {?} */
                const comment = new Comment(v4(), annotationId, null, null, new Date(), null, null, null, content);
                this.updateComments(documentId, comment);
                /** @type {?} */
                const annotation = this.findById(this.annotations, annotationId);
                this.log.info('Comment:' + comment.id + ' has been added to annotation:' + annotationId);
                annotation.comments.push(comment);
                if (this.isDraftComment(comment)) {
                    this.log.info('Removing comment box because no content exists');
                    resolve(comment);
                }
                else {
                    this.log.info('Add comment:' + comment.id + '-' + 'annotationId:' + annotation.id);
                    this.annotationChangeSubject.next({ 'type': 'addComment', 'annotation': annotation });
                    resolve(comment);
                }
            });
        };
        /** @type {?} */
        const deleteComment = (documentId, commentId) => {
            return new Promise((resolve, reject) => {
                /** @type {?} */
                const comment = this.findById(this.commentData, commentId);
                /** @type {?} */
                const annotation = this.findById(this.annotations, comment.annotationId);
                this.remove(this.commentData, commentId);
                this.remove(annotation.comments, commentId);
                if (this.isDraftComment(comment)) {
                    this.log.info('Removing comment box because no content exists');
                    resolve(comment);
                }
                else {
                    this.log.info('Deleted comment:' + commentId + '-' + 'annotationId:' + annotation.id);
                    this.annotationChangeSubject.next({ 'type': 'deleteComment', 'annotation': annotation });
                    resolve(this.annotations);
                }
            });
        };
        // Unused
        /** @type {?} */
        const editAnnotation = (documentId, pageNumber, annotation) => {
            return new Promise((resolve, reject) => {
                this.annotationChangeSubject.next({ 'type': 'editAnnotation', 'annotation': annotation });
                resolve(this.commentData);
            });
        };
        return {
            getAnnotations,
            getComments,
            getAnnotation,
            addAnnotation,
            editAnnotation,
            deleteAnnotation,
            addComment,
            deleteComment
        };
    }
    /**
     * @param {?} array
     * @param {?} id
     * @return {?}
     */
    findById(array, id) {
        return array.find(e => e.id === id);
    }
    /**
     * @param {?} array
     * @param {?} id
     * @return {?}
     */
    remove(array, id) {
        return array.splice(array.findIndex(e => e.id === id), 1);
    }
}
PdfAdapter.decorators = [
    { type: Injectable }
];
PdfAdapter.ctorParameters = () => [
    { type: EmLoggerService },
    { type: Utils },
    { type: undefined, decorators: [{ type: Inject, args: [WINDOW,] }] }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class ApiHttpService {
    /**
     * @param {?} log
     * @param {?} httpClient
     * @param {?} platformId
     * @param {?} transferState
     */
    constructor(log, httpClient, platformId, transferState) {
        this.log = log;
        this.httpClient = httpClient;
        this.platformId = platformId;
        this.transferState = transferState;
        log.setClass('ApiHttpService');
    }
    /**
     * @param {?} baseUrl
     * @return {?}
     */
    setBaseUrl(baseUrl) {
        this.baseUrl = baseUrl;
    }
    /**
     * @return {?}
     */
    getBaseUrl() {
        return this.baseUrl;
    }
    /**
     * @param {?} baseUrl
     * @param {?} body
     * @return {?}
     */
    createAnnotationSet(baseUrl, body) {
        return this.httpClient.post(`${baseUrl}/em-anno/annotation-sets`, body, { observe: 'response' });
    }
    /**
     * @param {?} baseUrl
     * @param {?} dmDocumentId
     * @return {?}
     */
    fetch(baseUrl, dmDocumentId) {
        /** @type {?} */
        const STATE_KEY = makeStateKey('annotationSet-' + dmDocumentId);
        if (this.transferState.hasKey(STATE_KEY)) {
            /** @type {?} */
            const annotationSet = this.transferState.get(STATE_KEY, null);
            this.transferState.remove(STATE_KEY);
            return of(annotationSet);
        }
        else {
            /** @type {?} */
            const url = `${baseUrl}/em-anno/annotation-sets/${dmDocumentId}`;
            return this.httpClient.get(url, { observe: 'response' })
                .pipe(tap(annotationSet => {
                if (isPlatformServer(this.platformId)) {
                    this.transferState.set(STATE_KEY, annotationSet);
                }
            }));
        }
    }
    /**
     * @param {?} dmDocumentId
     * @param {?} outputDmDocumentId
     * @param {?} baseUrl
     * @return {?}
     */
    documentTask(dmDocumentId, outputDmDocumentId, baseUrl) {
        /** @type {?} */
        const url = `${baseUrl}/api/em-npa/document-tasks`;
        /** @type {?} */
        const documentTasks = {
            inputDocumentId: dmDocumentId,
            outputDocumentId: outputDmDocumentId
        };
        this.log.info('Calling NPA service-' + dmDocumentId);
        return this.httpClient.post(url, documentTasks, { observe: 'response' });
    }
    /**
     * @param {?} annotation
     * @return {?}
     */
    deleteAnnotation(annotation) {
        /** @type {?} */
        const url = `${this.baseUrl}/em-anno/annotations/${annotation.id}`;
        return this.httpClient.delete(url, { observe: 'response' });
    }
    /**
     * @param {?} annotation
     * @return {?}
     */
    saveAnnotation(annotation) {
        /** @type {?} */
        const url = `${this.baseUrl}/em-anno/annotations`;
        return this.httpClient.post(url, annotation, { observe: 'response' });
    }
}
ApiHttpService.decorators = [
    { type: Injectable }
];
ApiHttpService.ctorParameters = () => [
    { type: EmLoggerService },
    { type: HttpClient },
    { type: undefined, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] },
    { type: TransferState }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class PdfWrapper {
    /**
     * @param {?} documentId
     * @return {?}
     */
    getDocument(documentId) {
        return PDFJS.getDocument(documentId);
    }
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class RotationModel {
    /**
     * @param {?} pageNumber
     * @param {?} pageDom
     */
    constructor(pageNumber, pageDom) {
        this.pageNumber = pageNumber;
        this.pageDom = pageDom;
    }
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class PdfRenderService {
    /**
     * @param {?} pdfWrapper
     * @param {?} log
     * @param {?} pdfAnnotateWrapper
     */
    constructor(pdfWrapper, log, pdfAnnotateWrapper) {
        this.pdfWrapper = pdfWrapper;
        this.log = log;
        this.pdfAnnotateWrapper = pdfAnnotateWrapper;
        this.listPages = [];
        this.log.setClass('PdfRenderService');
        this.dataLoadedSubject = new BehaviorSubject(false);
        this.listPagesSubject = new Subject();
    }
    /**
     * @return {?}
     */
    getDataLoadedSub() {
        return this.dataLoadedSubject;
    }
    /**
     * @param {?} isLoaded
     * @return {?}
     */
    dataLoadedUpdate(isLoaded) {
        this.dataLoadedSubject.next(isLoaded);
    }
    /**
     * @return {?}
     */
    getRenderOptions() {
        return Object.assign({}, this.RENDER_OPTIONS);
    }
    /**
     * @param {?} RENDER_OPTIONS
     * @return {?}
     */
    setRenderOptions(RENDER_OPTIONS) {
        this.RENDER_OPTIONS = RENDER_OPTIONS;
    }
    /**
     * @return {?}
     */
    getViewerElementRef() {
        return this.viewerElementRef;
    }
    /**
     * @return {?}
     */
    getPdfPages() {
        return this.pdfPages;
    }
    /**
     * @param {?=} viewerElementRef
     * @return {?}
     */
    render(viewerElementRef) {
        if (viewerElementRef != null) {
            this.viewerElementRef = viewerElementRef;
        }
        /** @type {?} */
        const renderOptions = this.getRenderOptions();
        this.pdfWrapper.getDocument(renderOptions.documentId)
            .then(pdf => {
            renderOptions.pdfDocument = pdf;
            /** @type {?} */
            const viewer = this.viewerElementRef.nativeElement;
            viewer.innerHTML = '';
            this.pdfPages = pdf.pdfInfo.numPages;
            this.listPages = [];
            for (let i = 1; i < this.pdfPages + 1; i++) {
                /** @type {?} */
                const pageDom = this.pdfAnnotateWrapper.createPage(i);
                // Create a copy of the render options for each page.
                /** @type {?} */
                const pageOptions = Object.assign({}, renderOptions);
                viewer.appendChild(pageDom);
                this.addDomPage(pageDom, i);
                pdf.getPage(i).then((pdfPage) => {
                    // Get current page rotation from page rotation objects
                    pageOptions.rotate = this.addPageRotation(renderOptions, pageOptions, pdfPage);
                    setTimeout(() => {
                        this.pdfAnnotateWrapper.renderPage(i, pageOptions).then(() => {
                            if (i === this.pdfPages) {
                                this.setRenderOptions(renderOptions);
                                this.dataLoadedUpdate(true);
                                this.listPagesSubject.next(this.listPages);
                            }
                        });
                    });
                });
            }
        }).catch((error) => {
            /** @type {?} */
            const errorMessage = new Error('Unable to render your supplied PDF. ' +
                renderOptions.documentId + '. Error is: ' + error);
            this.log.error('Encountered error while rendering the PDF:' + errorMessage);
        });
    }
    /**
     * @param {?} pageDom
     * @param {?} pageNumber
     * @return {?}
     */
    addDomPage(pageDom, pageNumber) {
        /** @type {?} */
        const pagedetails = new RotationModel(pageNumber, pageDom);
        /** @type {?} */
        const index = this.listPages.findIndex(pageElement => pageElement.pageNumber === pageNumber);
        if (index > 0) {
            this.listPages[index] = pagedetails;
        }
        else {
            this.listPages.push(pagedetails);
        }
    }
    /**
     * @param {?} renderOptions
     * @param {?} pageOptions
     * @param {?} pdfPage
     * @return {?}
     */
    addPageRotation(renderOptions, pageOptions, pdfPage) {
        /** @type {?} */
        let rotation = this.getPageRotation(pageOptions, pdfPage);
        if (!rotation) {
            renderOptions.rotationPages.push({ page: pdfPage.pageNumber, rotate: pdfPage.rotate });
            rotation = pdfPage.rotate;
        }
        return rotation;
    }
    /**
     * @param {?} pageOptions
     * @param {?} pdfPage
     * @return {?}
     */
    getPageRotation(pageOptions, pdfPage) {
        return pageOptions.rotationPages
            .filter(rotateObj => rotateObj.page === pdfPage.pageNumber)
            .map(rotateObj => rotateObj.rotate)[0];
    }
}
PdfRenderService.decorators = [
    { type: Injectable }
];
PdfRenderService.ctorParameters = () => [
    { type: PdfWrapper },
    { type: EmLoggerService },
    { type: PdfAnnotateWrapper }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class AnnotationStoreService {
    /**
     * @param {?} log
     * @param {?} pdfAdapter
     * @param {?} apiHttpService
     * @param {?} pdfService
     * @param {?} pdfAnnotateWrapper
     * @param {?} pdfRenderService
     */
    constructor(log, pdfAdapter, apiHttpService, pdfService, pdfAnnotateWrapper, pdfRenderService) {
        this.log = log;
        this.pdfAdapter = pdfAdapter;
        this.apiHttpService = apiHttpService;
        this.pdfService = pdfService;
        this.pdfAnnotateWrapper = pdfAnnotateWrapper;
        this.pdfRenderService = pdfRenderService;
        log.setClass('AnnotationStoreService');
        this.commentBtnSubject = new Subject();
        this.commentFocusSubject = new BehaviorSubject({ annotation: new Annotation(null, null, null, null, null, null, null, null, null, null, null, null) });
        this.contextualToolBarOptions = new Subject();
        this.annotationFocusSubject = new Subject();
        this.annotationChangeSubscription = this.pdfAdapter.getAnnotationChangeSubject().subscribe((e) => this.handleAnnotationEvent(e));
    }
    /**
     * @return {?}
     */
    getAnnotationFocusSubject() {
        return this.annotationFocusSubject;
    }
    /**
     * @param {?} annotation
     * @return {?}
     */
    setAnnotationFocusSubject(annotation) {
        this.annotationFocusSubject.next(annotation);
    }
    /**
     * @return {?}
     */
    getCommentFocusSubject() {
        return this.commentFocusSubject;
    }
    /**
     * @param {?} annotation
     * @param {?=} showButton
     * @return {?}
     */
    setCommentFocusSubject(annotation, showButton) {
        this.commentFocusSubject.next({ annotation, showButton });
    }
    /**
     * @return {?}
     */
    getCommentBtnSubject() {
        return this.commentBtnSubject;
    }
    /**
     * @param {?} commentId
     * @return {?}
     */
    setCommentBtnSubject(commentId) {
        this.commentBtnSubject.next(commentId);
    }
    /**
     * @param {?} annotation
     * @param {?=} showDelete
     * @return {?}
     */
    setToolBarUpdate(annotation, showDelete) {
        /** @type {?} */
        const contextualOptions = {
            annotation,
            showDelete
        };
        this.contextualToolBarOptions.next(contextualOptions);
    }
    /**
     * @return {?}
     */
    getToolbarUpdate() {
        return this.contextualToolBarOptions;
    }
    /**
     * @param {?} annotationData
     * @return {?}
     */
    preLoad(annotationData) {
        if (annotationData != null) {
            this.pdfAdapter.setStoreData(annotationData);
            this.pdfAnnotateWrapper.setStoreAdapter(this.pdfAdapter.getStoreAdapter());
            this.pdfService.setHighlightTool();
        }
        else {
            this.pdfService.setCursorTool();
            this.pdfAnnotateWrapper.setStoreAdapter();
        }
    }
    /**
     * @param {?} e
     * @return {?}
     */
    handleAnnotationEvent(e) {
        switch (e.type) {
            case 'addAnnotation': {
                this.saveAnnotation(e.annotation);
                break;
            }
            case 'addComment': {
                this.saveAnnotation(e.annotation, e.type);
                break;
            }
            case 'editComment': {
                this.saveAnnotation(e.annotation, e.type);
                break;
            }
            case 'deleteComment': {
                this.saveAnnotation(e.annotation);
                break;
            }
            case 'editAnnotation': {
                this.saveAnnotation(e.annotation);
                break;
            }
            case 'deleteAnnotation': {
                this.deleteAnnotation(e.annotation);
                break;
            }
        }
    }
    /**
     * @param {?} baseUrl
     * @param {?} dmDocumentId
     * @return {?}
     */
    getAnnotationSet(baseUrl, dmDocumentId) {
        return this.apiHttpService.fetch(baseUrl, dmDocumentId).pipe(catchError((err) => {
            if (err instanceof HttpErrorResponse) {
                switch (err.status) {
                    case 400: {
                        this.log.error('Bad request: ' + err.error);
                        return throwError(err.error);
                    }
                    case 404: {
                        /** @type {?} */
                        const body = {
                            documentId: dmDocumentId,
                            id: v4()
                        };
                        this.log.info('Creating new annotation set for document id:' + dmDocumentId);
                        return this.apiHttpService.createAnnotationSet(baseUrl, body);
                    }
                    case 500: {
                        this.log.error('Internal server error: ' + err);
                        return throwError('Internal server error: ' + err);
                    }
                }
            }
        }));
    }
    /**
     * @return {?}
     */
    saveData() {
        /** @type {?} */
        let loadedData;
        /** @type {?} */
        let toKeepAnnotations;
        /** @type {?} */
        let toRemoveAnnotations;
        loadedData = this.pdfAdapter.annotationSet;
        toKeepAnnotations = this.pdfAdapter.annotations;
        toRemoveAnnotations = this.pdfAdapter.annotationSet.annotations
            .filter((annotation) => !this.pdfAdapter.annotations.map(a => a.id).includes(annotation.id));
        toKeepAnnotations.forEach((annotation) => {
            this.apiHttpService.saveAnnotation(annotation).subscribe(response => this.log.info('Successfully saved annotation:' + response), error => this.log.error('There has been a problem saving the annotation:' + annotation.id + '-' + error));
        });
        toRemoveAnnotations.forEach((annotation) => {
            this.apiHttpService.deleteAnnotation(annotation).subscribe(response => this.log.info('Successfully deleted annotation:' + response), error => this.log.error('There has been a problem deleting annotation:' + annotation.id + '-' + error));
        });
        loadedData.annotations.splice(0, loadedData.annotations.length);
        loadedData.annotations.concat(toKeepAnnotations);
        this.pdfAdapter.annotationSet = loadedData;
    }
    /**
     * @param {?} annotation
     * @param {?=} type
     * @return {?}
     */
    saveAnnotation(annotation, type) {
        this.apiHttpService.saveAnnotation(annotation).subscribe(response => {
            if (type === 'addComment' || type === 'editComment') {
                this.pdfAdapter.annotationSet.annotations[this.pdfAdapter.annotationSet.annotations
                    .findIndex(x => x.id === annotation.id)] = response.body;
            }
            this.log.info('Successfully saved annotation:' + response);
        }, error => this.log.error('There has been a problem saving the annotation:' + annotation.id + '-' + error));
    }
    /**
     * @param {?} annotation
     * @return {?}
     */
    deleteAnnotation(annotation) {
        this.apiHttpService.deleteAnnotation(annotation).subscribe(response => {
            this.log.info('Successfully deleted annotation:' + annotation.id + '-' + response);
        }, error => this.log.error('There has been a problem deleting annotation:' + annotation.id + '-' + error));
    }
    /**
     * @param {?} comment
     * @return {?}
     */
    editComment(comment) {
        this.pdfAdapter.editComment(comment);
    }
    /**
     * @param {?} annotationId
     * @return {?}
     */
    getAnnotationById(annotationId) {
        return new Promise((resolve) => {
            this.getAnnotation(annotationId, annotation => {
                resolve(annotation);
            });
        });
    }
    /**
     * @param {?} pageNumber
     * @return {?}
     */
    getAnnotationsForPage(pageNumber) {
        return new Promise((resolve) => {
            this.getAnnotations(pageNumber, pageData => {
                resolve(pageData);
            });
        });
    }
    /**
     * @param {?} annotationId
     * @return {?}
     */
    getCommentsForAnnotation(annotationId) {
        return new Promise((resolve) => {
            this.getComments(annotationId, comments => {
                resolve(comments);
            });
        });
    }
    /**
     * @param {?} annotationId
     * @param {?} callback
     * @return {?}
     */
    getAnnotation(annotationId, callback) {
        this.pdfAnnotateWrapper.getStoreAdapter()
            .getAnnotation(this.pdfRenderService.getRenderOptions().documentId, annotationId)
            .then(callback);
    }
    /**
     * @param {?} annotationId
     * @param {?} callback
     * @return {?}
     */
    getComments(annotationId, callback) {
        this.pdfAnnotateWrapper.getStoreAdapter()
            .getComments(this.pdfRenderService.getRenderOptions().documentId, annotationId)
            .then(callback);
    }
    /**
     * @param {?} comment
     * @return {?}
     */
    addComment(comment) {
        this.pdfAnnotateWrapper.getStoreAdapter()
            .addComment(this.pdfRenderService.getRenderOptions().documentId, comment.annotationId, comment.content)
            .then();
    }
    /**
     * @param {?} pageNumber
     * @param {?} callback
     * @return {?}
     */
    getAnnotations(pageNumber, callback) {
        this.pdfAnnotateWrapper.getStoreAdapter()
            .getAnnotations(this.pdfRenderService.getRenderOptions().documentId, pageNumber)
            .then(callback);
    }
    /**
     * @param {?} commentId
     * @return {?}
     */
    deleteComment(commentId) {
        this.pdfAnnotateWrapper.getStoreAdapter()
            .deleteComment(this.pdfRenderService.getRenderOptions().documentId, commentId)
            .then();
    }
    /**
     * @param {?} annotationId
     * @param {?} pageNumber
     * @return {?}
     */
    deleteAnnotationById(annotationId, pageNumber) {
        return __awaiter(this, void 0, void 0, function* () {
            /** @type {?} */
            const renderOptions = this.pdfRenderService.getRenderOptions();
            yield this.pdfAnnotateWrapper.getStoreAdapter()
                .deleteAnnotation(renderOptions.documentId, annotationId);
            this.renderPage(renderOptions, pageNumber);
        });
    }
    /**
     * @param {?} renderOptions
     * @param {?} pageNumber
     * @return {?}
     */
    renderPage(renderOptions, pageNumber) {
        renderOptions.rotate = this.pdfRenderService.getPageRotation(renderOptions, { pageNumber: pageNumber });
        this.pdfAnnotateWrapper.renderPage(pageNumber, renderOptions);
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        if (this.annotationChangeSubscription) {
            this.annotationChangeSubscription.unsubscribe();
        }
    }
}
AnnotationStoreService.decorators = [
    { type: Injectable }
];
AnnotationStoreService.ctorParameters = () => [
    { type: EmLoggerService },
    { type: PdfAdapter },
    { type: ApiHttpService },
    { type: PdfService },
    { type: PdfAnnotateWrapper },
    { type: PdfRenderService }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class CommentsComponent {
    /**
     * @param {?} annotationStoreService
     * @param {?} pdfService
     * @param {?} utils
     * @param {?} pdfRenderService
     * @param {?} log
     */
    constructor(annotationStoreService, pdfService, utils, pdfRenderService, log) {
        this.annotationStoreService = annotationStoreService;
        this.pdfService = pdfService;
        this.utils = utils;
        this.pdfRenderService = pdfRenderService;
        this.log = log;
        this.log.setClass('CommentsComponent');
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.dataLoadedSub = this.pdfRenderService.getDataLoadedSub()
            .subscribe(isDataLoaded => {
            if (isDataLoaded) {
                this.showAllComments();
                this.preRun();
            }
        });
    }
    /**
     * @return {?}
     */
    redrawCommentItemComponents() {
        setTimeout(() => {
            /** @type {?} */
            let previousCommentItem;
            this.sortCommentItemComponents().forEach((commentItem) => {
                previousCommentItem = this.isOverlapping(commentItem, previousCommentItem);
            });
        });
    }
    /**
     * @return {?}
     */
    sortCommentItemComponents() {
        return this.commentItems.map((commentItem) => commentItem)
            .sort((a, b) => {
            return this.processSort(a, b);
        });
    }
    /**
     * @param {?} a
     * @param {?} b
     * @return {?}
     */
    processSort(a, b) {
        if (this.isAnnotationOnSameLine(a, b)) {
            if (a.annotationLeftPos < b.annotationLeftPos) {
                return -1;
            }
            if (a.annotationLeftPos >= b.annotationLeftPos) {
                return 1;
            }
        }
        if (a.annotationTopPos < b.annotationTopPos) {
            return -1;
        }
        if (a.annotationTopPos >= b.annotationTopPos) {
            return 1;
        }
        return 0;
    }
    /**
     * @param {?} a
     * @param {?} b
     * @return {?}
     */
    isAnnotationOnSameLine(a, b) {
        /** @type {?} */
        const delta = (a.annotationHeight >= b.annotationHeight) ? a.annotationHeight : b.annotationHeight;
        if (this.utils.difference(a.annotationTopPos, b.annotationTopPos) > delta) {
            return false;
        }
        return true;
    }
    /**
     * @param {?} commentItem
     * @param {?} previousCommentItem
     * @return {?}
     */
    isOverlapping(commentItem, previousCommentItem) {
        commentItem.commentTopPos = commentItem.annotationTopPos;
        if (previousCommentItem) {
            /** @type {?} */
            const endOfPreviousCommentItem = (previousCommentItem.commentTopPos + previousCommentItem.commentHeight);
            if (commentItem.commentTopPos <= endOfPreviousCommentItem) {
                commentItem.commentTopPos = endOfPreviousCommentItem;
            }
        }
        return commentItem;
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        if (this.pageNumSub) {
            this.pageNumSub.unsubscribe();
        }
        if (this.dataLoadedSub) {
            this.dataLoadedSub.unsubscribe();
        }
    }
    /**
     * @return {?}
     */
    preRun() {
        this.pageNumSub = this.pdfService.getPageNumber().subscribe(pageNumber => {
            this.pageNumber = pageNumber;
        });
    }
    /**
     * @return {?}
     */
    showAllComments() {
        // todo - refactor this out of component
        this.annotations = [];
        for (let i = 0; i < this.pdfRenderService.getPdfPages() + 1; i++) {
            this.annotationStoreService.getAnnotationsForPage(i)
                .then((pageData) => {
                this.annotations = this.annotations.concat(pageData.annotations.slice());
            });
        }
    }
    /**
     * @return {?}
     */
    handleAnnotationBlur() {
        this.showAllComments();
    }
    /**
     * @param {?} event
     * @return {?}
     */
    handleAnnotationClick(event) {
        /** @type {?} */
        const annotationId = event.getAttribute('data-pdf-annotate-id');
        this.annotationStoreService.getAnnotationById(annotationId)
            .then((annotation) => {
            this.annotationStoreService.setAnnotationFocusSubject(annotation);
            this.annotationStoreService.setCommentFocusSubject(annotation);
            this.annotationStoreService.setToolBarUpdate(annotation, true);
        });
    }
}
CommentsComponent.decorators = [
    { type: Component, args: [{
                selector: 'app-comments',
                template: "<div *ngIf=\"pageNumber\" id=\"comment-wrapper\">\n  <div class=\"comment-list-container\">\n\n    <div *ngFor=\"let annotation of annotations\" class=\"highlight-group\">\n      <app-comment-item #commentItem\n                        *ngFor=\"let comment of annotation.comments\"\n                        [annotation]=\"annotation\"\n                        [comment]=\"comment\"\n                        (commentSubmitted)='showAllComments()'\n                        (commentRendered)='redrawCommentItemComponents()'\n      ></app-comment-item>\n    </div>\n  </div>\n</div>\n",
                styles: ["#comment-wrapper{position:absolute;height:100%;width:380px;right:0;overflow:hidden;z-index:0;font-family:nta,Arial,sans-serif;-webkit-font-smoothing:antialiased;font-size:12px}#comment-wrapper .comment-list{font-size:12px;position:absolute;top:38px;left:0;right:0;bottom:0}#comment-wrapper .comment-list-container{position:absolute;top:0;left:0;right:0;bottom:47px;overflow-x:hidden;overflow-y:auto}"]
            }] }
];
CommentsComponent.ctorParameters = () => [
    { type: AnnotationStoreService },
    { type: PdfService },
    { type: Utils },
    { type: PdfRenderService },
    { type: EmLoggerService }
];
CommentsComponent.propDecorators = {
    commentItems: [{ type: ViewChildren, args: ['commentItem',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class CommentItemComponent {
    /**
     * @param {?} annotationStoreService
     * @param {?} pdfService
     * @param {?} pdfRenderService
     * @param {?} ref
     * @param {?} renderer
     * @param {?} utils
     * @param {?} log
     */
    constructor(annotationStoreService, pdfService, pdfRenderService, ref, renderer, utils, log) {
        this.annotationStoreService = annotationStoreService;
        this.pdfService = pdfService;
        this.pdfRenderService = pdfRenderService;
        this.ref = ref;
        this.renderer = renderer;
        this.utils = utils;
        this.log = log;
        this.commentSubmitted = new EventEmitter();
        this.commentRendered = new EventEmitter();
        this.model = new Comment(null, null, null, null, null, null, null, null, null);
        this.log.setClass('CommentItemComponent');
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.hideButton = true;
        this.focused = false;
        this.sliceComment = this.comment.content;
        this.commentFocusSub = this.annotationStoreService.getCommentFocusSubject()
            .subscribe((options) => {
            if (options.annotation.id === this.comment.annotationId) {
                if (options.showButton) {
                    this.onEdit();
                }
                else {
                    this.handleShowBtn();
                }
                this.ref.detectChanges();
            }
            else {
                this.onBlur();
            }
        });
        this.commentBtnSub = this.annotationStoreService.getCommentBtnSubject()
            .subscribe((commentId) => {
            (commentId === this.comment.id) ? this.handleShowBtn() : this.handleHideBtn();
        });
        this.dataLoadedSub = this.pdfRenderService.getDataLoadedSub()
            .subscribe((dataLoaded) => {
            if (dataLoaded) {
                this.annotationTopPos = this.getRelativePosition(this.comment.annotationId);
                this.commentTopPos = this.annotationTopPos;
                this.utils.sortByX(this.annotation.rectangles, true);
                this.annotationHeight = this.utils.getAnnotationLineHeight(this.annotation.rectangles);
                this.annotationLeftPos = this.annotation.rectangles[0].x;
                this.commentRendered.emit(true);
                this.collapseComment();
            }
        });
        this.commentItem.statusChanges.subscribe(() => {
            if (this.focused) {
                this.expandComment();
            }
        });
    }
    /**
     * @return {?}
     */
    setHeight() {
        this.renderer.setStyle(this.commentArea.nativeElement, 'height', 'fit-content');
        this.renderer.setStyle(this.commentArea.nativeElement, 'height', (this.commentArea.nativeElement.scrollHeight) + 'px');
        this.commentHeight = this.commentSelector.nativeElement.getBoundingClientRect().height;
        this.commentRendered.emit(true);
        if (!this.ref['destroyed']) {
            this.ref.detectChanges();
        }
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        if (this.commentFocusSub) {
            this.commentFocusSub.unsubscribe();
        }
        if (this.commentBtnSub) {
            this.commentBtnSub.unsubscribe();
        }
        if (this.dataLoadedSub) {
            this.dataLoadedSub.unsubscribe();
        }
    }
    /**
     * @return {?}
     */
    onSubmit() {
        /** @type {?} */
        const comment = this.convertFormToComment(this.commentItem);
        this.annotationStoreService.editComment(comment);
        this.commentSubmitted.emit(this.annotation);
        this.viewOnly();
    }
    /**
     * @return {?}
     */
    onEdit() {
        this.editOnly();
    }
    /**
     * @return {?}
     */
    onCancel() {
        this.renderer.setProperty(this.commentArea.nativeElement, 'value', this.comment.content);
        this.viewOnly();
    }
    /**
     * @return {?}
     */
    viewOnly() {
        this.renderer.addClass(this.commentArea.nativeElement, 'view-mode');
        this.focused = false;
    }
    /**
     * @return {?}
     */
    editOnly() {
        this.focused = true;
        this.renderer.removeClass(this.commentArea.nativeElement, 'view-mode');
    }
    /**
     * @return {?}
     */
    isModified() {
        if (this.comment.createdDate === null) {
            return false;
        }
        else if (this.comment.lastModifiedBy === null) {
            return false;
        }
        else if (this.comment.createdDate === this.comment.lastModifiedDate) {
            return false;
        }
        else {
            return true;
        }
    }
    /**
     * @return {?}
     */
    onBlur() {
        if (!this.ref['destroyed']) {
            this.ref.detectChanges();
        }
    }
    /**
     * @param {?} commentForm
     * @return {?}
     */
    convertFormToComment(commentForm) {
        return new Comment(this.comment.id, this.comment.annotationId, null, null, new Date(), null, null, null, commentForm.value.content);
    }
    /**
     * @return {?}
     */
    handleDeleteComment() {
        this.annotationStoreService.deleteComment(this.comment.id);
    }
    /**
     * @param {?} event
     * @return {?}
     */
    handleCommentClick(event) {
        event.stopPropagation();
        this.annotationStoreService.setCommentBtnSubject(this.comment.id);
        this.annotationStoreService.setAnnotationFocusSubject(this.annotation);
    }
    /**
     * @return {?}
     */
    handleShowBtn() {
        new Promise(resolve => {
            this.hideButton = false;
            this.expandComment();
            resolve('Success');
        }).then(() => {
            this.setHeight();
            setTimeout(() => {
                this.commentArea.nativeElement.focus();
            });
        });
    }
    /**
     * @return {?}
     */
    handleHideBtn() {
        new Promise(resolve => {
            if (!this.commentItem.value.content) {
                this.annotationStoreService.deleteComment(this.comment.id);
            }
            this.focused = false;
            this.hideButton = true;
            this.collapseComment();
            resolve('Success');
        }).then(() => {
            this.setHeight();
        });
    }
    /**
     * @return {?}
     */
    collapseComment() {
        new Promise(resolve => {
            this.expandComment();
            resolve('Success');
        }).then(() => {
            if (!this.isCommentEmpty()) {
                this.shrinkComment();
            }
            this.renderer.addClass(this.commentArea.nativeElement, 'collapsed');
            this.renderer.removeClass(this.commentArea.nativeElement, 'expanded');
            this.renderer.addClass(this.detailsWrapper.nativeElement, 'collapsed');
            this.renderer.addClass(this.commentArea.nativeElement, 'view-mode');
            this.setHeight();
        });
    }
    /**
     * @return {?}
     */
    isCommentEmpty() {
        return this.comment.content === null;
    }
    /**
     * @return {?}
     */
    isShrinkable() {
        return this.commentArea.nativeElement.scrollHeight > 31;
    }
    /**
     * @return {?}
     */
    shrinkComment() {
        if (this.isShrinkable()) {
            this.sliceComment = this.removeMultipleLines().slice(0, 20) + '...';
        }
    }
    /**
     * @return {?}
     */
    removeMultipleLines() {
        return this.comment.content.split('\n').join(' ');
    }
    /**
     * @return {?}
     */
    expandComment() {
        this.renderer.addClass(this.commentArea.nativeElement, 'expanded');
        this.renderer.removeClass(this.commentArea.nativeElement, 'collapsed');
        this.renderer.removeClass(this.detailsWrapper.nativeElement, 'collapsed');
        this.renderer.addClass(this.detailsWrapper.nativeElement, 'expanded');
        this.sliceComment = this.comment.content;
        this.setHeight();
    }
    /**
     * @param {?} annotationId
     * @return {?}
     */
    getRelativePosition(annotationId) {
        /** @type {?} */
        const svgSelector = this.pdfRenderService.getViewerElementRef().nativeElement
            .querySelector(`g[data-pdf-annotate-id="${annotationId}"]`);
        if (svgSelector === null) {
            return null;
        }
        else {
            /** @type {?} */
            const highlightRect = (/** @type {?} */ (svgSelector.getBoundingClientRect()));
            /** @type {?} */
            const wrapperRect = (/** @type {?} */ (this.pdfService.getAnnotationWrapper().nativeElement.getBoundingClientRect()));
            return (highlightRect.y - wrapperRect.top);
        }
    }
}
CommentItemComponent.decorators = [
    { type: Component, args: [{
                selector: 'app-comment-item',
                template: "<form class=\"aui-comment comment-list-item\"\n      (ngSubmit)=\"onSubmit()\"\n      #commentSelector\n      #commentItem=\"ngForm\"\n      (click)=\"handleCommentClick($event)\"\n      [style.top.px]=\"commentTopPos\">\n  <div #detailsWrapper id=\"detailsWrapper\" class=\"aui-comment__header\">\n    <span *ngIf=\"comment.createdByDetails\" class=\"aui-comment__author\">{{comment.createdByDetails.forename}} {{comment.createdByDetails.surname}}</span>\n    <time #commentDate class=\"aui-comment__meta\" ng-controller=\"datCtrl\">{{ comment.createdDate | date: 'd MMMM y h:mm a' }}</time>\n    <div *ngIf=\"false\">\n      <span>modified By: {{comment.lastModifiedByDetails.forename}} {{comment.lastModifiedByDetails.surname}}</span>\n      <time class=\"aui-comment__meta\" ng-controller=\"datCtrl\"><br>{{ comment.lastModifiedDate | date: 'd MMMM y h:mm a' }}</time>\n    </div>\n  </div>\n\n  <textarea\n    #commentArea\n    (blur)=\"onBlur()\"\n    type=\"text\"\n    [class.mimic-focus]=\"focused\"\n    class=\"aui-comment__content form-control mimic-focus view-mode\"\n    required\n    [ngModel]=\"sliceComment\" name=\"content\"\n    value=\"comment.content\"\n    [readonly]=\"!focused\"></textarea>\n\n  <div [hidden]=\"hideButton\" class=\"aui-comment__footer commentBtns\">\n    <button *ngIf=\"focused\" type=\"submit\" class=\"govuk-button\" role=\"button\">Save</button>\n    <button *ngIf=\"!focused\" (click)=\"onEdit()\" class=\"govuk-button\" role=\"button\">Edit</button>\n    <button\n      *ngIf=\"!focused\"\n      class=\"govuk-button hmcts hmcts-button--secondary\"\n      role=\"button\"\n      (click)=\"handleDeleteComment()\">Delete</button>\n    <button\n      *ngIf=\"focused\"\n      class=\"govuk-button hmcts hmcts-button--secondary\"\n      role=\"button\"\n      (click)=\"onCancel()\">Cancel</button>\n  </div>\n</form>\n",
                styles: ["form{width:95%;margin-bottom:5px;position:absolute;background-color:#fff;padding:20px 20px 0}form textarea{width:95%;padding:2px;border:none;font-size:17px;font-family:nta,Arial,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-weight:400;overflow:hidden;resize:none}.mimic-focus{outline-offset:-2px;outline:#0b0c0c auto 5px}textarea.view-mode:focus{outline:0}#detailsWrapper{padding:0}#detailsWrapper.expanded{margin-bottom:15px}.commentBtns{height:50px}.expanded{margin-top:0}.collapsed{height:30px}textarea.expanded{margin-bottom:10px}textarea.collapsed{margin-top:-25px;max-height:20px}.collapsed>time{display:none}"]
            }] }
];
CommentItemComponent.ctorParameters = () => [
    { type: AnnotationStoreService },
    { type: PdfService },
    { type: PdfRenderService },
    { type: ChangeDetectorRef },
    { type: Renderer2 },
    { type: Utils },
    { type: EmLoggerService }
];
CommentItemComponent.propDecorators = {
    comment: [{ type: Input }],
    annotation: [{ type: Input }],
    commentSubmitted: [{ type: Output }],
    commentRendered: [{ type: Output }],
    commentSelector: [{ type: ViewChild, args: ['commentSelector',] }],
    commentArea: [{ type: ViewChild, args: ['commentArea',] }],
    commentItem: [{ type: ViewChild, args: ['commentItem',] }],
    detailsWrapper: [{ type: ViewChild, args: ['detailsWrapper',] }],
    commentDate: [{ type: ViewChild, args: ['commentDate',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class NpaService {
    /**
     * @param {?} log
     * @param {?} apiHttpService
     */
    constructor(log, apiHttpService) {
        this.log = log;
        this.apiHttpService = apiHttpService;
        log.setClass('NpaService');
        this.outputDmDocumentId = new Subject();
        this.documentTask = new Subject();
    }
    /**
     * @param {?} dmDocumentId
     * @param {?} outputDmDocumentId
     * @param {?} baseUrl
     * @return {?}
     */
    exportPdf(dmDocumentId, outputDmDocumentId, baseUrl) {
        this.log.info('Calling HTTP service for NPA');
        return this.apiHttpService.documentTask(dmDocumentId, outputDmDocumentId, baseUrl);
    }
}
NpaService.decorators = [
    { type: Injectable }
];
NpaService.ctorParameters = () => [
    { type: EmLoggerService },
    { type: ApiHttpService }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class ContextualToolbarComponent {
    /**
     * @param {?} annotationStoreService
     * @param {?} ref
     * @param {?} pdfRenderService
     * @param {?} pdfService
     * @param {?} log
     */
    constructor(annotationStoreService, ref, pdfRenderService, pdfService, log) {
        this.annotationStoreService = annotationStoreService;
        this.ref = ref;
        this.pdfRenderService = pdfRenderService;
        this.pdfService = pdfService;
        this.log = log;
        this.deletedAnnotation = new EventEmitter();
        this.log.setClass('ContextualToolbarComponent');
        this.toolPos = {
            left: 0,
            top: 0
        };
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.contextualToolBarOptions = this.annotationStoreService.getToolbarUpdate()
            .subscribe(contextualOptions => {
            if (contextualOptions.annotation != null) {
                this.showToolBar(contextualOptions.annotation, contextualOptions.showDelete);
            }
            else {
                this.hideToolBar();
            }
        });
        this.isShowToolbar = false;
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        this.ref.detach();
        if (this.contextualToolBarOptions) {
            this.contextualToolBarOptions.unsubscribe();
        }
    }
    /**
     * @param {?} annotation
     * @param {?=} showDelete
     * @return {?}
     */
    showToolBar(annotation, showDelete) {
        this.annotation = annotation;
        this.showDelete = showDelete;
        this.toolPos = this.getRelativePosition(annotation.id);
        this.isShowToolbar = true;
        if (!this.ref['destroyed']) {
            this.ref.detectChanges();
        }
    }
    /**
     * @param {?} annotationId
     * @return {?}
     */
    getRelativePosition(annotationId) {
        /** @type {?} */
        const svgSelector = this.pdfRenderService.getViewerElementRef().nativeElement
            .querySelector(`g[data-pdf-annotate-id="${annotationId}"]`);
        /** @type {?} */
        const highlightRect = (/** @type {?} */ (svgSelector.getBoundingClientRect()));
        /** @type {?} */
        const wrapper = this.pdfService.getAnnotationWrapper().nativeElement;
        /** @type {?} */
        const wrapperRect = (/** @type {?} */ (wrapper.getBoundingClientRect()));
        /** @type {?} */
        const left = ((highlightRect.x - wrapperRect.left)
            - 175) + highlightRect.width / 2;
        // Minus half the toolbar width + half the length of the highlight
        /** @type {?} */
        const top = ((highlightRect.y - wrapperRect.top)
            - 59) - 5;
        return {
            left,
            top
        };
    }
    /**
     * @return {?}
     */
    hideToolBar() {
        this.annotation = null;
        this.isShowToolbar = false;
        this.showDelete = false;
        if (!this.ref['destroyed']) {
            this.ref.detectChanges();
        }
    }
    /**
     * @return {?}
     */
    handleCommentBtnClick() {
        if (this.annotation.comments.length === 0) {
            this.annotationStoreService.addComment(new Comment(null, this.annotation.id, null, null, null, null, null, null, null));
        }
        setTimeout(() => {
            /** @type {?} */
            const tempAnnotation = this.annotation;
            this.hideToolBar();
            this.annotationStoreService.setCommentFocusSubject(tempAnnotation, true);
        }, 10);
    }
    /**
     * @return {?}
     */
    handleHighlightBtnClick() {
        this.hideToolBar();
    }
    /**
     * @return {?}
     */
    handleDeleteBtnClick() {
        return __awaiter(this, void 0, void 0, function* () {
            yield this.annotationStoreService.deleteAnnotationById(this.annotation.id, this.annotation.page);
            this.hideToolBar();
            this.deletedAnnotation.emit('deleted annotation');
        });
    }
}
ContextualToolbarComponent.decorators = [
    { type: Component, args: [{
                selector: 'app-contextual-toolbar',
                template: "<div [hidden]=\"!isShowToolbar\" class=\"toolbar\"\n     [style.left.px]=\"toolPos.left\"\n     [style.top.px]=\"toolPos.top\">\n\n  <button\n    [hidden]=\"showDelete\"\n    type=\"button\" class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n    title=\"Highlight\"\n    (click)=\"handleHighlightBtnClick()\"\n  ><span>Add Highlight</span></button>\n\n  <button\n    [hidden]=\"!showDelete\"\n    type=\"button\"\n    title=\"Delete\" class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn leftButton\"\n    (click)=\"handleDeleteBtnClick()\"\n  ><span>Remove Highlight</span></button>\n\n  <button type=\"button\" title=\"Comment\" class=\"aui__toolbar-button aui__toolbar-button--comments contextual-btn rightButton\"\n          (click)=\"handleCommentBtnClick()\"\n  ><span>Comment</span></button>\n\n\n  <div class=\"arrow-down\">\n    <div class=\"inner-triangle\"></div>\n  </div>\n\n</div>\n",
                styles: [".toolbar{position:absolute;background-color:#fff;height:52px;width:350px;margin:0 auto;text-shadow:1px 1px 0 #fff;z-index:1;border:1px solid #c1c1c1;box-shadow:0 2px #c1c1c1}.toolbar .spacer{display:inline-block;border-left:1px solid #c1c1c1;height:34px;margin:0 5px -11px}.toolbar button span{margin-left:20px}.toolbar button{padding:0;margin-left:2.5%;margin-right:2.5%;margin-top:6px;height:40px;border:0}.toolbar button:hover{border:1px solid #000}.contextual-btn{font-size:16px;background:5px 50%/20px 20px no-repeat #fff}.rightButton{width:124px;background-image:url(/assets/images/icon-document-comments.svg)}.leftButton{background-image:url(/assets/images/annotate-highlight.svg);width:190px}.arrow-down{margin:53px auto 0;width:0;height:0;border-left:12px solid transparent;border-right:12px solid transparent;border-top:12px solid #c1c1c1}.inner-triangle{position:relative;top:-13px;left:-10px;width:0;height:0;border-left:10px solid transparent;border-right:10px solid transparent;border-top:10px solid #fff}"]
            }] }
];
ContextualToolbarComponent.ctorParameters = () => [
    { type: AnnotationStoreService },
    { type: ChangeDetectorRef },
    { type: PdfRenderService },
    { type: PdfService },
    { type: EmLoggerService }
];
ContextualToolbarComponent.propDecorators = {
    deletedAnnotation: [{ type: Output }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class RenderOptions {
    /**
     * @param {?} documentId
     * @param {?} pdfDocument
     * @param {?} scale
     * @param {?} rotate
     * @param {?} rotationPages
     */
    constructor(documentId, pdfDocument, scale, rotate, rotationPages) {
        this.documentId = documentId;
        this.pdfDocument = pdfDocument;
        this.scale = scale;
        this.rotate = rotate;
        this.rotationPages = rotationPages;
    }
}

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class RotationComponent {
    /**
     * @param {?} pdfRenderService
     * @param {?} log
     */
    constructor(pdfRenderService, log) {
        this.pdfRenderService = pdfRenderService;
        this.log = log;
        this.rotationStyle = {};
        this.viewerStyle = {};
        this.log.setClass('RotationComponent');
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        /** @type {?} */
        const height = `${((/** @type {?} */ (document.getElementById('pageContainer' + this.pageNumber).querySelector('.textLayer')))).style.height}`;
        this.rotationStyle = {
            'margin-top': `-${height}`
        };
        this.viewerStyle = {
            'top': `${height}`
        };
    }
    /**
     * @param {?} rotateVal
     * @return {?}
     */
    calculateRotation(rotateVal) {
        /** @type {?} */
        const circleDegrees = 360;
        return (rotateVal % circleDegrees + circleDegrees) % circleDegrees;
    }
    /**
     * @return {?}
     */
    onRotateClockwise() {
        /** @type {?} */
        const RENDER_OPTIONS = this.pdfRenderService.getRenderOptions();
        /** @type {?} */
        const rotation = RENDER_OPTIONS.rotationPages
            .find(rotatePage => rotatePage.page === this.pageNumber).rotate;
        RENDER_OPTIONS.rotationPages
            .find(rotatePage => rotatePage.page === this.pageNumber).rotate = this.calculateRotation(rotation + 90);
        this.pdfRenderService.setRenderOptions(RENDER_OPTIONS);
        this.pdfRenderService.render();
    }
}
RotationComponent.decorators = [
    { type: Component, args: [{
                selector: 'app-rotation-toolbar',
                template: "<div class=\"viewer-menu\" [ngStyle]=\"viewerStyle\">\n  <button\n    [ngStyle]=\"rotationStyle\"\n    class=\"govuk-button hmcts hmcts-button--secondary rotate\"\n    title=\"Clockwise\"\n    role=\"button\"\n    (click)=\"onRotateClockwise()\">Rotate</button>\n</div>\n",
                styles: [".viewer-menu{width:100%;position:-webkit-sticky;position:sticky;left:0}.rotate{background-repeat:no-repeat;background-size:14px 14px;background-position:3px 50%;background-image:url(/assets/images/viewer-rotate.svg);padding-left:25px;float:right}"]
            }] }
];
RotationComponent.ctorParameters = () => [
    { type: PdfRenderService },
    { type: EmLoggerService }
];
RotationComponent.propDecorators = {
    pageNumber: [{ type: Input }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class RotationFactoryService {
    /**
     * @param {?} componentFactoryResolver
     * @param {?} log
     * @param {?} injector
     * @param {?} appRef
     */
    constructor(componentFactoryResolver, log, injector, appRef) {
        this.componentFactoryResolver = componentFactoryResolver;
        this.log = log;
        this.injector = injector;
        this.appRef = appRef;
        this.log.setClass('RotationFactoryService');
    }
    /**
     * @param {?} rotationModel
     * @return {?}
     */
    addToDom(rotationModel) {
        this.log.info('Adding rotate button to PDF page ' + rotationModel.pageNumber);
        /** @type {?} */
        const componentRef = this.componentFactoryResolver
            .resolveComponentFactory(RotationComponent)
            .create(this.injector);
        componentRef.instance.pageNumber = rotationModel.pageNumber;
        this.appRef.attachView(componentRef.hostView);
        /** @type {?} */
        const domElem = (/** @type {?} */ (((/** @type {?} */ (componentRef.hostView)))
            .rootNodes[0]));
        rotationModel.pageDom.appendChild(domElem);
        return componentRef;
    }
}
RotationFactoryService.decorators = [
    { type: Injectable }
];
RotationFactoryService.ctorParameters = () => [
    { type: ComponentFactoryResolver },
    { type: EmLoggerService },
    { type: Injector },
    { type: ApplicationRef }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class AnnotationPdfViewerComponent {
    /**
     * @param {?} pdfService
     * @param {?} npaService
     * @param {?} apiHttpService
     * @param {?} annotationStoreService
     * @param {?} utils
     * @param {?} ref
     * @param {?} renderer
     * @param {?} pdfAnnotateWrapper
     * @param {?} pdfRenderService
     * @param {?} rotationFactoryService
     * @param {?} log
     */
    constructor(pdfService, npaService, apiHttpService, annotationStoreService, utils, ref, renderer, pdfAnnotateWrapper, pdfRenderService, rotationFactoryService, log) {
        this.pdfService = pdfService;
        this.npaService = npaService;
        this.apiHttpService = apiHttpService;
        this.annotationStoreService = annotationStoreService;
        this.utils = utils;
        this.ref = ref;
        this.renderer = renderer;
        this.pdfAnnotateWrapper = pdfAnnotateWrapper;
        this.pdfRenderService = pdfRenderService;
        this.rotationFactoryService = rotationFactoryService;
        this.log = log;
        this.rotationComponents = [];
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.loadAnnotations(this.annotate);
        this.pdfService.preRun();
        this.pdfRenderService.setRenderOptions(new RenderOptions(this.url, null, parseFloat('1.33'), 0, []));
        if (this.rotate) {
            this.pdfPageSubscription = this.pdfRenderService.listPagesSubject
                .subscribe((listPages) => {
                this.rotationComponents.forEach(rc => rc.destroy());
                listPages.forEach(pageDetails => {
                    this.rotationComponents.push(this.rotationFactoryService.addToDom(pageDetails));
                });
            });
        }
        this.pdfRenderService.render(this.viewerElementRef);
        this.pdfService.setAnnotationWrapper(this.annotationWrapper);
        this.pageNumberSubscription = this.pdfService.getPageNumber()
            .subscribe(page => this.page = page);
        this.focusedAnnotationSubscription = this.annotationStoreService.getAnnotationFocusSubject()
            .subscribe(focusedAnnotation => this.focusHighlightStyle(focusedAnnotation));
    }
    /**
     * @return {?}
     */
    ngAfterViewInit() {
        this.pdfAnnotateWrapper.getUi().addEventListener('annotation:click', this.handleAnnotationClick.bind(this));
    }
    /**
     * @return {?}
     */
    ngOnDestroy() {
        if (this.pageNumberSubscription) {
            this.pageNumberSubscription.unsubscribe();
        }
        if (this.focusedAnnotationSubscription) {
            this.focusedAnnotationSubscription.unsubscribe();
        }
        if (this.pdfPageSubscription) {
            this.pdfPageSubscription.unsubscribe();
        }
    }
    /**
     * @param {?} annotate
     * @return {?}
     */
    loadAnnotations(annotate) {
        if (annotate) {
            this.log.info('annotations are enabled');
            this.apiHttpService.setBaseUrl(this.baseUrl);
            this.annotationStoreService.preLoad(this.annotationSet);
            this.npaService.outputDmDocumentId.next(this.outputDmDocumentId);
        }
        else {
            this.log.info('annotations are disabled');
            this.annotationStoreService.preLoad(null);
        }
    }
    /**
     * @param {?} event
     * @param {?=} isPage
     * @return {?}
     */
    handleClick(event, isPage) {
        if (this.annotate) {
            if (!this.utils.clickIsHighlight(event)) {
                this.unfocusAnnotation();
                this.annotationStoreService.setToolBarUpdate(null, null);
            }
            this.commentsComponent.handleAnnotationBlur();
            if (isPage) {
                this.pdfService.setPageNumber(this.utils.getClickedPage(event));
            }
        }
    }
    /**
     * @return {?}
     */
    renderComments() {
        this.unfocusAnnotation();
        this.commentsComponent.showAllComments();
    }
    /**
     * @return {?}
     */
    unfocusAnnotation() {
        this.annotationStoreService.setAnnotationFocusSubject(new Annotation());
        this.annotationStoreService.setCommentBtnSubject(null);
        this.annotationStoreService.setCommentFocusSubject(new Annotation(), null);
    }
    /**
     * @param {?} event
     * @return {?}
     */
    handleAnnotationClick(event) {
        if (!this.contextualToolbar.isShowToolbar) {
            /** @type {?} */
            const annotationId = event.getAttribute('data-pdf-annotate-id');
            this.annotationStoreService.getAnnotationById(annotationId)
                .then((annotation) => {
                this.annotationStoreService.setAnnotationFocusSubject(annotation);
                this.annotationStoreService.setCommentFocusSubject(annotation);
                this.annotationStoreService.setToolBarUpdate(annotation, true);
            });
        }
    }
    /**
     * @param {?} focusedAnnotation
     * @return {?}
     */
    focusHighlightStyle(focusedAnnotation) {
        Array.from(this.viewerElementRef.nativeElement.querySelector(`#pageContainer${this.page} .annotationLayer`).childNodes)
            .forEach((annotationDom) => {
            if (annotationDom.dataset.pdfAnnotateId === focusedAnnotation.id) {
                this.renderer.addClass(annotationDom, 'comment-selected');
            }
            else {
                this.renderer.removeClass(annotationDom, 'comment-selected');
            }
        });
        if (!this.ref['destroyed']) {
            this.ref.detectChanges();
        }
    }
}
AnnotationPdfViewerComponent.decorators = [
    { type: Component, args: [{
                selector: 'app-annotation-pdf-viewer',
                template: "\n<app-comments (click)=\"handleClick($event, false)\" #commentsComponent\n              *ngIf=\"annotate\"></app-comments>\n\n<div id=\"annotation-wrapper\" #annotationWrapper>\n  <app-contextual-toolbar (deletedAnnotation)=\"renderComments()\" #contextualToolbar></app-contextual-toolbar>\n\n  <div id=\"content-wrapper\"\n       #contentWrapper\n       (click)=\"handleClick($event, true)\">\n    <div id=\"viewer\" #viewer class=\"pdfViewer\"></div>\n  </div>\n</div>\n",
                styles: ["#annotation-wrapper{position:relative;width:100%}#content-wrapper{overflow:hidden}"]
            }] }
];
AnnotationPdfViewerComponent.ctorParameters = () => [
    { type: PdfService },
    { type: NpaService },
    { type: ApiHttpService },
    { type: AnnotationStoreService },
    { type: Utils },
    { type: ChangeDetectorRef },
    { type: Renderer2 },
    { type: PdfAnnotateWrapper },
    { type: PdfRenderService },
    { type: RotationFactoryService },
    { type: EmLoggerService }
];
AnnotationPdfViewerComponent.propDecorators = {
    annotate: [{ type: Input }],
    dmDocumentId: [{ type: Input }],
    outputDmDocumentId: [{ type: Input }],
    url: [{ type: Input }],
    annotationSet: [{ type: Input }],
    baseUrl: [{ type: Input }],
    rotate: [{ type: Input }],
    contentWrapper: [{ type: ViewChild, args: ['contentWrapper',] }],
    viewerElementRef: [{ type: ViewChild, args: ['viewer',] }],
    annotationWrapper: [{ type: ViewChild, args: ['annotationWrapper',] }],
    commentsComponent: [{ type: ViewChild, args: ['commentsComponent',] }],
    contextualToolbar: [{ type: ViewChild, args: ['contextualToolbar',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class ImageViewerComponent {
    /**
     * @param {?} renderer
     * @param {?} log
     */
    constructor(renderer, log) {
        this.renderer = renderer;
        this.log = log;
        this.log.setClass('ImageViewerComponent');
    }
    /**
     * @return {?}
     */
    ngOnInit() {
        this.rotation = 0;
    }
    /**
     * @return {?}
     */
    onRotateClockwise() {
        this.rotation = this.rotation + 90;
        this.rotateImage();
    }
    /**
     * @return {?}
     */
    rotateImage() {
        this.log.info('rotating to-' + this.rotation + 'degrees');
        /** @type {?} */
        const styles = ['transform', '-ms-transform', '-o-transform', '-moz-transform', '-webkit-transform'];
        for (const style of styles) {
            this.renderer.setStyle(this.img.nativeElement, style, `rotate(${this.rotation}deg)`);
        }
    }
}
ImageViewerComponent.decorators = [
    { type: Component, args: [{
                selector: 'app-image-viewer',
                template: "\n    <div id=\"viewer-wrapper\">\n        <button\n          *ngIf=\"rotate\"\n          class=\"govuk-button hmcts hmcts-button--secondary rotate\"\n          title=\"Clockwise\"\n          role=\"button\"\n          (click)=\"onRotateClockwise()\">Rotate</button>\n\n        <img #img *ngIf=\"url\" data-hook=\"dm.viewer.img\" [src]=\"url\"  />\n    </div>",
                styles: ["#viewer-wrapper{position:relative;width:100%}.rotate{z-index:1;position:absolute;right:0;background-repeat:no-repeat;background-size:14px 14px;background-position:3px 50%;padding-left:25px;background-image:url(/assets/images/viewer-rotate.svg)}.anti{right:24px;-webkit-transform:scaleX(-1);transform:scaleX(-1)}img{width:100%}"]
            }] }
];
ImageViewerComponent.ctorParameters = () => [
    { type: Renderer2 },
    { type: EmLoggerService }
];
ImageViewerComponent.propDecorators = {
    url: [{ type: Input }],
    originalUrl: [{ type: Input }],
    rotate: [{ type: Input }],
    img: [{ type: ViewChild, args: ['img',] }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class UnsupportedViewerComponent {
    constructor() { }
    /**
     * @return {?}
     */
    ngOnInit() {
    }
}
UnsupportedViewerComponent.decorators = [
    { type: Component, args: [{
                selector: 'app-unsupported-viewer',
                template: "<p data-hook=\"dm.viewer.unsupported\">\n  This file type is not supported. Please <a href=\"{{url}}\">click here to download</a>.\n</p>\n",
                styles: [""]
            }] }
];
UnsupportedViewerComponent.ctorParameters = () => [];
UnsupportedViewerComponent.propDecorators = {
    url: [{ type: Input }],
    originalUrl: [{ type: Input }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class UrlFixerService {
    /**
     * @param {?} url
     * @param {?} baseUrl
     * @return {?}
     */
    fixDm(url, baseUrl) {
        return url.replace(/http.*\/documents\//, `${baseUrl}/documents/`);
    }
}
UrlFixerService.decorators = [
    { type: Injectable }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class ViewerFactoryService {
    /**
     * @param {?} componentFactoryResolver
     * @param {?} annotationStoreService
     * @param {?} urlFixer
     * @param {?} log
     */
    constructor(componentFactoryResolver, annotationStoreService, urlFixer, log) {
        this.componentFactoryResolver = componentFactoryResolver;
        this.annotationStoreService = annotationStoreService;
        this.urlFixer = urlFixer;
        this.log = log;
        this.log.setClass('ViewerFactoryService');
    }
    /**
     * @private
     * @param {?} mimeType
     * @return {?}
     */
    static determineComponent(mimeType) {
        if (ViewerFactoryService.isImage(mimeType)) {
            return ImageViewerComponent;
        }
        return UnsupportedViewerComponent;
    }
    /**
     * @private
     * @param {?} mimeType
     * @return {?}
     */
    static isImage(mimeType) {
        return mimeType.startsWith('image/') || mimeType === 'image';
    }
    /**
     * @private
     * @param {?} mimeType
     * @return {?}
     */
    static isPdf(mimeType) {
        return mimeType === 'application/pdf' || mimeType === 'pdf';
    }
    /**
     * @param {?} documentMetaData
     * @return {?}
     */
    getDocumentId(documentMetaData) {
        /** @type {?} */
        const docArray = documentMetaData._links.self.href.split('/');
        return docArray[docArray.length - 1];
    }
    /**
     * @param {?} viewContainerRef
     * @param {?} contentType
     * @param {?} url
     * @param {?} baseUrl
     * @param {?} originalUrl
     * @param {?} annotate
     * @param {?} annotationSet
     * @param {?} rotate
     * @return {?}
     */
    buildComponent(viewContainerRef, contentType, url, baseUrl, originalUrl, annotate, annotationSet, rotate) {
        if (ViewerFactoryService.isPdf(contentType) && annotate) {
            this.log.info('Selected pdf viewer with annotations enabled');
            return this.buildAnnotateUi(url, viewContainerRef, baseUrl, annotate, annotationSet, rotate);
        }
        else if (ViewerFactoryService.isPdf(contentType) && !annotate) {
            this.log.info('Selected pdf viewer with annotations disabled');
            return this.buildAnnotateUi(url, viewContainerRef, baseUrl, annotate, null, rotate);
        }
        else if (ViewerFactoryService.isImage(contentType)) {
            this.log.info('Selected image viewer');
            return this.createComponent(ImageViewerComponent, viewContainerRef, originalUrl, url, rotate);
        }
        else {
            this.log.info('Unsupported type for viewer');
            return this.createComponent(UnsupportedViewerComponent, viewContainerRef, originalUrl, url);
        }
    }
    /**
     * @param {?} url
     * @param {?} viewContainerRef
     * @param {?} baseUrl
     * @param {?} annotate
     * @param {?} annotationSet
     * @param {?} rotate
     * @return {?}
     */
    buildAnnotateUi(url, viewContainerRef, baseUrl, annotate, annotationSet, rotate) {
        viewContainerRef.clear();
        /** @type {?} */
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(AnnotationPdfViewerComponent);
        /** @type {?} */
        const componentRef = viewContainerRef.createComponent(componentFactory);
        componentRef.instance.annotate = annotate;
        componentRef.instance.annotationSet = annotationSet;
        componentRef.instance.outputDmDocumentId = null; // '4fbdde23-e9a7-4843-b6c0-24d5bf2140ab';
        componentRef.instance.baseUrl = baseUrl;
        componentRef.instance.url = url;
        componentRef.instance.rotate = rotate;
        return componentRef.instance;
    }
    /**
     * @param {?} component
     * @param {?} viewContainerRef
     * @param {?} originalUrl
     * @param {?} url
     * @param {?=} rotate
     * @return {?}
     */
    createComponent(component, viewContainerRef, originalUrl, url, rotate) {
        /** @type {?} */
        const componentFactory = this.componentFactoryResolver.resolveComponentFactory(component);
        viewContainerRef.clear();
        /** @type {?} */
        const componentRef = viewContainerRef.createComponent(componentFactory);
        componentRef.instance.originalUrl = originalUrl;
        componentRef.instance.url = url;
        componentRef.instance.rotate = rotate;
        return componentRef.instance;
    }
}
ViewerFactoryService.decorators = [
    { type: Injectable }
];
ViewerFactoryService.ctorParameters = () => [
    { type: ComponentFactoryResolver },
    { type: AnnotationStoreService },
    { type: UrlFixerService },
    { type: EmLoggerService }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class ViewerAnchorDirective {
    /**
     * @param {?} viewContainerRef
     */
    constructor(viewContainerRef) {
        this.viewContainerRef = viewContainerRef;
    }
}
ViewerAnchorDirective.decorators = [
    { type: Directive, args: [{
                selector: '[appViewerAnchor]',
            },] }
];
ViewerAnchorDirective.ctorParameters = () => [
    { type: ViewContainerRef }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class DocumentViewerService {
    /**
     * @param {?} log
     * @param {?} httpClient
     * @param {?} state
     */
    constructor(log, httpClient, state) {
        this.log = log;
        this.httpClient = httpClient;
        this.state = state;
        log.setClass('DocumentViewerService');
    }
    /**
     * @param {?} documentUri
     * @return {?}
     */
    getDocumentMetadata(documentUri) {
        /** @type {?} */
        const key = makeStateKey(documentUri);
        /** @type {?} */
        const cache = this.state.get(key, (/** @type {?} */ (null)));
        if (cache) {
            return of(cache);
        }
        return this.httpClient
            .get(documentUri)
            .pipe(map(data => {
            this.state.set(key, data);
            return data;
        }))
            .pipe(catchError(error => {
            /** @type {?} */
            const value = { error };
            this.state.set(key, value);
            this.log.error('Encountered error while downloading document:' + documentUri + '-' + error);
            return of(value);
        }));
    }
}
DocumentViewerService.decorators = [
    { type: Injectable, args: [{
                providedIn: 'root'
            },] }
];
DocumentViewerService.ctorParameters = () => [
    { type: EmLoggerService },
    { type: HttpClient },
    { type: TransferState }
];
/** @nocollapse */ DocumentViewerService.ngInjectableDef = defineInjectable({ factory: function DocumentViewerService_Factory() { return new DocumentViewerService(inject(EmLoggerService), inject(HttpClient), inject(TransferState)); }, token: DocumentViewerService, providedIn: "root" });

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class DocumentViewerComponent {
    /**
     * @param {?} log
     * @param {?} viewerFactoryService
     * @param {?} annotationStoreService
     * @param {?} urlFixer
     * @param {?} documentViewerService
     */
    constructor(log, viewerFactoryService, annotationStoreService, urlFixer, documentViewerService) {
        this.log = log;
        this.viewerFactoryService = viewerFactoryService;
        this.annotationStoreService = annotationStoreService;
        this.urlFixer = urlFixer;
        this.documentViewerService = documentViewerService;
        this.url = '';
        this.rotate = false;
        log.setClass('DocumentViewerComponent');
    }
    /**
     * @return {?}
     */
    ngOnInit() {
    }
    /**
     * @param {?} changes
     * @return {?}
     */
    ngOnChanges(changes) {
        if (changes.url || changes.annotate) {
            this.buildViewer();
        }
    }
    /**
     * @return {?}
     */
    buildViewer() {
        if (!this.url) {
            this.log.error('url is required argument');
            throw new Error('url is required argument');
        }
        if (this.isDM) {
            this.documentViewerService.getDocumentMetadata(`${this.urlFixer.fixDm(this.url, this.baseUrl)}`).subscribe(metadata => {
                this.log.info(metadata);
                if (metadata && metadata._links) {
                    /** @type {?} */
                    const url = this.urlFixer.fixDm(metadata._links.binary.href, this.baseUrl);
                    /** @type {?} */
                    const dmDocumentId = this.viewerFactoryService.getDocumentId(metadata);
                    if (this.annotate) {
                        this.annotationStoreService.getAnnotationSet(this.baseUrl, dmDocumentId).subscribe(annotationSet => {
                            this.buildComponent(metadata, url, annotationSet.body);
                        });
                    }
                    else {
                        this.buildComponent(metadata, url, null);
                    }
                }
            }, err => {
                this.log.error('An error has occured while fetching document' + err);
                this.error = err;
            });
        }
        else {
            this.viewerComponent = this.viewerFactoryService.buildComponent(this.viewerAnchor.viewContainerRef, this.contentType, this.url, this.baseUrl, this.url, this.annotate, null, this.rotate);
        }
    }
    /**
     * @param {?} metadata
     * @param {?} url
     * @param {?=} annotationSet
     * @return {?}
     */
    buildComponent(metadata, url, annotationSet) {
        this.viewerFactoryService.buildComponent(this.viewerAnchor.viewContainerRef, metadata.mimeType, url, this.baseUrl, metadata._links.self.href, this.annotate, annotationSet, this.rotate);
    }
}
DocumentViewerComponent.decorators = [
    { type: Component, args: [{
                selector: 'app-document-viewer',
                template: "\n<ng-template appViewerAnchor></ng-template>\n\n<div class=\"grid-row\">\n  <div *ngIf=\"error\"  class=\"error-summary\" role=\"alert\" aria-labelledby=\"error-summary-heading-example-1\" tabindex=\"-1\">\n    <h2 class=\"heading-medium error-summary-heading\" id=\"error-summary-heading-example-1\">There was an error while loading your document.</h2>\n    <p>Response status was {{error.status}}.</p>\n  </div>\n</div>\n\n"
            }] }
];
DocumentViewerComponent.ctorParameters = () => [
    { type: EmLoggerService },
    { type: ViewerFactoryService },
    { type: AnnotationStoreService },
    { type: UrlFixerService },
    { type: DocumentViewerService }
];
DocumentViewerComponent.propDecorators = {
    viewerAnchor: [{ type: ViewChild, args: [ViewerAnchorDirective,] }],
    url: [{ type: Input }],
    annotate: [{ type: Input }],
    baseUrl: [{ type: Input }],
    isDM: [{ type: Input }],
    contentType: [{ type: Input }],
    rotate: [{ type: Input }]
};

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */
class HmctsEmViewerUiModule {
}
HmctsEmViewerUiModule.decorators = [
    { type: NgModule, args: [{
                imports: [
                    NgtUniversalModule,
                    CommonModule,
                    FormsModule,
                    HttpClientModule
                ],
                declarations: [
                    CommentsComponent,
                    CommentItemComponent,
                    ContextualToolbarComponent,
                    AnnotationPdfViewerComponent,
                    ImageViewerComponent,
                    UnsupportedViewerComponent,
                    DocumentViewerComponent,
                    ViewerAnchorDirective,
                    RotationComponent
                ],
                entryComponents: [
                    AnnotationPdfViewerComponent,
                    ImageViewerComponent,
                    UnsupportedViewerComponent,
                    RotationComponent
                ],
                providers: [
                    PdfAnnotateWrapper,
                    PdfWrapper,
                    PdfService,
                    AnnotationStoreService,
                    PdfAdapter,
                    NpaService,
                    ApiHttpService,
                    Utils,
                    UrlFixerService,
                    ViewerFactoryService,
                    DocumentViewerService,
                    RotationFactoryService,
                    PdfRenderService,
                    EmLoggerService
                ],
                exports: [
                    DocumentViewerComponent
                ]
            },] }
];

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

/**
 * @fileoverview added by tsickle
 * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
 */

export { HmctsEmViewerUiModule, AnnotationStoreService as ɵb, ApiHttpService as ɵf, PdfAnnotateWrapper as ɵh, PdfWrapper as ɵj, NpaService as ɵn, PdfAdapter as ɵd, PdfRenderService as ɵi, PdfService as ɵg, UrlFixerService as ɵu, Utils as ɵe, DocumentViewerComponent as ɵr, DocumentViewerService as ɵv, ViewerAnchorDirective as ɵs, EmLoggerService as ɵc, AnnotationPdfViewerComponent as ɵm, CommentItemComponent as ɵk, CommentsComponent as ɵa, ContextualToolbarComponent as ɵl, RotationFactoryService as ɵo, RotationComponent as ɵw, ImageViewerComponent as ɵp, UnsupportedViewerComponent as ɵq, ViewerFactoryService as ɵt };

//# sourceMappingURL=hmcts-annotation-ui-lib.js.map