{"version":3,"sources":["../js/Common.js"],"names":["eAnnotationHandleTypes","DragRect","DeleteButton","LeftResize","RightResize","TopResize","BottomResize","CreateNewAnnotation","sortAlphabetical","a","b","DocumentName","toLowerCase","sortAnnotationCoords","returnXMin","returnXMax","returnYMin","returnYMax","eApproverType","Individual","Group","Hidden","eApproverStatus","Pending","Approved","ApprovedChanges","Rejected","eApprovalStatus","AwaitingMyReview","eCompareMode","NoCompare","Blink","Overlay","SliderHorizontal","SliderVertical","SideBySide","SideBySideDiff","DifferencesOnly","eDocumentTypes","PDF","Image","ThreeD","Office","SVG","AnnotationAttachment","AI","CopyMagic","eRetrievalSource","ApprovalId","DocumentPageId","DocumentId","eCanvasType","Artwork","Annotation","eMessageType","Success","Error","eAnnotationDivType","Popup","ListItem","eAnnotationTypes","Postit","Freedraw","Rectangle","Ellipse","Line","Global","TextMeasurement","PointToPointMeasurement","AreaMeasurement","HorizontalCalliperMeasurement","VerticalCalliperMeasurement","ColourDensityMeasurement","BarcodeMeasurement","ColourDensityMeasurementPostit","SVGRectangle","SVGEllipse","SVGPolygon","TextHighlight","TextClassification","eAnnotationColours","blue","red","green","orange","purple","cyan","magenta","yellow","grey","eAnnotationStatuses","Initial","Query","ToDo","eAnnotationStatusUpdateType","addStatus","deleteStatus","updateStatus","eFieldTypes","AnnotationMainHeader","ReplyHeader","StatusHeader","DifferenceHeader","eKeyboardShorcutBehaviours","ZoomIn","ZoomOut","ZoomReset","Pan","PanTextCompare","eWheelZoomType","Static","Centered","Smart","eZoomSpeed","Slow","Medium","Fast","eZoomIncrements","Smallest","Small","Large","Largest","eAlignmentType","OnRequest","Always","eHighlightType","LeftToRight","RightToLeft","eSVGNodeType","None","PointText","AreaText","PathText","eSVGBoundingElementType","Polygon","eReviewType","ReadOnly","Approver","Sheriff","events","g_oActiveBubbles","g_iActiveBubbleId","g_iBubbleCloseSeconds","ActiveBubble","id","type","displayTop","autoClose","this","displayDate","Date","addDomElement","src","className","title","clickFunction","destination","dataAttribute","dataAttributeValue","element","createDomElement","appendChild","prependDomElement","prepend","document","createElement","length","onclick","setAttribute","addPlaceholderToTextbox","input","placeholderText","$","val","on","e","value","changeCanvasFunction","eventType","functionToBind","undefined","clearCanvasBindings","clearElementBindings","bindFunctionToElement","off","g_oViewer","g_oArtworkViewer","g_oDoc","documentType","oAnnotationCanvas","getCanvas","target","oArtworkCanvas","getLinkedArtworkCanvas","g_oAnnotations","findAnnotation","AnnotationAction","prototype","mouseMove","mouseMoveLite","handleClick","g_oTextCompare","g_bTextCompareInProgress","findThreeDAnnotations","documentDisplaysAsPDF","documentDisplaysAsSVG","documentHasSeparations","documentPages","MeasurementInMM","num","g_oSettings","g_oUserSettings","UseMetricUnits","Number","DelimitNum","decimalPoints","i","toFixed","GetElementId","scrollElement","time","stop","animate","scrollTop","AscendingOrder","clearHighlightSelectedButton","elem","removeClass","convertUTCDateToLocal","utcDate","moment","utc","local","format","debounce","func","wait","immediate","timeout","context","args","arguments","callNow","clearTimeout","setTimeout","apply","deepCopyArray","oldArray","jQuery","extend","deepCopyObject","oldObject","displayErrorContentHTML","errors","szHTML","Array","isArray","errorDescription","displayErrorResultHTML","errorMessage","formatDate","oDateElements","isNothing","c_szDateFormat","split","szDate","toUpperCase","substring","generateGuid","s4","Math","floor","random","toString","getClientHeight","window","height","getClientWidth","width","getScrollAmountY","highlightSelectedButton","removeCurrentHighlight","removeExistingHighlights","addClass","highlightButtonClearingAllIcons","string","isNumeric","required","szTxt","iLen","aChar","notSelector","not","c_bFindSVGText","slideToggle","resizeViewerCell","iWidth","iHeight","css","calculateSlideOutDivSize","slideDiv","leftMenu","toggle","iCanvasWidth","iCanvasHeight","divWidth","children","g_oCompare","g_bAlignmentModeActive","iLeftPos","parseInt","iTargetLeftPos","bSlideOut","bRotate","LeftMenuCollapse","RightMenuCollapse","iAnimateLeft","show","left","hide","resizeSeparationListItems","reziseChecklistItems","resizeAnnotationListItems","isEmptyObject","getAnnotationCanvasId","redraw","iAnnotationsListHeight","offsetHeight","iSeparationsListHeight","iChecklistListHeight","swapImage","imgElement","newImageSrc","exists","attr","lockScreen","fadeIn","unlockScreen","fadeOut","showSpinnerMessage","message","html","hideSpinnerMessage","displayPopupWindow","div","percentX","percentY","calculateContentPositions","flatten","array","concat","hidePopupWindow","getScrollAmountX","scrollLeft","dragOverFile","preventDefault","stopPropagation","dragLeaveFile","droppedFile","g_oAnnotationAttachments","setUploadingStatus","dt","dataTransfer","addAnnotationAttachments","files","x","y","switched","idivHeight","idivWidth","iTop","calculateCentralYCoordinate","iLeft","calculateCentralXCoordinate","round","oPopup","top","oPopupContent","iHeaderHeight","has","mainHeight","header","find","elementExistsAndIsVisible","is","objectHeight","objectWidth","exp","isNaN","NaN","addFloats","subtractFloats","isInt","parseFloat","contains","R1_x","R1_y","R1_w","R1_h","R2_x","R2_y","R2_w","R2_h","getClickCoords","event","oViewer","clientX","body","getElementById","g_szCanvasId","documentElement","clientY","rect","g_oCanvas","getBoundingClientRect","c_iDPI","getAnimationFramesForZoomSpeed","zoomSpeed","getZoomMultiplierForZoomIncrement","zoomIncrement","fakeClickCoords","findClickCanvasCoordinates","oAnnotationsUI","oCoords","getClick","iCompareOffset","calculateCompareOffsetInPx","g_iRotDegrees","g_iScaledImageHeight","g_iScaledImageWidth","Seperation","SeperationName","Red","Green","Blue","Opaque","OriginalRed","OriginalGreen","OriginalBlue","OriginalOpaque","ImageWidth","ImageHeight","Visable","WidthResolution","HeightResolution","ImageDimensions","MinX","MinY","MaxX","MaxY","ImageObject","Width","Height","ImageBox","RequestApproval","RequestedPage","RequestedImageObject","ImagePercentages","UserImageObject","CompareImageObject","ScaledImageObject","CompareOffsetX","CompareOffsetY","CompareRotationDegrees","VisibleSeparations","ImageRequest","SessionId","OriginalResolution","CompareMode","ImageRequestName","ArtworkViewerImageBox","CompareViewerImageBox","IsCompareImageRequest","CompareGhosting","CompareTolerance","IsGetNewImageCallType","OverrideSingleColourChange","ExamineImageRequest","Dimensions","ApprovalID","PageNumber","ExamTypeCode","g_oTechTools","g_eExamTypes","COLOURDENSITY","CurrentResolution","RealtimeRenderReference","AnnotationID","FullImageHeight","FullImageWidth","SeparationName","CodeType","CodeData","DisplayText","MarqueeCoordinates","widthMagnification","X","Y","GetFileNameWithoutExtension","FileName","lastIndexOf","ProcessApiError","xhr","textStatus","bNoFormatting","szMessage","status","responseJSON","Message","g_oGreenlightMessages","c_szUnauthorisedMessage","responseText","displayErrorBubble","matrix_invert","M","ii","j","dim","I","C","convertColourHexToRGB","szHex","result","exec","r","g","convertColourToRBG","szRGB","replace","convertRGBToSRGB","oRGB","convertRGBToHex","max","min","convertRGBComponentToHex","c","hex","calculateLuminance","oSRGB","pow","isIE","ua","navigator","userAgent","msie","indexOf","trident","dtNow","parents","closeBubble","log2","log","LOG2E","String","Element","Document","DocumentFragment","forEach","item","hasOwnProperty","Object","defineProperty","configurable","enumerable","writable","argArr","slice","call","docFrag","createDocumentFragment","argItem","isNode","Node","createTextNode","insertBefore","firstChild"],"mappings":"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","file":"Common-6f2920b63d.js","sourcesContent":["/*\r\n* Copyright (c) 2017 SGS Europe. All rights reserved.\r\n*\r\n* This program is the CONFIDENTIAL and PROPRIETARY property of 2017 SGS Europe.\r\n* Any unauthorised use, reproduction, or transfer of this program is strictly\r\n* prohibited.\r\n*\r\n* File Name:\tCommon.js\r\n*\r\n* Description:\tCommon JavaScript functions between all objects.\r\n*\r\n* History:\t\t01-AUG-17\tJ Fuller\tInitial implementation.\r\n*\t\t\t\t22-NOV-17\tM Sherer\tChanges for the Greenlight Annotation Module (DR207).\r\n*\t\t\t\t14-DEC-17\tN Settle\tAdded a rounding function for the Greenlight Tech Tools Module (DR208).\r\n*\t\t\t\t19-JAN-18\tN Settle\tAdded TextMeasurement Annotation Type to the eAnnotationTypes enumerator (DR208).\r\n*\t\t\t\t14-FEB-18\tJ Fuller\tAdded warning bubble and function to add placeholder text to input box.\r\n*\t\t\t\t21-FEB-18\tP Raper\t\tAdded lockScreen() and formatDate() as part of UAT enhancements.\r\n*\t\t\t\t06-MAR-18\tN Settle\tModified the slideDiv() function to take a boolean parameter to control whether the canvas is redrawn after the animate (DR208).\r\n*\t\t\t\t28-MAR-18\tN Settle\tMade the Pan function re-render the Barcode Measurement details so that it can move it into a better position to view (DR208).\r\n*\t\t\t\t12-OCT-18\tS Dervey\tAdded eKeyboardShorcutBehaviours (GL205006).\r\n*\t\t\t\t16-OCT-18\tJ Swan\t\tAdded eAppovalStatus enum (GL205006)\r\n*\t\t\t\t07-NOV-18 S Norman Added functions to display a pop-up window within greenlight. (DR212)\r\n* \t\t\t19-NOV-18 R Pavolas Moved bubble logic to new file,\tchanged the default changeCanvasFunction(), added ColourDensityPostit annotation type (DR158989).\r\n*\t\t\t\t05-DEC-18\tN Alexander\tModified formatDate to apply a full date time format or time format if either is missing.\r\n*\t\t\t\t07-DEC-18\tP Dickson\tAdded high pixel density support. (Feature 5334)\r\n*\t\t\t\t30-MAY-19\tP Dickson\tImplemented the SVG text functionality.\r\n*\t\t\t\t20-JAN-20\tS Norman\tAdded drag, drop attachments functions, resize attachment pop-up functions\r\n*\t\t\t\t\t\t\t\t\t\tand general clean-up as part of UserStory 43113 - Upload Documents to Annotations)\r\n*\t\t\t 22-JAN-20 P Raper Added generic method for processing API responses.\r\n*\t\t\t 05-FEB-20\tR Pavolas\tAdded a bunch of helper methods and refactored changeCanvasFunction\r\n*\t\t\t 22-APR-20\tJ Morris\tAdded a prependDomElement function for adding new elements at the beginning of containers.\r\n*/\r\n\r\n/*\r\n * - - - G L O B A L V A R I A B L E S - - -\r\n */\r\n\r\nvar eAnnotationHandleTypes = {\r\n\tDragRect: 0,\r\n\tDeleteButton: 1,\r\n\tLeftResize: 2,\r\n\tRightResize: 3,\r\n\tTopResize: 4,\r\n\tBottomResize: 5,\r\n\tCreateNewAnnotation: 6\r\n};\r\n\r\n/**\r\n * Sort documents alphabetically.\r\n * @param {any} a - first parameter a\r\n * @param {any} b - Second parameter B\r\n * @returns {object} - sorted document\r\n */\r\nfunction sortAlphabetical(a, b) {\r\n\treturn a.DocumentName.toLowerCase() > b.DocumentName.toLowerCase() ? 1 : -1;\r\n}\r\n\r\n// Sorts annotation coordinates min/max of x or y.\r\nvar sortAnnotationCoords = {\r\n\treturnXMin: function (a, b) {\r\n\t\treturn a[0] - b[0];\r\n\t},\r\n\treturnXMax: function (a, b) {\r\n\t\treturn b[0] - a[0];\r\n\t},\r\n\treturnYMin: function (a, b) {\r\n\t\treturn a[1] - b[1];\r\n\t},\r\n\treturnYMax: function (a, b) {\r\n\t\treturn b[1] - a[1];\r\n\t}\r\n};\r\n\r\nvar eApproverType = {\r\n\tIndividual: 1,\r\n\tGroup: 2,\r\n\tHidden: 3\r\n}\r\n\r\nvar eApproverStatus = {\r\n\tPending: 0,\r\n\tApproved: 1,\r\n\tApprovedChanges: 2,\r\n\tRejected: 3\r\n};\r\n\r\nvar eApprovalStatus = {\r\n\tPending: 0,\r\n\tApproved: 1,\r\n\tApprovedChanges: 2,\r\n\tRejected: 3,\r\n\tAwaitingMyReview: 4\r\n};\r\n\r\nvar eCompareMode = {\r\n\tNoCompare: 0,\r\n\tBlink: 1,\r\n\tOverlay: 2,\r\n\tSliderHorizontal: 3,\r\n\tSliderVertical: 4,\r\n\tSideBySide: 5,\r\n\tSideBySideDiff: 6,\r\n\tDifferencesOnly: 7\r\n};\r\n\r\nvar eDocumentTypes = {\r\n\tPDF: 1,\r\n\tImage: 2,\r\n\tThreeD: 3,\r\n\tOffice: 4,\r\n\tSVG: 5,\r\n\tAnnotationAttachment: 6,\r\n\tAI: 7,\r\n\tCopyMagic: 8\r\n};\r\n\r\nvar eRetrievalSource = {\r\n\tApprovalId: 1,\r\n\tDocumentPageId: 2,\r\n\tDocumentId: 3\r\n};\r\n\r\nvar eCanvasType = {\r\n\tArtwork: 1,\r\n\tAnnotation: 2\r\n};\r\n\r\nvar eMessageType = {\r\n\tSuccess: 1,\r\n\tError: 2\r\n};\r\n\r\nvar eAnnotationDivType = {\r\n\tPopup: 1,\r\n\tListItem: 2\r\n};\r\n\r\nvar eAnnotationTypes = {\r\n\tPostit: 0,\r\n\tFreedraw: 1,\r\n\tRectangle: 2,\r\n\tEllipse: 3,\r\n\tLine: 4,\r\n\tGlobal: 5,\r\n\tThreeD: 6,\r\n\tTextMeasurement: 7,\r\n\tPointToPointMeasurement: 8,\r\n\tAreaMeasurement: 9,\r\n\tHorizontalCalliperMeasurement: 10,\r\n\tVerticalCalliperMeasurement: 11,\r\n\tColourDensityMeasurement: 12,\r\n\tBarcodeMeasurement: 13,\r\n\tColourDensityMeasurementPostit: 14,\r\n\tSVGRectangle: 15,\r\n\tSVGEllipse: 16,\r\n\tSVGPolygon: 17,\r\n\tTextHighlight: 18,\r\n\tTextClassification: 19\r\n};\r\n\r\nvar eAnnotationColours = {\r\n\tblue: \"#0000FF\",\r\n\tred: \"#FF0000\",\r\n\tgreen: \"#008000\",\r\n\torange: \"#FFA500\",\r\n\tpurple: \"#800080\",\r\n\tcyan: \"#00FFFF\",\r\n\tmagenta: \"#FF00FF\",\r\n\tyellow: \"#FFFF00\",\r\n\tgrey: \"#999999\"\r\n};\r\n\r\nvar eAnnotationStatuses = {\r\n\tInitial: 0,\r\n\tApproved: 1,\r\n\tRejected: 2,\r\n\tQuery: 3,\r\n\tToDo: 4\r\n};\r\n\r\nvar eAnnotationStatusUpdateType = {\r\n\taddStatus: 1,\r\n\tdeleteStatus: 2,\r\n\tupdateStatus: 3\r\n};\r\n\r\nvar eFieldTypes = {\r\n\tAnnotationMainHeader: 0,\r\n\tReplyHeader: 1,\r\n\tStatusHeader: 2,\r\n\tDifferenceHeader: 3,\r\n\tCopyMagic: 4\r\n};\r\n\r\nvar eKeyboardShorcutBehaviours = {\r\n\tZoomIn: 1,\r\n\tZoomOut: 2,\r\n\tZoomReset: 3,\r\n\tPan: 4,\r\n\tPanTextCompare: 5\r\n};\r\n\r\nvar eWheelZoomType = {\r\n\tStatic: 1,\r\n\tCentered: 2,\r\n\tSmart: 3\r\n};\r\n\r\nvar eZoomSpeed = {\r\n\tSlow: 1,\r\n\tMedium: 2,\r\n\tFast: 3\r\n};\r\n\r\nvar eZoomIncrements = {\r\n\tSmallest: 1,\r\n\tSmall: 2,\r\n\tMedium: 3,\r\n\tLarge: 4,\r\n\tLargest: 5\r\n};\r\n\r\nvar eAlignmentType = {\r\n\tOnRequest: 1,\r\n\tAlways: 2\r\n};\r\n\r\nvar eHighlightType = {\r\n\tLeftToRight: 1,\r\n\tRightToLeft: 2\r\n};\r\n\r\nvar eSVGNodeType = {\r\n\tNone: 0,\r\n\tPointText: 1,\r\n\tAreaText: 2,\r\n\tPathText: 3\r\n};\r\n\r\nvar eSVGBoundingElementType = {\r\n\tNone: 0,\r\n\tRectangle: 1,\r\n\tEllipse: 2,\r\n\tPolygon: 3\r\n};\r\n\r\nvar eReviewType = {\r\n\tReadOnly: 1,\r\n\tApprover: 2,\r\n\tSheriff: 3\r\n};\r\n\r\n// JQuery PEP setup to allow touch events\r\nvar events = [\r\n // base events\r\n 'click',\r\n 'pointerdown',\r\n 'pointerup',\r\n 'pointermove',\r\n 'pointerover',\r\n 'pointerout',\r\n 'pointerenter',\r\n 'pointerleave'\r\n];\r\n\r\n// Active Bubbles.\r\nvar g_oActiveBubbles = [];\r\n\r\n// Keeps track of the next id to be used for the active bubble.\r\nvar g_iActiveBubbleId = 1;\r\n\r\n// The number of seconds before a static bubble will auto-hide.\r\nvar g_iBubbleCloseSeconds = 5;\r\n\r\n/**\r\n * Creates a new active bubble object.\r\n * @param {int} id - The id of the bubble.\r\n * @param {string} type - The type of bubble.\r\n * @param {bool} displayTop - If the bubble should be displayed at the top of the screen.\r\n * @param {bool} autoClose - If the bubble should auto close.\r\n */\r\nfunction ActiveBubble(id, type, displayTop, autoClose) {\r\n\tthis.id = id;\r\n\tthis.type = type;\r\n\tthis.displayTop = displayTop;\r\n\tthis.autoClose = autoClose;\r\n\tthis.displayDate = new Date();\r\n}\r\n\r\n/*\r\n * - - - P U B L I C M E T H O D S - - -\r\n */\r\n\r\n/**\r\n * Adds a DOM Element to the Canvas\r\n * @param {int} id - ID of the notification\r\n * @param {string} type - Type of Action the DOM element will perform\r\n * @param {string} src - The location of the image\r\n * @param {string} className - The class identifier\r\n * @param {string} title - The tooltip.\r\n * @param {event} clickFunction - The click function to bind to the new element\r\n * @param {string} destination - The Div to append the element to.\r\n * @param {string} dataAttribute - The data attribute at be attached to element.\r\n * @param {string} dataAttributeValue - The data attribute value.\r\n * @returns {object} - The new element.\r\n */\r\nfunction addDomElement(id, type, src, className, title, clickFunction, destination, dataAttribute, dataAttributeValue) {\r\n\tvar element = createDomElement(id, type, src, className, title, clickFunction, dataAttribute, dataAttributeValue);\r\n\tdestination.appendChild(element);\r\n\r\n\treturn element;\r\n}\r\n\r\n/**\r\n * Adds a DOM Element to the Canvas as the first child within the container.\r\n * @param {int} id - ID of the notification\r\n * @param {string} type - Type of Action the DOM element will perform\r\n * @param {string} src - The location of the image\r\n * @param {string} className - The class identifier\r\n * @param {string} title - The tooltip.\r\n * @param {event} clickFunction - The click function to bind to the new element\r\n * @param {string} destination - The Div to append the element to.\r\n * @param {string} dataAttribute - The data attribute at be attached to element.\r\n * @param {string} dataAttributeValue - The data attribute value.\r\n * @returns {object} - The new element.,\r\n */\r\nfunction prependDomElement(id, type, src, className, title, clickFunction, destination, dataAttribute, dataAttributeValue) {\r\n\tvar element = createDomElement(id, type, src, className, title, clickFunction, dataAttribute, dataAttributeValue);\r\n\tdestination.prepend(element);\r\n\r\n\treturn element;\r\n}\r\n\r\n\r\n/**\r\n * Adds a DOM Element to the Canvas\r\n * @param {number} id - ID of the notification\r\n * @param {string} type - Type of Action the DOM element will perform\r\n * @param {string} src - The location of the image\r\n * @param {string} className - The class identifier\r\n * @param {string} title - The tooltip.\r\n * @param {event} clickFunction - The click function to bind to the new element\r\n * @param {string} destination - The Div to append the element to.\r\n * @returns {object} - The new element.\r\n */\r\nfunction createDomElement(id, type, src, className, title, clickFunction, dataAttribute, dataAttributeValue) {\r\n\tvar element = document.createElement(type);\r\n\r\n\t// Set the ID if we have it.\r\n\tif (id) {\r\n\t\telement.id = id;\r\n\t}\r\n\r\n\t// If it's an input, set type to image.\r\n\tif (type === \"input\") {\r\n\t\telement.type = \"image\";\r\n\t\telement.src = src;\r\n\t}\r\n\r\n\t// Set the class name\r\n\tif (className) {\r\n\t\telement.className = className;\r\n\t}\r\n\r\n\t// Set the title\r\n\tif (title) {\r\n\t\telement.title = title;\r\n\r\n\t\tif (element.className.length > 0) {\r\n\t\t\telement.className = element.className + \" \";\r\n\t\t}\r\n\r\n\t\telement.className = element.className + \"tooltip\";\r\n\t}\r\n\r\n\t// Set the onclick function\r\n\tif (clickFunction) {\r\n\t\telement.onclick = clickFunction;\r\n\t}\r\n\r\n\t// Set the data attribute\r\n\tif (typeof (dataAttribute) !== 'undefined' && typeof (dataAttributeValue) !== 'undefined' && dataAttribute.length > 0 && dataAttributeValue.length > 0) {\r\n\t\telement.setAttribute(dataAttribute, dataAttributeValue);\r\n\t}\r\n\r\n\treturn element;\r\n}\r\n\r\n/*\r\n * Adds placeholder text to a text box.\r\n * Added due to not all browsers supporting the placeholder attribute.\r\n * @param {string} input - The element name.\r\n * @param {string} placeholderText - The text to used as the placeholder.\r\n */\r\nfunction addPlaceholderToTextbox(input, placeholderText) {\r\n\r\n\t// Set the value of the placeholder text.\r\n\t$(\"#\" + input).val(placeholderText);\r\n\r\n\t// On focus.\r\n\t$(\"#\" + input).on(\"focus\", function (e) {\r\n\t\tif (this.value === placeholderText) {\r\n\t\t\tthis.value = \"\";\r\n\t\t}\r\n\t});\r\n\r\n\t// On blur.\r\n\t$(\"#\" + input).on(\"blur\", function (e) {\r\n\t\tif (this.value === \"\") {\r\n\t\t\tthis.value = placeholderText;\r\n\t\t}\r\n\t});\r\n}\r\n\r\n/**\r\n * Helper function to change canvas event bindings.\r\n * @param {string} element - The element we are updating the event for.\r\n * @param {string} eventType - The event type we are updating.\r\n * @param {function} functionToBind - The function we are binding to the event.\r\n */\r\nfunction changeCanvasFunction(element, eventType, functionToBind) {\r\n\tif (element === undefined && eventType === undefined && functionToBind === undefined) {\r\n\t\tclearCanvasBindings();\r\n\t}\r\n\telse if (eventType === undefined && functionToBind === undefined) {\r\n\t\tclearElementBindings(element);\r\n\t}\r\n\telse {\r\n\t\tbindFunctionToElement(element, eventType, functionToBind);\r\n\t}\r\n}\r\n\r\n/**\r\n * Removes most binding from a given element\r\n * @param {object} element The element to unbind events for\r\n */\r\nfunction clearElementBindings(element) {\r\n\t$(element).off(\"click\");\r\n\t$(element).off(\"pointerdown\");\r\n\t$(element).off(\"pointerup\");\r\n\t$(element).off(\"pointermove.annotationUI\");\r\n}\r\n\r\n/**\r\n * Binds a function to an event for a given element\r\n * @param {object} element The element to bind for\r\n * @param {string} eventType The type of event\r\n * @param {function} functionToBind The function to bind\r\n */\r\nfunction bindFunctionToElement(element, eventType, functionToBind) {\r\n\t$(element).off(eventType);\r\n\tif (functionToBind !== undefined) {\r\n\t\t$(element).on(eventType, functionToBind);\r\n\t}\r\n}\r\n\r\n/**\r\n * Reset most bindings to their defaults\r\n */\r\nfunction clearCanvasBindings() {\r\n\t// Clear current bindings\r\n\t$(\".annotationViewer\").off(\"click\");\r\n\t$(\".annotationViewer\").off(\"pointerdown\");\r\n\t$(\".annotationViewer\").off(\"pointerup\");\r\n\t$(\".annotationViewer\").off(\"pointermove.annotationUI\");\r\n\r\n\tif (g_oViewer.g_oArtworkViewer.g_oDoc.documentType !== eDocumentTypes.ThreeD) {\r\n\t\t$(\".annotationViewer\").on(\"click\", function (e) {\r\n\t\t\t// Get the annotation and artwork viewer.\r\n\t\t\toAnnotationCanvas = g_oViewer.getCanvas(e.target.id);\r\n\t\t\toArtworkCanvas = g_oViewer.getLinkedArtworkCanvas(e.target.id);\r\n\r\n\t\t\t// Find annotations.\r\n\t\t\tg_oAnnotations.findAnnotation(e, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t});\r\n\t\t$(\"#AnnotationViewer\").on(\"pointermove.annotationUI\", function (e) {\r\n\t\t\toAnnotationCanvas = g_oViewer.getCanvas(e.target.id);\r\n\t\t\toArtworkCanvas = g_oViewer.getLinkedArtworkCanvas(e.target.id);\r\n\t\t\tAnnotationAction.prototype.mouseMove(e, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t});\r\n\t\t$(\"#CompareAnnotationViewer\").on(\"pointermove.annotationUI\", function (e) {\r\n\t\t\toAnnotationCanvas = g_oViewer.getCanvas(e.target.id);\r\n\t\t\toArtworkCanvas = g_oViewer.getLinkedArtworkCanvas(e.target.id);\r\n\t\t\tAnnotationAction.prototype.mouseMoveLite(e, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t});\r\n\t\t$(\"#AnnotationViewer\").on(\"pointerdown\", function (e) {\r\n\t\t\t// Get the annotation and artwork viewer.\r\n\t\t\toAnnotationCanvas = g_oViewer.getCanvas(e.target.id);\r\n\t\t\toArtworkCanvas = g_oViewer.getLinkedArtworkCanvas(e.target.id);\r\n\r\n\t\t\t// Check if any handles were clicked.\r\n\t\t\tAnnotationAction.prototype.handleClick(e, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t});\r\n\t\t// If we are in text compare, add the pointer down for the compare canvas.\r\n\t\tif (g_oTextCompare.g_bTextCompareInProgress) {\r\n\t\t\t$(\"#CompareAnnotationViewer\").on(\"pointerdown\", function (e) {\r\n\t\t\t\t// Get the annotation and artwork viewer.\r\n\t\t\t\toAnnotationCanvas = g_oViewer.getCanvas(e.target.id);\r\n\t\t\t\toArtworkCanvas = g_oViewer.getLinkedArtworkCanvas(e.target.id);\r\n\r\n\t\t\t\t// Check if any handles were clicked.\r\n\t\t\t\tAnnotationAction.prototype.handleClick(e, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t});\r\n\t\t}\r\n\t}\r\n\telse {\r\n\t\t$(\".annotationViewer\").on(\"click\", function (e) {\r\n\t\t\t// Get the annotation and artwork viewer.\r\n\t\t\toAnnotationCanvas = g_oViewer.getCanvas(e.target.id);\r\n\t\t\toArtworkCanvas = g_oViewer.getLinkedArtworkCanvas(e.target.id);\r\n\r\n\t\t\t// Find annotations.\r\n\t\t\tg_oAnnotations.findThreeDAnnotations(e, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t});\r\n\t}\r\n}\r\n\r\n/**\r\n * Determines if a document displays as a PDF.\r\n * @param {eDocumentType} documentType - The document type to check.\r\n * @returns {bool} - If the document displays as a PDF.\r\n */\r\nfunction documentDisplaysAsPDF(documentType) {\r\n\treturn documentType === eDocumentTypes.PDF || documentType === eDocumentTypes.Office || documentType === eDocumentTypes.AI;\r\n}\r\n\r\n/**\r\n * Determines if a document displays as an SVG.\r\n * @param {eDocumentType} documentType - The document type to check.\r\n * @returns {bool} - If the document displays as an SVG.\r\n */\r\nfunction documentDisplaysAsSVG(documentType) {\r\n\treturn documentType === eDocumentTypes.SVG || documentType === eDocumentTypes.CopyMagic;\r\n}\r\n\r\n/**\r\n * Determines if a document has separations.\r\n * @param {eDocumentType} documentType - The document type to check.\r\n * @param {int} documentPages - The number of document pages.\r\n * @returns {bool} - If the document has separations.\r\n */\r\nfunction documentHasSeparations(documentType, documentPages) {\r\n\treturn documentType === eDocumentTypes.PDF || documentType === eDocumentTypes.Office || documentType === eDocumentTypes.AI || (documentType === eDocumentTypes.Image && documentPages > 0);\r\n}\r\n\r\n/**\r\n * Takes a measurement and converts it to millimetres if needed\r\n * @param {number} num The measurement in MM or Inches\r\n * @returns {number} The measurement in MM\r\n */\r\nvar MeasurementInMM = function (num) {\r\n\tif (g_oSettings.g_oUserSettings.UseMetricUnits) {\r\n\t\t// Came in as a mm\r\n\t\treturn Number(DelimitNum(num, 4));\r\n\t}\r\n\telse {\r\n\t\t// Came in as inch, convert to mm\r\n\t\treturn Number(DelimitNum(num * 25.4, 4));\r\n\t}\r\n};\r\n\r\n/**\r\n * Dynamically delimit a number and remove any trailing zeroes.\r\n * @param {number} num Number to delimit\r\n * @param {number} decimalPoints Max number of decimal points\r\n * @returns {number} Delimited number\r\n */\r\nfunction DelimitNum(num, decimalPoints) {\r\n\tfor (var i = 0; i < decimalPoints; i++) {\r\n\t\tif (num.toFixed(decimalPoints) % num.toFixed(i) === 0) {\r\n\t\t\treturn num.toFixed(i);\r\n\t\t}\r\n\t}\r\n\treturn num.toFixed(decimalPoints);\r\n}\r\n\r\n/**\r\n * Retrieve the element id from a given element.\r\n * @param {object} element Element in question\r\n * @returns {string} The element's id\r\n */\r\nfunction GetElementId(element) {\r\n\treturn element.id || element[0].id;\r\n}\r\n\r\n/**\r\n * Scroll a given element to a specific point over a certain time-frame\r\n * @param {object} element The element to scroll\r\n * @param {number} target Where to scroll it to in pixels\r\n * @param {number} time How much time to take to scroll there in milliseconds\r\n */\r\nfunction scrollElement(element, target, time) {\r\n\t$(element).stop().animate({\r\n\t\t'scrollTop': target\r\n\t}, time);\r\n}\r\n\r\n/**\r\n * Sorting method to sort elements in an ascending order\r\n * @param {any} a Item a\r\n * @param {any} b Item B\r\n * @returns {number} Positive if a > b, negative if b < a, 0 otherwise\r\n */\r\nfunction AscendingOrder(a, b) {\r\n\treturn a - b;\r\n}\r\n\r\n/**\r\n * Un-highlights a button.\r\n * @param {element} elem - The button we are removing the highlighting from.\r\n */\r\nfunction clearHighlightSelectedButton(elem) {\r\n\t$(elem).removeClass(\"selectedButton\");\r\n}\r\n\r\n/**\r\n * Converts the UTC date to the users local using the browser time settings.\r\n * @param {Object|string} utcDate - The UTC date we are converting.\r\n * @returns {string} - The local date time AS A STRING.\r\n */\r\nfunction convertUTCDateToLocal(utcDate) {\r\n\tvar szDateFormat = \"DD/MM/YYYY HH:mm:ss\";\r\n\tvar oDate = moment.utc(utcDate).local();\r\n\treturn oDate.format(szDateFormat);\r\n}\r\n\r\n/* Returns a function, that, as long as it continues to be invoked, will not\r\n * be triggered. The function will be called after it stops being called for\r\n * N milliseconds. If `immediate` is passed, trigger the function on the\r\n * leading edge, instead of the trailing.\r\n*/\r\nfunction debounce(func, wait, immediate) {\r\n\tvar timeout;\r\n\treturn function () {\r\n\t\tvar context = this, args = arguments;\r\n\t\tvar later = function () {\r\n\t\t\ttimeout = null;\r\n\t\t\tif (!immediate) func.apply(context, args);\r\n\t\t};\r\n\t\tvar callNow = immediate && !timeout;\r\n\t\tclearTimeout(timeout);\r\n\t\ttimeout = setTimeout(later, wait);\r\n\t\tif (callNow) func.apply(context, args);\r\n\t};\r\n}\r\n\r\n/**\r\n * Performs a deep copy on an array.\r\n * @param {array} oldArray Array to deep copy.\r\n * @returns {array} The deep copy of the array.\r\n */\r\nfunction deepCopyArray(oldArray) {\r\n\treturn jQuery.extend(true, [], oldArray);\r\n}\r\n\r\n/**\r\n * Performs a deep copy on an object\r\n * @param {object} oldObject Object to deep copy.\r\n * @returns {object} The deep copy of the object.\r\n */\r\nfunction deepCopyObject(oldObject) {\r\n\treturn jQuery.extend(true, {}, oldObject);\r\n}\r\n\r\n/**\r\n * Displays any errors within the html.\r\n * @param {array} errors - The list of errors.\r\n * @returns {string} HTML of the errors.\r\n */\r\nfunction displayErrorContentHTML(errors) {\r\n\r\n\t// Declare a variable to hold the error content.\r\n\tvar szHTML = \"\";\r\n\r\n\t// If the error object is an array, add each of the errors to the list.\r\n\tif (Array.isArray(errors)) {\r\n\t\tif (errors.length > 0) {\r\n\t\t\tfor (var i = 0; i < errors.length; i++) {\r\n\t\t\t\tvar oErr = errors[i];\r\n\t\t\t\tszHTML += \"
  • \" + oErr.errorDescription + \"
  • \";\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t// Return the error content.\r\n\treturn szHTML;\r\n}\r\n\r\n/**\r\n * Generates the HTML for the error bubble for a single error message..\r\n * @param {string} errorMessage - The error message.\r\n * @returns {string} HTML of the error message within a list item element.\r\n */\r\nfunction displayErrorResultHTML(errorMessage) {\r\n\treturn \"
  • \" + errorMessage + \"
  • \";\r\n}\r\n\r\n// Confirm bubble auto closing.\r\n$(document).on('click', function (event) {\r\n\r\n\t// Loop through each of the active bubbles.\r\n\tfor (var i = 0; i < g_oActiveBubbles.length; i++) {\r\n\r\n\t\t// If this bubble is a confirmation bubble.\r\n\t\tif (g_oActiveBubbles[i].type === \"Confirm\") {\r\n\r\n\t\t\t// Get the current date time.\r\n\t\t\tvar dtNow = new Date();\r\n\r\n\t\t\t// If we have not clicked on this bubble, and the bubble has been active for more than the configured seconds.\r\n\t\t\tif ($(event.target).parents(\"#divGLSpeech\" + g_oActiveBubbles[i].id).length === 0 &&\r\n\t\t\t\t(((dtNow - g_oActiveBubbles[i].displayDate) / 1000) > g_iBubbleCloseSeconds)) {\r\n\r\n\t\t\t\t// Close the confirmation bubble.\r\n\t\t\t\tg_oGreenlightMessages.closeBubble(g_oActiveBubbles[i].id, true, true);\r\n\t\t\t\ti--;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n});\r\n\r\n/**\r\n * Format a date in the users preference.\r\n * @param {Object|string} Date - The Date to be formatted. If string should be ISO 8601.\r\n * @returns {string} Date Formatted\r\n */\r\nfunction formatDate(Date) {\r\n\t\r\n\t// The position of the date format in the array.\r\n\tvar iDateArrayPos = 0;\r\n\t\r\n\t// The position of the time format in the array.\r\n\tvar iTimeArrayPos = 1;\r\n\r\n\t// Outline the default date elements.\r\n\tvar oDateElements = [\"dd/MM/yyyy\", \"HH:mm:ss\"];\r\n\r\n\t// If we have a setting for the date format.\r\n\tif (!isNothing(g_oSettings.c_szDateFormat)) {\r\n\r\n\t\t// Split the users date format.\r\n\t\toDateElements = g_oSettings.c_szDateFormat.split(' ');\r\n\t}\r\n\r\n\t// Convert the date to the format.\r\n\tvar szDate = moment(Date).format(oDateElements[iDateArrayPos].toUpperCase() + \" \" + oDateElements[iTimeArrayPos]).substring();\r\n\r\n\t// Remove the seconds and return.\r\n\treturn szDate.substring(0, szDate.length - 3);\r\n};\r\n\r\n/**\r\n * Generates a GUID.\r\n * @returns {string} - The newly generated GUID.\r\n */\r\nfunction generateGuid() {\r\n\tfunction s4() {\r\n\t\treturn Math.floor((1 + Math.random()) * 0x10000)\r\n\t\t.toString(16)\r\n\t\t.substring(1);\r\n\t}\r\n\treturn s4() + s4() + '-' + s4() + '-' + s4() + '-' +\r\n\t\ts4() + '-' + s4() + s4() + s4();\r\n}\r\n\r\n/**\r\n * Returns the correct height of the browser window.\r\n * @returns {int} Correct height of browser window.\r\n */\r\nfunction getClientHeight() {\r\n\tvar iClientHeight = $(window).height();\r\n\treturn iClientHeight;\r\n}\r\n\r\n/**\r\n * Returns the correct width of the browser window.\r\n * @returns {int} Correct width of the browser window.\r\n */\r\nfunction getClientWidth() {\r\n\tvar iClientWidth = $(window).width();\r\n\treturn iClientWidth;\r\n}\r\n\r\n/**\r\n * Returns the correct vertical scrolling amount of the browser window.\r\n * @returns {int} Correct vertical scrolling amount.\r\n */\r\nfunction getScrollAmountY() {\r\n\tvar iScrollAmountY = $(window).scrollTop();\r\n\treturn iScrollAmountY;\r\n}\r\n\r\n/**\r\n * Highlights a button, clearing highlights off all but the navigation section.\r\n * @param {element} elem - The button we are highlighting.\r\n * @param {Boolean} removeCurrentHighlight - Remove the current highlight.\r\n */\r\nfunction highlightSelectedButton(elem, removeCurrentHighlight) {\r\n\tif (removeCurrentHighlight) {\r\n\t\tremoveExistingHighlights(\"#tblNavTools .selectedButton\");\r\n\t}\r\n\t$(elem).addClass(\"selectedButton\");\r\n}\r\n\r\n/**\r\n * Highlights the passed in element, whilst removing all existing highlights.\r\n * @param {element} elem - The button we are highlighting.\r\n * @param {Boolean} removeCurrentHighlight - Remove the current highlight.\r\n */\r\nfunction highlightButtonClearingAllIcons(elem, removeCurrentHighlight) {\r\n\tif (removeCurrentHighlight) {\r\n\t\tremoveExistingHighlights(null);\r\n\t}\r\n\t$(elem).addClass(\"selectedButton\");\r\n}\r\n\r\n/**\r\n * Function to determine if a string is nothing or not.\r\n * @param {string} string String to check.\r\n * @returns {bool} True if the string is not nothing else false.\r\n */\r\nfunction isNothing(string) {\r\n\tif (string !== null && string + \"\" !== \"\") { return false; }\r\n\telse { return true; }\r\n}\r\n\r\n/**\r\n * Function to check that a string contains only numeric characters.\r\n * @param {string} string String to validate.\r\n * @param {bool} required Is the validation required.\r\n * @returns {bool} True if the string only contains numeric characters.\r\n */\r\nfunction isNumeric(string, required) {\r\n\tif (isNothing(string) && required) { return false; }\r\n\telse if (isNothing(string)) { return true; }\r\n\telse {\r\n\t\tvar szTxt = string;\r\n\t\tvar iLen = szTxt.length;\r\n\t\tfor (var i = 0; i !== iLen; i++) {\r\n\t\t\tvar aChar = szTxt.substring(i, i + 1);\r\n\t\t\tif (aChar < \"0\" || aChar > \"9\") { return false; }\r\n\t\t}\r\n\t}\r\n\r\n\treturn true;\r\n}\r\n\r\n/**\r\n * Removes the existing button highlights.\r\n * @param {Element} notSelector notSelector element.\r\n */\r\nfunction removeExistingHighlights(notSelector) {\r\n\r\n\t// Remove existing selected buttons that do not fall in the nor selector.\r\n\t$(\".selectedButton\").not($(notSelector)).removeClass(\"selectedButton\");\r\n\r\n\t// If we are finding SVG text, this must remain highlighted.\r\n\tif (g_oViewer.c_bFindSVGText) {\r\n\t\t$(\"#btnSVGFindText\").addClass(\"selectedButton\");\r\n\t}\r\n\r\n\t// Toggle the drop down content.\r\n\t$(\".dropdown-content:visible\").slideToggle(200);\r\n}\r\n\r\n/**\r\n * Resizes the viewer cell to fit the screen.\r\n */\r\nfunction resizeViewerCell() {\r\n\r\n\t// Start with the width and height of the window.\r\n\tvar iWidth = $(window).width();\r\n\tvar iHeight = $(window).height();\r\n\r\n\t// Remove 16px for the width margin from the width.\r\n\tiWidth -= 16;\r\n\r\n\t// Remove the height of the toolbar container from the height.\r\n\tiHeight -= $(\"#divContainer\").height();\r\n\r\n\t// Set the width and height of the viewer cell.\r\n\t$(\"#divViewerCell\").css(\"width\", iWidth);\r\n\t$(\"#divViewerCell\").css(\"height\", iHeight);\r\n}\r\n\r\n/**\r\n *\tCalculate the width of the slide out div container.\r\n *\t@returns {number} the width in pixels\r\n */\r\nfunction calculateSlideOutDivSize() {\r\n\tvar iCanvasWidth = $(\"#divViewerCell\").width();\r\n\treturn iCanvasWidth / 5;\r\n}\r\n\r\n/**\r\n * Slides a div out.\r\n * @param {object} elem - The element we are sliding.\r\n * @param {bool} leftMenu - If the div should be animated from the left or right side.\r\n * @param {bool} toggle - If the div is being toggled.\r\n */\r\nfunction slideDiv(elem, leftMenu, toggle) {\r\n\r\n\t// Get the width and height of the canvas.\r\n\tvar iCanvasWidth = $(\"#divViewerCell\").width();\r\n\tvar iCanvasHeight = $(\"#divViewerCell\").height();\r\n\r\n\tvar divWidth = calculateSlideOutDivSize();\r\n\r\n\t// Set the width of the element to be relative of the canvas size.\r\n\t$(elem).width(divWidth - 8); // 8px Margin.\r\n\t$(\"#\" + $(elem).children()[0].id).width(divWidth - 8); // 8px Margin.\r\n\r\n\t// Set the height of the element to be relative of the canvas size.\r\n\t$(elem).height(iCanvasHeight);\r\n\t$(\"#\" + $(elem).children()[0].id).height(iCanvasHeight);\r\n\r\n\t// Show the element if we are not in alignment mode.\r\n\tif (!g_oCompare.g_bAlignmentModeActive && !g_oTextCompare.g_bTextCompareInProgress) {\r\n\t\t$(elem).toggle(true);\r\n\t}\r\n\r\n\t// Declare the required variables.\r\n\tvar iLeftPos = parseInt($(elem).css('left'));\r\n\tvar iTargetLeftPos = 0;\r\n\tvar bSlideOut = false;\r\n\tvar bRotate = false;\r\n\r\n\t// If we are sliding in from the left.\r\n\tif (leftMenu) {\r\n\r\n\t\t// Slide Out.\r\n\t\tif ((toggle && iLeftPos <= 0) || (!toggle && !g_oSettings.g_oUserSettings.LeftMenuCollapse)) {\r\n\t\t\tiTargetLeftPos = 8; // 8px Margin.\r\n\t\t\tbSlideOut = true;\r\n\t\t\tbRotate = true;\r\n\t\t}\r\n\t\t// Slide In.\r\n\t\telse {\r\n\t\t\tiTargetLeftPos = (-($(elem).width())) + 8; // 8px Margin.\r\n\t\t\tbSlideOut = false;\r\n\t\t\tbRotate = false;\r\n\t\t}\r\n\r\n\t\t// Update the user preferences.\r\n\t\tg_oSettings.g_oUserSettings.LeftMenuCollapse = !bSlideOut;\r\n\t}\r\n\t// If we are sliding in from the right.\r\n\telse {\r\n\r\n\t\t// Slide Out.\r\n\t\tif ((toggle && (iLeftPos >= iCanvasWidth || iLeftPos === 0)) || (!toggle && !g_oSettings.g_oUserSettings.RightMenuCollapse)) {\r\n\t\t\tiTargetLeftPos = iCanvasWidth - $(elem).width() + 8; // 8px Margin.\r\n\t\t\tbSlideOut = true;\r\n\t\t\tbRotate = false;\r\n\t\t}\r\n\t\t// Slide In.\r\n\t\telse {\r\n\t\t\tiTargetLeftPos = iCanvasWidth + 8; // 8px Margin.\r\n\t\t\tbSlideOut = false;\r\n\t\t\tbRotate = true;\r\n\t\t}\r\n\r\n\t\t// Update the user preferences.\r\n\t\tg_oSettings.g_oUserSettings.RightMenuCollapse = !bSlideOut;\r\n\t}\r\n\r\n\t// Determine animation to move in from the left\r\n\tvar iAnimateLeft = (parseInt($(elem).css('left')) === iTargetLeftPos) ? iLeftPos : iTargetLeftPos;\r\n\r\n\t// If we are sliding out, make sure the child div is shown.\r\n\tif (bSlideOut) {\r\n\t\t$($(elem).children()[0]).show();\r\n\t}\r\n\r\n\t// Animate the div, then hide the child div if not sliding out.\r\n\t$(elem).animate(\r\n\t\t{left: iAnimateLeft + 'px'}, // Animate the div to the correct position.\r\n\t\t(toggle ? 400 : 0), // Animate slowly if we are toggling.\r\n\t\tfunction () {\r\n\r\n\t\t\t// Hide the child div after animation if sliding in.\r\n\t\t\tif (!bSlideOut) {\r\n\t\t\t\t$($(elem).children()[0]).hide();\r\n\t\t\t}\r\n\r\n\t\t\t// If this is the right menu.\r\n\t\t\tif (bSlideOut && !leftMenu) {\r\n\r\n\t\t\t\t// Resize the separations and checklist items.\r\n\t\t\t\tresizeSeparationListItems();\r\n\t\t\t\treziseChecklistItems();\r\n\t\t\t}\r\n\t\t\t// If this is the left menu.\r\n\t\t\telse if (bSlideOut && leftMenu) {\r\n\r\n\t\t\t\t// Resize the annotations list items.\r\n\t\t\t\tresizeAnnotationListItems();\r\n\t\t\t}\r\n\r\n\t\t\t// If sliding out and we have active annotation bubbles, redraw any annotations to adjust for the slide out.\r\n\t\t\tif (bSlideOut && !$.isEmptyObject(g_oAnnotations) && $(\".speechbubble\").length > 0) {\r\n\t\t\t\tg_oViewer.getCanvas(g_oCompare.getAnnotationCanvasId()).redraw(false);\r\n\t\t\t}\r\n\t\t}\r\n\t);\r\n\r\n\t// Update the transform of the arrow icon.\r\n\t$(\"#\" + (leftMenu ? \"divAnnButtonArrow\" : \"divSepButtonArrow\")).css(\"transform\", (bRotate ? \"rotate(180deg)\" : \"\"));\r\n}\r\n\r\n/**\r\n * Resizes the height of the separations list items div.\r\n */\r\nfunction resizeAnnotationListItems() {\r\n\t\r\n\t// Set the height of the annotations list div to the full viewer cell.\r\n\tvar iAnnotationsListHeight = $(\"#divViewerCell\").height();\r\n\r\n\t// Remove the height of the header div.\r\n\tif ($(\"#divAnnDiv_Header\").length > 0) {\r\n\t\tiAnnotationsListHeight -= $(\"#divAnnDiv_Header\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Remove the height of the filters div.\r\n\tif ($(\"#divAnnFilters\").length > 0) {\r\n\t\tiAnnotationsListHeight -= $(\"#divAnnFilters\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Update the height of the annotations list div.\r\n\tif ($(\"#divAnnDiv_ListItems\").length > 0) {\r\n\t\t$(\"#divAnnDiv_ListItems\").css(\"height\", iAnnotationsListHeight);\r\n\t}\r\n}\r\n\r\n/**\r\n * Resizes the height of the separations list items div.\r\n */\r\nfunction resizeSeparationListItems() {\r\n\r\n\t// Set the height of the separations list div to the full viewer cell.\r\n\tvar iSeparationsListHeight = $(\"#divViewerCell\").height();\r\n\r\n\t// Remove the height of the navigator div.\r\n\tif ($(\"#divNavigator\").length > 0) {\r\n\t\tiSeparationsListHeight -= $(\"#divNavigator\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Remove the height of the disabled navigator div.\r\n\tif ($(\"#divNavigatorDisabled\").length > 0) {\r\n\t\tiSeparationsListHeight -= $(\"#divNavigatorDisabled\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Remove the height of the checklist tabs.\r\n\tif ($(\"#divChecklistTabs\").length > 0) {\r\n\t\tiSeparationsListHeight -= $(\"#divChecklistTabs\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Remove the height of the separations list header div.\r\n\tif ($(\"#divSeparationItems_Header\").length > 0) {\r\n\t\tiSeparationsListHeight -= $(\"#divSeparationItems_Header\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Update the height of the separations list div.\r\n\tif ($(\"#divSeparationItems\").length > 0) {\r\n\t\t$(\"#divSeparationItems\").css(\"height\", iSeparationsListHeight);\r\n\t}\r\n}\r\n\r\n/**\r\n * Resizes the checklist tab.\r\n */\r\nfunction reziseChecklistItems() {\r\n\r\n\t// Set the height of the checklist list div to the full viewer cell.\r\n\tvar iChecklistListHeight = $(\"#divViewerCell\").height();\r\n\r\n\t// Remove the height of the navigator div.\r\n\tif ($(\"#divNavigator\").length > 0) {\r\n\t\tiChecklistListHeight -= $(\"#divNavigator\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Remove the height of the disabled navigator div.\r\n\tif ($(\"#divNavigatorDisabled\").length > 0) {\r\n\t\tiChecklistListHeight -= $(\"#divNavigatorDisabled\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Remove the height of the checklist tabs.\r\n\tif ($(\"#divChecklistTabs\").length > 0) {\r\n\t\tiChecklistListHeight -= $(\"#divChecklistTabs\")[0].offsetHeight;\r\n\t}\r\n\r\n\t// Update the height of the separations list div.\r\n\tif ($(\"#divChecklist\").length > 0) {\r\n\t\t$(\"#divChecklist\").css(\"height\", iChecklistListHeight);\r\n\t}\r\n}\r\n\r\n/**\r\n * Swaps an image objects source.\r\n * @param {string} imgElement HTML id of the img element to change the src of.\r\n * @param {string} newImageSrc The source of the image to swap to.\r\n */\r\nfunction swapImage(imgElement, newImageSrc) {\r\n\tif ($(\"#\" + imgElement).exists()) {\r\n\t\t$(\"#\" + imgElement).attr(\"src\", newImageSrc);\r\n\t}\r\n}\r\n\r\n/**\r\n * Locks the screen.\r\n */\r\nfunction lockScreen() {\r\n\t$(\"#divLockScreen\").fadeIn(600);\r\n}\r\n\r\n/**\r\n * Unlocks the screen.\r\n */\r\nfunction unlockScreen() {\r\n\t$(\"#divLockScreen\").fadeOut(600);\r\n}\r\n\r\n/**\r\n * Shows the spinner message.\r\n * @param {string} message - The message to be shown.\r\n */\r\nfunction showSpinnerMessage(message) {\r\n\t$(\"#divSpinnerMessage\").html(message);\r\n\t$(\"#divSpinnerMessage\").fadeIn(600);\r\n}\r\n\r\n/** \r\n * Hides the spinner message. \r\n */\r\nfunction hideSpinnerMessage() {\r\n\t$(\"#divSpinnerMessage\").html(\"\");\r\n\t$(\"#divSpinnerMessage\").fadeOut(600);\r\n}\r\n\r\n/**\r\n * Shows the pop-up and locks the window behind.\r\n * @param {string} div HTML id of the div to display as the pop up window.\r\n * @param {int} percentX Percentage of the screens width this pop-up will take.\r\n * @param {int} percentY Percentage of the screens height this pop-up will take.\r\n */\r\nfunction displayPopupWindow(div, percentX, percentY) {\r\n\r\n\t// Check the div exists.\r\n\tif ($(\"#\" + div).exists()) {\r\n\r\n\t\t// Lock window firstly\r\n\t\tlockScreen();\r\n\t\t// Hide spinner\r\n\t\t$('#imgSpinner').hide();\r\n\t\t// Calculate the Pop-up position and content sizes.\r\n\t\tcalculateContentPositions(div, percentX, percentY, false);\r\n\r\n\t\t// Show the window.\r\n\t\t$(\"#\" + div).fadeIn();\r\n\t}\r\n}\r\n\r\nfunction flatten(array) {\r\n\treturn [].concat.apply([], array);\r\n}\r\n\r\n/**\r\n* Hides the pop-up and unlocks the window.\r\n* @param {string} div HTML id of the div to hide.\r\n*/\r\nfunction hidePopupWindow(div) {\r\n\r\n\t// Check the div exists.\r\n\tif ($(\"#\" + div).exists()) {\r\n\r\n\t\t// Hide the pop-up.\r\n\t\t$(\"#\" + div).fadeOut();\r\n\r\n\t\t// Unlock the window.\r\n\t\tunlockScreen();\r\n\r\n\t\t// show the spinner\r\n\t\t$('#imgSpinner').show();\r\n\t}\r\n}\r\n\r\n/**\r\n * Returns the correct horizontal scrolling amount of the browser window.\r\n * @returns {int} Correct horizontal scrolling amount.\r\n */\r\nfunction getScrollAmountX() {\r\n\tvar iScrollAmountX = $(window).scrollLeft();\r\n\treturn iScrollAmountX;\r\n}\r\n\r\n/**\r\n * Called when a file is dragged over the file upload control.\r\n * @param {event} e - event object\r\n */\r\nfunction dragOverFile(e) {\r\n\r\n\t// Stop the browsers default behaviour.\r\n\te.preventDefault();\r\n\te.stopPropagation();\r\n\r\n\t// Add the drag over outline active class to the file upload control.\r\n\t$(\"#divFileUpload\").addClass(\"uploadZoneActive\");\r\n}\r\n\r\n/**\r\n * Called when a file is dragged out of the file upload control.\r\n * @param {event} e - event object\r\n */\r\nfunction dragLeaveFile(e) {\r\n\r\n\t// Stop the browsers default behaviour.\r\n\te.preventDefault();\r\n\te.stopPropagation();\r\n\r\n\t// Remove the drag over outline active class from the file upload control.\r\n\t$(\"#divFileUpload\").removeClass(\"uploadZoneActive\");\r\n}\r\n\r\n/**\r\n * Called when a file is dropped over the upload control.\r\n * @param {event} e - event object.\r\n */\r\nfunction droppedFile(e) {\r\n\r\n\t// Set that we are uploading files.\r\n\tg_oAnnotationAttachments.setUploadingStatus(true);\r\n\r\n\t// Stop the browsers default behaviour.\r\n\te.preventDefault();\r\n\te.stopPropagation();\r\n\r\n\t// Remove the drag over outline active class from the file upload control.\r\n\t$(\"#divFileUpload\").removeClass(\"uploadZoneActive\");\r\n\r\n\t// Add the dropped attachments.\r\n\tvar dt = e.dataTransfer;\r\n\tg_oAnnotationAttachments.addAnnotationAttachments(dt.files);\r\n}\r\n\r\n/**\r\n * Calculate the div position and content sizes (pop-up percentage size specified).\r\n * @param {string} div HTML id of the div to calculate the positions and content sizes for.\r\n * @param {int} x Percentage of the screens width this pop-up will take.\r\n * @param {int} y Percentage of the screens height this pop-up will take.\r\n * @param {bool} switched If false the z-index will be updated.\r\n */\r\nfunction calculateContentPositions(div, x, y, switched) {\r\n\t// Calculate the Pop-up positions.\r\n\tvar idivHeight = y * getClientHeight() / 100;\r\n\tvar idivWidth = x * getClientWidth() / 100;\r\n\tvar iTop = calculateCentralYCoordinate(parseInt(idivHeight, 10));\r\n\tvar iLeft = calculateCentralXCoordinate(parseInt(idivWidth, 10));\r\n\r\n\t// Round the Pop-up positions to the nearest whole number.\r\n\tidivHeight = Math.round(idivHeight);\r\n\tidivWidth = Math.round(idivWidth);\r\n\tiTop = Math.round(iTop);\r\n\tiLeft = Math.round(iLeft);\r\n\r\n\t// Get the margin size for the header to subtract from the height.\r\n\tvar iHeaderMargin = 0;\r\n\r\n\t//// If we have a skin folder, check if this needs to be amended for the classic view.\r\n\t//if (typeof (g_oUserProfile) != \"undefined\" && g_oUserProfile.skinFolder == \"cls\") {\r\n\t// iHeaderMargin = 20;\r\n\t//}\r\n\r\n\t// Apply the CSS.\r\n\tvar oPopup = $(\"#\" + div);\r\n\toPopup.css({\r\n\t\t\"height\": idivHeight,\r\n\t\t\"width\": idivWidth,\r\n\t\t\"top\": iTop,\r\n\t\t\"left\": iLeft\r\n\t});\r\n\r\n\t//if (!switched) {\r\n\t// oPopup.css(\"z-index\", 1000 + (10 * g_iCurrLockingLevel));\r\n\t//}\r\n\r\n\t// Calculate the Pop-up content height and widths (required for scrolling).\r\n\tvar oPopupContent = $(\"#\" + div + \"_Content\");\r\n\tif (oPopupContent.exists()) {\r\n\r\n\t\tvar iHeaderHeight = $(\"#\" + div + \"_Header\").height();\r\n\r\n\t\toPopupContent.css({\r\n\t\t\t\"height\": (idivHeight - iHeaderHeight - iHeaderMargin),\t// 20px (cls) or 30px (mod) margin space.\r\n\t\t\t\"width\": (idivWidth - 15)\t\t\t\t\t\t\t\t// 15px margin space.\r\n\t\t});\r\n\r\n\t\tif (oPopup.has(\"#divPopUpContent_Content\") && $(\"#\" + div).has(\"#divPopUpContent_Header\")) {\r\n\t\t\tvar mainHeight = oPopupContent.height();\r\n\t\t\tvar header = oPopupContent.find(\"#divPopUpContent_Header\").height();\r\n\t\t\toPopupContent.find(\"#divPopUpContent_Content\").css(\"height\", mainHeight - header - iHeaderMargin);\r\n\t\t}\r\n\t}\r\n}\r\n\r\nfunction elementExistsAndIsVisible(element) {\r\n\treturn $(element).exists() && $(element).is(\":visible\");\r\n}\r\n\r\n/**\r\n * Calculates the correct Y position to place an object in the centre of the window.\r\n * @param {int} objectHeight Height of the object to center.\r\n * @returns {int} Y position.\r\n */\r\nfunction calculateCentralYCoordinate(objectHeight) {\r\n\tvar iHeight = getClientHeight();\r\n\tvar iTop = getScrollAmountY() + (iHeight - objectHeight) / 2;\r\n\treturn iTop;\r\n}\r\n\r\n/**\r\n * Calculates the correct X position to place an object in the centre of the window.\r\n * @param {int} objectWidth Width of object to center.\r\n * @returns {int} X position.\r\n */\r\nfunction calculateCentralXCoordinate(objectWidth) {\r\n\tvar iWidth = getClientWidth();\r\n\tvar iLeft = getScrollAmountX() + (iWidth - objectWidth) / 2;\r\n\treturn iLeft;\r\n}\r\n\r\n/*\r\n * Takes a value and rounds it to the specified number.\r\n * Code taken from this StackOverflow post:\r\n * https://stackoverflow.com/questions/1726630/formatting-a-number-with-exactly-two-decimals-in-javascript\r\n */\r\nfunction round(value, exp) {\r\n\tif (typeof exp === 'undefined' || +exp === 0) {\r\n\t\treturn Math.round(value);\r\n\t}\r\n\r\n\tvalue = +value;\r\n\texp = +exp;\r\n\r\n\tif (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {\r\n\t\treturn NaN;\r\n\t}\r\n\r\n\t// Shift\r\n\tvalue = value.toString().split('e');\r\n\tvalue = Math.round(+(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp)));\r\n\r\n\t// Shift back\r\n\tvalue = value.toString().split('e');\r\n\treturn +(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp));\r\n}\r\n\r\n/**\r\n * Adds two floats safely.\r\n * Due to the way js floats are combined, the 1000 is required to ensure exact accuracy adding.\r\n * @param {float} x - The first float value.\r\n * @param {float} y - The second float value.\r\n * @returns {float} - The sum of the floats.\r\n */\r\nfunction addFloats(x, y) {\r\n\treturn ((x * 1000) + (y * 1000)) / 1000;\r\n}\r\n\r\n/**\r\n * Sebtracts two floats safely.\r\n * Due to the way js floats are combined, the 1000 is required to ensure exact accuracy subtracting.\r\n * @param {float} x - The first float value.\r\n * @param {float} y - The second float value.\r\n * @returns {float} - The return of the float subtraction.\r\n */\r\nfunction subtractFloats(x, y) {\r\n\treturn ((x * 1000) - (y * 1000)) / 1000;\r\n}\r\n\r\n/*\r\n * Parses a value to check that it is an integer.\r\n * Code taken from this StackOverflow post:\r\n * https://stackoverflow.com/questions/14636536/how-to-check-if-a-variable-is-an-integer-in-javascript\r\n */\r\nfunction isInt(value) {\r\n\tif (isNaN(value)) {\r\n\t\treturn false;\r\n\t}\r\n\r\n\tvar x;\r\n\tx = parseFloat(value);\r\n\treturn (x | 0) === x;\r\n}\r\n\r\n\r\nfunction contains(R1_x, R1_y, R1_w, R1_h, R2_x, R2_y, R2_w, R2_h) {\r\n\tif ((R2_x + R2_w) <= (R1_x + R1_w) &&\r\n\t\t(R2_x) >= (R1_x) &&\r\n\t\t(R2_y) >= (R1_y) &&\r\n\t\t(R2_y + R2_h) <= (R1_y + R1_h)\r\n\t) {\r\n\t\treturn true;\r\n\t}\r\n\telse {\r\n\t\treturn false;\r\n\t}\r\n}\r\n\r\n/**\r\n * Gets the clicked coordinates.\r\n * @param {object} event - The click event.\r\n * @param {object} oViewer - The viewer containing the canvas the user has clicked on.\r\n * @returns {number[]} - X & Y coordinates.\r\n */\r\nfunction getClickCoords(event, oViewer) {\r\n\tvar x = event.x || event.clientX + document.body.scrollLeft + document.getElementById(oViewer.g_szCanvasId).scrollLeft + document.documentElement.scrollLeft;\r\n\tvar y = event.y || event.clientY + document.body.scrollTop + document.getElementById(oViewer.g_szCanvasId).scrollTop + document.documentElement.scrollTop;\r\n\tvar rect = oViewer.g_oCanvas.getBoundingClientRect();\r\n\r\n\tx = x - rect.left;\r\n\ty = y - rect.top;\r\n\r\n\t// Factor in the users DPI for the click co-ordinates.\r\n\tx *= g_oViewer.c_iDPI;\r\n\ty *= g_oViewer.c_iDPI;\r\n\r\n\treturn [x, y];\r\n}\r\n\r\n/**\r\n * Gets the number of frames to be used for the zoom animation.\r\n * @param {eZoomSpeed} zoomSpeed - The speed of the zoom.\r\n * @returns - Int number of frames.\r\n */\r\nfunction getAnimationFramesForZoomSpeed(zoomSpeed) {\r\n\tswitch (zoomSpeed) {\r\n\t\tcase eZoomSpeed.Slow: return 15;\r\n\t\tcase eZoomSpeed.Medium: return 10;\r\n\t\tcase eZoomSpeed.Fast: return 5;\r\n\t\tdefault: return 5;\r\n\t}\r\n}\r\n\r\n/**\r\n * Gets the multiplier for the zoom increment.\r\n * @param {eZoomIncrements} zoomIncrement - The zoom increment.\r\n * @returns - Float zoom multiplier.\r\n */\r\nfunction getZoomMultiplierForZoomIncrement(zoomIncrement) {\r\n\tswitch (zoomIncrement) {\r\n\t\tcase eZoomIncrements.Smallest: return 1.2;\r\n\t\tcase eZoomIncrements.Small: return 1.5;\r\n\t\tcase eZoomIncrements.Medium: return 2;\r\n\t\tcase eZoomIncrements.Large: return 3;\r\n\t\tcase eZoomIncrements.Largest: return 4;\r\n\t\tdefault: return 2;\r\n\t}\r\n}\r\n\r\n/**\r\n * Fakes getClickCoords as if it were made on the given coordinates\r\n * @param {any} x The x coordinate\r\n * @param {any} y The y coordinate\r\n * @param {any} oViewer The viewer containing the canvas the user has clicked on.\r\n * @returns {number[]} A set of coordinates\r\n */\r\nfunction fakeClickCoords(x, y, oViewer) {\r\n\tvar rect = oViewer.g_oCanvas.getBoundingClientRect();\r\n\r\n\tx = x - rect.left;\r\n\ty = y - rect.top;\r\n\r\n\t// Factor in the users DPI for the click co-ordinates.\r\n\tx *= g_oViewer.c_iDPI;\r\n\ty *= g_oViewer.c_iDPI;\r\n\r\n\treturn [x, y];\r\n}\r\n\r\n/**\r\n * Transforms the event click coordinates into coordinates on the canvas\r\n * @param {event} event - The event reference.\r\n * @param {object} oArtworkCanvas - The artwork canvas.\r\n * @param {object} oAnnotationsUI - The annotationsUI reference.\r\n * @returns {number} co-ordinates\r\n */\r\nfunction findClickCanvasCoordinates(event, oArtworkCanvas, oAnnotationsUI) {\r\n\tvar oCoords = oAnnotationsUI.getClick(event, oArtworkCanvas);\r\n\tvar iCompareOffset = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\tswitch (oArtworkCanvas.g_iRotDegrees) {\r\n\t\tcase 90:\r\n\t\tcase 270:\r\n\t\t\treturn [(oCoords[0] - iCompareOffset.x) / oArtworkCanvas.g_iScaledImageHeight, (oCoords[1] - iCompareOffset.y) / oArtworkCanvas.g_iScaledImageWidth];\r\n\t\tcase 180:\r\n\t\tdefault:\r\n\t\t\treturn [(oCoords[0] - iCompareOffset.x) / oArtworkCanvas.g_iScaledImageWidth, (oCoords[1] - iCompareOffset.y) / oArtworkCanvas.g_iScaledImageHeight];\r\n\t}\r\n}\r\n\r\n/*\r\n * - - - O B J E C T P R O T O T Y P E S - - -\r\n */\r\n\r\nfunction Seperation() {\r\n\tthis.SeperationName = \"\";\r\n\tthis.Red = 0;\r\n\tthis.Green = 0;\r\n\tthis.Blue = 0;\r\n\tthis.Opaque = \"\";\r\n\tthis.OriginalRed = 0;\r\n\tthis.OriginalGreen = 0;\r\n\tthis.OriginalBlue = 0;\r\n\tthis.OriginalOpaque = \"\";\r\n\tthis.ImageWidth = 0;\r\n\tthis.ImageHeight = 0;\r\n\tthis.Visable = true;\r\n\tthis.WidthResolution = 0;\r\n\tthis.HeightResolution = 0;\r\n}\r\n\r\nfunction ImageDimensions() {\r\n\tthis.MinX = 0;\r\n\tthis.MinY = 0;\r\n\tthis.MaxX = 0;\r\n\tthis.MaxY = 0;\r\n}\r\n\r\nfunction ImageObject() {\r\n\tthis.Width = 0;\r\n\tthis.Height = 0;\r\n}\r\n\r\nfunction ImageBox() {\r\n\tthis.RequestApproval = 0;\r\n\tthis.RequestedPage = 0;\r\n\tthis.RequestedImageObject = new ImageObject();\r\n\tthis.ImagePercentages = new ImageDimensions();\r\n\tthis.UserImageObject = new ImageObject();\r\n\tthis.CompareImageObject = new ImageObject();\r\n\tthis.ScaledImageObject = new ImageObject();\r\n\tthis.CompareOffsetX = 0;\r\n\tthis.CompareOffsetY = 0;\r\n\tthis.CompareRotationDegrees = 0;\r\n\tthis.VisibleSeparations = new Array();\t\t\t\t\t// An array of Separation Objects.\r\n}\r\n\r\n/**\r\n * Imaging Engine Request Object.\r\n */\r\nfunction ImageRequest() {\r\n\tthis.SessionId;\r\n\tthis.OriginalResolution;\t\t\t\t// Translates to a nullable int in the C# code so no default is being set.\r\n\tthis.ApprovalId = 0;\r\n\tthis.CompareMode = eCompareMode.NoCompare;\r\n\tthis.ImageRequestName = \"\";\r\n\tthis.ArtworkViewerImageBox = new ImageBox();\r\n\tthis.CompareViewerImageBox = new ImageBox();\r\n\tthis.IsCompareImageRequest = false;\r\n\tthis.CompareGhosting = 0;\r\n\tthis.CompareTolerance = 0;\r\n\tthis.IsGetNewImageCallType = false;\r\n\tthis.OverrideSingleColourChange = false;\r\n}\r\n\r\n/**\r\n * Examine Image Request Object.\r\n * Used for the Colour Density, Barcode & Text Measurement Technical Tools.\r\n */\r\nfunction ExamineImageRequest() {\r\n\tthis.DocumentName = \"\";\r\n\tthis.Dimensions = new ImageDimensions();\r\n\tthis.ApprovalID = 0;\r\n\tthis.PageNumber = 0;\r\n\tthis.ExamTypeCode = g_oTechTools.g_eExamTypes.COLOURDENSITY;\r\n\tthis.CurrentResolution = 0;\r\n\tthis.OriginalResolution = 0;\r\n\tthis.RealtimeRenderReference = \"\";\r\n\tthis.AnnotationID = -1;\r\n\tthis.FullImageHeight = 0;\r\n\tthis.FullImageWidth = 0;\r\n}\r\n\r\n/**\r\n * Barcode Measurement Object.\r\n * Used to hold the details of the separation barcode measurement details.\r\n */\r\nfunction BarcodeMeasurement() {\r\n\tthis.SeparationName = \"\";\r\n\tthis.CodeType = \"\";\r\n\tthis.CodeData = \"\";\r\n\tthis.DisplayText = \"\";\r\n\tthis.MarqueeCoordinates = new ImageDimensions();\r\n\tthis.widthMagnification = \"\";\r\n\tthis.X = 0;\r\n\tthis.Y = 0;\r\n\tthis.Width = 0;\r\n\tthis.Height = 0;\r\n}\r\n\r\n/**\r\n * Used to get a filename without its extension\r\n * @param {string} FileName - Name of file.\r\n * @returns {string} Name of file.\r\n */\r\nfunction GetFileNameWithoutExtension(FileName) {\r\n\treturn FileName.substring(0, FileName.lastIndexOf('.'));\r\n}\r\n\r\n// Polyfill for IE. Useless.\r\nMath.log2 = Math.log2 || function (x) {\r\n\treturn Math.log(x) * Math.LOG2E;\r\n};\r\n\r\n/**\r\n * Add Polyfill for .contains for IE. Useless.\r\n * @returns {bool} If this contains anything within arguments.\r\n */\r\nif (!String.prototype.contains) {\r\n\tString.prototype.contains = function () {\r\n\t\treturn String.prototype.indexOf.apply(this, arguments) !== -1;\r\n\t};\r\n}\r\n\r\n/**\r\n * Polyfill for .prepend\r\n * Source: https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/prepend\r\n */\r\n(function (arr) {\r\n\tarr.forEach(function (item) {\r\n\t\tif (item.hasOwnProperty('prepend')) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\tObject.defineProperty(item, 'prepend', {\r\n\t\t\tconfigurable: true,\r\n\t\t\tenumerable: true,\r\n\t\t\twritable: true,\r\n\t\t\tvalue: function prepend() {\r\n\t\t\t\tvar argArr = Array.prototype.slice.call(arguments),\r\n\t\t\t\t\tdocFrag = document.createDocumentFragment();\r\n\r\n\t\t\t\targArr.forEach(function (argItem) {\r\n\t\t\t\t\tvar isNode = argItem instanceof Node;\r\n\t\t\t\t\tdocFrag.appendChild(isNode ? argItem : document.createTextNode(String(argItem)));\r\n\t\t\t\t});\r\n\r\n\t\t\t\tthis.insertBefore(docFrag, this.firstChild);\r\n\t\t\t}\r\n\t\t});\r\n\t});\r\n})([Element.prototype, Document.prototype, DocumentFragment.prototype]);\r\n\r\n/**\r\n * Process API Response for errors.\r\n * @param {object} xhr - Response from the API.\r\n * @param {string} textStatus - Response from the API.\r\n * @param {boolean} bNoFormatting - Whether to skip formatting message into HTML.\r\n */\r\nfunction ProcessApiError(xhr, textStatus, bNoFormatting) {\r\n var szMessage = textStatus;\r\n switch (xhr.status) {\r\n case 400: // Bad Request\r\n szMessage = xhr.responseJSON.Message;\r\n break;\r\n case 401: // Unauthorised\r\n szMessage = g_oGreenlightMessages.c_szUnauthorisedMessage;\r\n break;\r\n case 500: // Server Error\r\n szMessage = xhr.responseText;\r\n break;\r\n\t}\r\n\r\n\tif (!bNoFormatting) {\r\n\t\tszMessage = displayErrorResultHTML(szMessage);\r\n\t}\r\n\r\n\tg_oGreenlightMessages.displayErrorBubble(szMessage);\r\n}\r\n\r\n\r\n//http://blog.acipo.com/matrix-inversion-in-javascript/\r\nfunction matrix_invert(M) {\r\n\t// I use Gaussian Elimination to calculate the inverse:\r\n\t// (1) 'augment' the matrix (left) by the identity (on the right)\r\n\t// (2) Turn the matrix on the left into the identity by elementary row ops\r\n\t// (3) The matrix on the right is the inverse (was the identity matrix)\r\n\t// There are 3 elementary row ops: (I combine b and c in my code)\r\n\t// (a) Swap 2 rows\r\n\t// (b) Multiply a row by a scalar\r\n\t// (c) Add 2 rows\r\n\r\n\t//if the matrix isn't square: exit (error)\r\n\tif (M.length !== M[0].length) { return; }\r\n\r\n\t//create the identity matrix (I), and a copy (C) of the original\r\n\tvar i = 0, ii = 0, j = 0, dim = M.length, e = 0, t = 0;\r\n\tvar I = [], C = [];\r\n\tfor (i = 0; i < dim; i += 1) {\r\n\t\t// Create the row\r\n\t\tI[I.length] = [];\r\n\t\tC[C.length] = [];\r\n\t\tfor (j = 0; j < dim; j += 1) {\r\n\r\n\t\t\t//if we're on the diagonal, put a 1 (for identity)\r\n\t\t\tif (i == j) { I[i][j] = 1; }\r\n\t\t\telse { I[i][j] = 0; }\r\n\r\n\t\t\t// Also, make the copy of the original\r\n\t\t\tC[i][j] = M[i][j];\r\n\t\t}\r\n\t}\r\n\r\n\t// Perform elementary row operations\r\n\tfor (i = 0; i < dim; i += 1) {\r\n\t\t// get the element e on the diagonal\r\n\t\te = C[i][i];\r\n\r\n\t\t// if we have a 0 on the diagonal (we'll need to swap with a lower row)\r\n\t\tif (e == 0) {\r\n\t\t\t//look through every row below the i'th row\r\n\t\t\tfor (ii = i + 1; ii < dim; ii += 1) {\r\n\t\t\t\t//if the ii'th row has a non-0 in the i'th col\r\n\t\t\t\tif (C[ii][i] != 0) {\r\n\t\t\t\t\t//it would make the diagonal have a non-0 so swap it\r\n\t\t\t\t\tfor (j = 0; j < dim; j++) {\r\n\t\t\t\t\t\te = C[i][j]; //temp store i'th row\r\n\t\t\t\t\t\tC[i][j] = C[ii][j];//replace i'th row by ii'th\r\n\t\t\t\t\t\tC[ii][j] = e; //replace ii'th by temp\r\n\t\t\t\t\t\te = I[i][j]; //temp store i'th row\r\n\t\t\t\t\t\tI[i][j] = I[ii][j];//replace i'th row by ii'th\r\n\t\t\t\t\t\tI[ii][j] = e; //replace ii'th by temp\r\n\t\t\t\t\t}\r\n\t\t\t\t\t//don't bother checking other rows since we've swapped\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t//get the new diagonal\r\n\t\t\te = C[i][i];\r\n\t\t\t// if it's still 0, not invertible (error)\r\n\t\t\tif (e == 0) { return; }\r\n\t\t}\r\n\r\n\t\t// Scale this row down by e (so we have a 1 on the diagonal)\r\n\t\tfor (j = 0; j < dim; j++) {\r\n\t\t\tC[i][j] = C[i][j] / e; //apply to original matrix\r\n\t\t\tI[i][j] = I[i][j] / e; //apply to identity\r\n\t\t}\r\n\r\n\t\t// Subtract this row (scaled appropriately for each row) from ALL of\r\n\t\t// the other rows so that there will be 0's in this column in the\r\n\t\t// rows above and below this one\r\n\t\tfor (ii = 0; ii < dim; ii++) {\r\n\t\t\t// Only apply to other rows (we want a 1 on the diagonal)\r\n\t\t\tif (ii == i) { continue; }\r\n\r\n\t\t\t// We want to change this element to 0\r\n\t\t\te = C[ii][i];\r\n\r\n\t\t\t// Subtract (the row above(or below) scaled by e) from (the\r\n\t\t\t// current row) but start at the i'th column and assume all the\r\n\t\t\t// stuff left of diagonal is 0 (which it should be if we made this\r\n\t\t\t// algorithm correctly)\r\n\t\t\tfor (j = 0; j < dim; j++) {\r\n\t\t\t\tC[ii][j] -= e * C[i][j]; //apply to original matrix\r\n\t\t\t\tI[ii][j] -= e * I[i][j]; //apply to identity\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t//we've done all operations, C should be the identity\r\n\t//matrix I should be the inverse:\r\n\treturn I;\r\n}\r\n\r\n/*\r\n * - - - C O L O U R F U N C T I O N S - - -\r\n */\r\n\r\n// Converts a hex colour to rgb.\r\nfunction convertColourHexToRGB(szHex) {\r\n\tvar result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(szHex);\r\n\treturn result ? {\r\n\t\tr: parseInt(result[1], 16),\r\n\t\tg: parseInt(result[2], 16),\r\n\t\tb: parseInt(result[3], 16)\r\n\t} : {\r\n\t\tr: 0,\r\n\t\tg: 0,\r\n\t\tb: 0\r\n\t};\r\n}\r\n\r\n// Converts an rbg string to rbg.\r\nfunction convertColourToRBG(szRGB) {\r\n\tvar result = szRGB.replace(/[^\\d,]/g, '').split(',');\r\n\treturn result ? {\r\n\t\tr: parseInt(result[0]),\r\n\t\tg: parseInt(result[1]),\r\n\t\tb: parseInt(result[2])\r\n\t} : {\r\n\t\tr: 0,\r\n\t\tg: 0,\r\n\t\tb: 0\r\n\t};\r\n}\r\n\r\n// Converts an rgb string to srgb.\r\nfunction convertRGBToSRGB(oRGB) {\r\n\treturn {\r\n\t\tr: oRGB.r / 255,\r\n\t\tg: oRGB.g / 255,\r\n\t\tb: oRGB.b / 255\r\n\t}\r\n}\r\n\r\n// Converts RGB to hex.\r\nfunction convertRGBToHex(r, g, b) {\r\n\r\n\t// Convert any values to an int and check the bounds.\r\n\tr = Math.max(0, Math.min(255, parseInt(r)));\r\n\tg = Math.max(0, Math.min(255, parseInt(g)));\r\n\tb = Math.max(0, Math.min(255, parseInt(b)));\r\n\r\n\t// Return the hex value.\r\n\treturn \"#\" + convertRGBComponentToHex(r) + convertRGBComponentToHex(g) + convertRGBComponentToHex(b);\r\n}\r\n\r\n// Converts an RBG component to hex.\r\nfunction convertRGBComponentToHex(c) {\r\n\tvar hex = c.toString(16);\r\n\treturn hex.length == 1 ? \"0\" + hex : hex;\r\n}\r\n\r\n// Calculates the luminance of an srgb colour.\r\nfunction calculateLuminance(oSRGB) {\r\n\r\n\t// Calculate the luminance of each colour.\r\n\tvar oLuminacne = {\r\n\t\tr: (oSRGB.r <= 0.03928) ? (oSRGB.r / 12.92) : Math.pow(((oSRGB.r + 0.055) / 1.055), 2.4),\r\n\t\tg: (oSRGB.g <= 0.03928) ? (oSRGB.g / 12.92) : Math.pow(((oSRGB.g + 0.055) / 1.055), 2.4),\r\n\t\tb: (oSRGB.b <= 0.03928) ? (oSRGB.b / 12.92) : Math.pow(((oSRGB.b + 0.055) / 1.055), 2.4)\r\n\t}\r\n\r\n\t// Return the luminance total.\r\n\treturn (0.2126 * oLuminacne.r) + (0.7152 * oLuminacne.g) + (0.0722 * oLuminacne.b);\r\n}\r\n\r\n/** \r\n * Check if we are using IE.\r\n * @returns {bool} - True or False.\r\n */\r\nfunction isIE() {\r\n\tvar ua = window.navigator.userAgent; //Check the userAgent property of the window.navigator object\r\n\tvar msie = ua.indexOf('MSIE '); // IE 10 or older\r\n\tvar trident = ua.indexOf('Trident/'); //IE 11\r\n\r\n\treturn (msie > 0 || trident > 0);\r\n}"]}