{"version":3,"sources":["../js/Text/GreenlightTextCompare.js"],"names":["g_oTextCompare","TextCompare","this","eTextCompareHandleTypes","AddText","AddParagraph","AddArea","RemoveText","Delete","eDifferenceTypes","Deletion","NoDifference","Addition","Substitution","WeightSubstitution","StyleSubstitution","WeightStyleSubstitution","FailedToCalculate","eMarkerTypes","NoMarker","MarkerBefore","MarkerAfter","g_eDifferenceMapping","Both","ApprovalOnly","CompareOnly","eDifferenceStatuses","Initial","Ignore","Accept","Reject","eAccuracyLevels","Word","Character","eCaseSensitivityLevels","Off","On","eBoldItalicDetectionLevels","eWhitespaceDetectionLevels","eAutoSelectionLevels","g_bTextCompareInProgress","g_bArtworkTextDataLoaded","g_bCompareTextDataLoaded","g_oStoredTextSelectionGroups","g_oArtworkTextSelectionGroups","g_oCompareTextSelectionGroups","g_bTextCompareDivShown","g_oCollapsedSectionOrders","g_oHiddenSeparations","g_bDifferencesCalculated","g_iNumberOfDifferences","g_iStepThroughDifference","g_iMarkerSize","g_oViewer","c_iDPI","g_szHighlightColour","g_bDifferenceAnnotations","g_iAccuracy","g_iCaseSensitivity","g_iBoldItalicDetection","g_iWhitespaceDetection","g_iAutoSelection","g_bDragScrolling","g_bAutoActivatePanTool","g_oAutoActivateTextHighlight","g_iAddHighlightToExistingGroup","prototype","setTextCompareActive","setTextCompareSettings","updateTextCompareSettings","$","val","g_oSettings","g_oUserSettings","TextComparisonAccuracy","TextComparisonCaseSensitivity","TextComparisonBoldItalicDetection","TextComparisonWhitespaceDetection","TextComparisonAutoSelection","parseInt","g_oAnnotations","getStringColour","TextComparisonHighlightColour","renderTextCompareSections","setTextCompareUnactive","hide","storeActiveTextSelectionGroups","storeTextSelectionGroups","g_oArtworkViewer","g_oCompare","g_oCompareViewer","oTextSelectionGroups","oArtworkCanvas","getStoredTextSelectionGroupIndex","splice","push","textSelectionGroups","deepCopyArray","retrieveTextSelectionGroups","iIndex","g_oTextSelectionGroups","i","length","g_szCanvasId","g_iDocumentId","g_oDoc","documentId","initialiseTextCompare","g_oGreenlightMessages","closeBubbles","g_oTextCompare_Equivalents","g_oTextEquivalents","loadTextEquivalents","oCompareCanvas","g_oTextData","loadFullTextData","initialiseTextCompare_CH","updatePageNavigation","renderTextCompareAnnotations","showTextCompareDiv","setActiveTextSelectionTool","prop","g_oConsumerSettings","LockTextComparisonAccuracy","LockTextComparisonCaseSensitivity","LockTextComparisonBoldItalicDetection","LockTextComparisonWhitespaceDetection","LockTextComparisonAutoSelection","storeActiveTextSelectionTool","resetActiveTextSelectionTool","g_oTextTools","g_bHighlightInProgress","g_eActiveToolType","iAddToExistingGroup","g_iExistingAnnotationId","selectionGroup","bCompareCanvas","g_bHighlightOnCompareCanvas","eActiveToolType","setTimeout","g_eToolTypes","TextHighlight","initialiseTextCompareHighlight","ParagraphHighlight","initialiseTextCompareParagraphHighlight","AreaTextHighlight","initialiseTextCompareAreaHighlight","RemoveTextHighlight","css","height","show","hideTextCompareDiv","toggleTextCompareDiv","endTextCompareHighlight","updateTextCompareDiv","iDivPosition","iIconMargin","iIconRotation","iIconBorderRadius","animate","bottom","margin-top","updateTextCompareSectionsHeight","position","top","szParentDiv","szNavigationDiv","children","append","pages","bBackButtonDisabled","g_iCurrentPage","bNextButtonDisabled","szHTML","c_szPrevious","c_szNext","html","changeDocument","hideTextCompareInformation","hideTextCompareSeparations","changePage","bNextPage","iNewPage","changeToPage","endhighlight","g_oAnnotationViewer","oAnnotationCanvas","g_oCompareAnnotationViewer","undefined","iCurrentPage","documentResolutionPPI","resetCanvas","iControlIndex","comboControl_GetControlById","iDocumentIndex","comboControl_GetDocumentById","iPageIndex","comboControl_GetPageById","documentPageId","comboControl_SelectOption","iCanvasFileRequestId","Math","random","g_iCanvasFileRequestId","getCanvasFiles","changeCurrentPage","EventService","publish","g_oAnnotationText","bCharacterLevelAccuracy","initialiseTextTool","eAnnotationTypes","initialiseTextCompareAddHighlight","iSelectionGroup","iSelection","bParagraphHighlight","selection","oTextSelectionGroup","getTextSelectionGroup","g_oTextSelections","eHighlightTool","initialiseTextCompareRemoveHighlight","initialiseTextCompareAddArea","click","bCompare","addTextData","oTextData","bAutoSelect","bRenderAnnotations","removeClass","iGroupOrder","getHighestTextSelectionGroup","textSelection","szJoinedSelectionText","getJoinedSelectionsText","g_oTextCompare_AutoSelection","startAutoSelection","oNewSelectionGroup","textSelectionGroup","selectionText","oSelectionText","g_oSelectionCharactersText","g_oSelectionWordsText","updateTextData","autoSelect","isAutoSelected","oSelection","deleteTextDataByGroupOrder","iGroupIndex","getTextSelectionGroupIndexFromOrder","deleteTextData","bEnableAutoSelect","isAutoSelectionEnabled","deleteLinkedSelectionTextData","deleteTextGroup","dropUnusedTextGroups","iHighestTextSelectionGroup","oApprovalSectionGroup","getTextSelectionGroupFromOrder","oCompareSectionGroup","dropUnusedTextGroup","iGroup","g_iGroupOrder","clearTextData","bApprovalCanvas","bConfirmed","oCallback","szConfirmationText","c_szClearText_All","c_szClearText_Approval","c_szClearText_Compare","displayConfirmBubble","bLinkedSelectionDeleted","oApprovalTextSelectionGroup","oCompareTextSelectionGroup","bDeleteSuccess","displaySuccessBubble","c_szAutoSelectionDeleted","renderTextCompareCanvasDifferences","updateDifferencesBar","updateDifferencesSummary","trigger","renderTextCompareCanvasAnnotations","removeHighlights","g_oTextDifferences","j","renderTextCompareCanvasDifference","oDifference","oTextSelections","g_iDifferenceNumber","renderTextCompareCanvasDifference_Words","renderTextCompareCanvasDifference_Characters","oDifferenceWords","getWordsForTextDifference","g_iDifferenceOrder","oDifferenceMarkers","getWordMarkersForTextDifference","highlightTextCompareMarker","highlightTextCompareWords","oWordBounds","getWordListBounds","oAnnotationContext","g_oContext","iImageObjW","g_iScaledImageWidth","iImageObjH","g_iScaledImageHeight","iCenterShift_x","g_iCenterShift_x","iCenterShift_y","g_iCenterShift_y","co","calculateCompareOffsetInPx","compareOffset_x","x","compareOffset_y","y","iCompareRotation","getCompareRotation","annotationColour","getAnnotationColourFromDifferenceStatus","g_iDifferenceStatus","setHighlightColour","newXBegin","x1","newYBegin","y1","newXEnd","x2","newYEnd","y2","beginPoint_x","min","beginPoint_y","dist_x","abs","dist_y","beginPath","rect","lineWidth","g_iAnnotationWidth","strokeStyle","setLineDash","stroke","szDifferenceText","c_szTextCompareGroupText","toString","c_szTextCompareDifferenceText","font","g_iAnnotationNumberFontSize","textBaseline","textalign","areaTextSize","measureText","fillStyle","g_iRotDegrees","g_oAnnotationNumberBox","iBeginX","iBeginY","width","iWidth","iHeight","fill","getHandleFillStyle","save","translate","scale","fillText","restore","g_oAnnotationNumberText","oDifferenceCharacters","getCharactersForTextDifference","getCharacterMarkersForTextDifference","highlightTextCompareCharacters","oCharacterBounds","getCharacterListBounds","oMarkerWords","marker","max","moveTo","lineTo","szMarkerText","iDifferece","iPage","g_iPage","g_oSelectionWords","difference","markerDifference","g_oSelectionCharacters","oMarkerCharacters","getWorldListFromCharacterList","oCharacterList","bWordInList","paragraph","line","word","oWord","textSelectionWord","oSelectionGroup","oSelectionBounds","g_oSelectionWordsBounds","g_oSelectionCharacterBounds","annText","iHandleType","Object","keys","handleXCoordinate","handleYCoordinate","g_oAnnotationActions","g_iAnnotationDragRectSize","closePath","drawImage","getHandleImage","oWords","oDocumentText","getTextData","textData","iPreviousWordStatus","iCurrentWordStatus","status","Paragraphs","Lines","Words","oPreviousWord","iX1","X2","X1","iX2","iY1","Y1","Y2","iY2","getAnnotationColourFromDifferenceType","highlightElement","highlightWord","oCharacters","iPreviousCharacterStatus","iCurrentCharacterStatus","oCharacter","Characters","character","oPreviousCharacter","highlightCharacter","eDifferenceType","szColour","eDifferenceStatus","handleColour","handleType","rotation","bBrightColor","g_oAddTextIconBlk270","g_oAddTextIcon270","g_oAddTextIconBlk180","g_oAddTextIcon180","g_oAddTextIconBlk90","g_oAddTextIcon90","g_oAddTextIconBlk","g_oAddTextIcon","g_oAddParagraphIconBlk270","g_oAddParagraphIcon270","g_oAddParagraphIconBlk180","g_oAddParagraphIcon180","g_oAddParagraphIconBlk90","g_oAddParagraphIcon90","g_oAddParagraphIconBlk","g_oAddParagraphIcon","g_oAddAreaIconBlk270","g_oAddAreaIcon270","g_oAddAreaIconBlk180","g_oAddAreaIcon180","g_oAddAreaIconBlk90","g_oAddAreaIcon90","g_oAddAreaIconBlk","g_oAddAreaIcon","g_oRemoveTextIconBlk270","g_oRemoveTextIcon270","g_oRemoveTextIconBlk180","g_oRemoveTextIcon180","g_oRemoveTextIconBlk90","g_oRemoveTextIcon90","g_oRemoveTextIconBlk","g_oRemoveTextIcon","g_oDeleteIconBlk270","g_oDeleteIcon270","g_oDeleteIconBlk180","g_oDeleteIcon180","g_oDeleteIconBlk90","g_oDeleteIcon90","g_oDeleteIconBlk","g_oDeleteIcon","checkHandleClicked","event","oClick","getClick","oTransformedClick","transformClickForRotation","iClickPercentage_X","iClickPercentage_Y","iHandlePosition_X","iHandlePosition_Y","iHandlePercentageStart_X","iHandlePercentageStart_Y","iHandlePercentageEnd_X","iHandlePercentageEnd_Y","clickAnnotationHandle","iHandle","szDifferencesClass","getGroupDifferencesClass","renderTextCompareSection","c_szTextCompareNoTextSelections","bCollapsed","indexOf","c_szTextCompareFailedToCalculateDifferencesText","iDifferences","countDifferences","c_szTextCompareNoDifferencesText","c_szTextCompareDifferencesText","renderTextSelections","renderTextDifferences","renderTextSelections_Words","renderTextSelections_Characters","szDropZoneClass","c_szTextCompareOrphanedStatement","szDragEvent","content","szSpaceClass","szWordClass","bold","italic","toLowerCase","szCharacterClass","c_szTextCompareUnableToCalculateDifferences","renderTextDifference","szStatusClass","c_szTextCompareDifferenceStatusInitial","c_szTextCompareDifferenceStatusIgnore","c_szTextCompareDifferenceStatusAccept","c_szTextCompareDifferenceStatusReject","getDifferenceText","g_eDifferenceType","differenceTypeIsSubstitution","c_szTextCompareCompareDocument","g_oFormattedDifferenceText","c_szTextCompareApprovalDocument","c_szTextCompareDifferenceTypeAddition","c_szTextCompareDifferenceTypeDeletion","c_szTextCompareDifferenceTypeSubstitution","c_szTextCompareDifferenceTypeFontWeight","c_szTextCompareDifferenceTypeFontStyle","c_szTextCompareDifferenceTypeFontWeightAndStyle","oApprovalTextSelections","bApproval","oCompareTextSelections","szDifferenceClass","toggleTextCompareInformation","c_szTextCompareInfo_Intro","showTextCompareInformation","toggleTextCompareSeparations","showTextCompareSeparations","hideTextCompareFullDocumentSelectionOptions","hideTextCompareHighlightColour","renderTextCompareSeparations","oSeparationList","g_oSeparations","GetSeparationElements","getSyncCanvas","Red","Green","Blue","SeparationName","Visible","toggleTextCompareFullDocumentSelectionOptions","showTextCompareFullDocumentSelectionOptions","renderTextCompareFullDocumentSelectionOptions","inputMinMatchWordsOnChange","element","value","isNaN","TextComparisonFullDocumentSelectionMinMatchWords","updateSettingTextComparisonMinMatchWords","MatchFromDocumentOnChange","TextComparisonFullDocumentSelectionMatchFromDocument","updateSettingTextComparisonMatchFromDocument","iMatchWords","iSelectedMatchFromDocument","toggleTextCompareHighlightColour","showTextCompareHighlightColour","renderTextCompareHighlightColour","find","c_iSkinType","off","on","updateTextCompareHighlightColour","target","getAttribute","szHighlightColour","getHexColour","updateSettingTextComparisonHighlightColour","remove","updateTextCompareSeparationVisibility","iCheckboxId","bVisible","is","szSeparationName","attr","displayWarningBubble","c_szTextCompareOneSeparation","SetSeparationVisibility","updateTextCompareHiddenSeparations","resetTextCompareHiddenSeparations","oHiddenSeparations","displayInfoBubble","c_szTextCompareInfo_Add","c_szTextCompareInfo_Remove","c_szTextCompareInfo_Review","c_szTextCompareInfo_Exit","startTextDrag","szDivId","id","parentNode","dataTransfer","setData","addClass","moveTextDrag","moveUp","iCurrentScrollTop","scrollTop","iScrollAmount","endTextDrag","textDragOver","preventDefault","stopPropagation","textDragOut","textDrop","oDraggedItemId","getData","oDragDestination","iDestinationGroupOrder","split","iDestinationSelectionOrder","iDraggedGroupOrder","iDraggedTextData","iDestinationGroupIndex","iDraggedGroupIndex","moveTextData","iTargetGroupOrder","iTargetGroup","iTargetGroupSelection","oCopiedTextData","toggleTextSection","expandTextSection","collapseTextSection","slideToggle","toggleFilter","opacity","margin-right","applyFilter","szFilter","groupMatchesFilter","calculateDifferences","c_szTextCompareDifferenceNoSelections","iApprovalComboControlId","comboControl_UpdateReadOnly","iCompareComboControlId","updateDifferenceCalculations","calculateGroupDifferences","iDifferencesCount","c_szTextCompareDifferenceLocated","c_szTextCompareDifferencesLocated","resetDifferences","c_szTextCompareDifferencesNotCalculated","g_oTextModifications","resetListStatuses","szApprovalText","combineTextSelections","szCompareText","oTextComparisons","calculateTextComparison","oTextModifications","convertTextComparisonsToModifications","removeTextEquivalentsFromModifications","oTextDifferences","convertTextModificationsToDifferences","updateListStatuses","calculateBoldItalicDifferences","generateFormattedDifferenceText","updateWordListStatuses","updateCharacterListStatuses","iDifference","oModificationWords","startWord","endWord","oSplitWords","g_szModificationText","equivalentDifference","iModificationWord","oModificationCharacters","startCharacter","endCharacter","oSplitCharacters","iModificationCharacter","text1","text2","calculateTextComparisonWords","calculateTextComparisonCharacters","oDiffMatchPath","diff_match_patch","oLinesToWords","diff_linesToWords_","oLineText1","chars1","oLineText2","chars2","oLineArray","lineArray","oDifferences","diff_main","diff_charsToLines_","diff_cleanupSemantic","diff_cleanupBlankValues","oDiffMatchPatch","diff_cleanupBlankValuesCharacters","oComparisons","oModifications","textModification","iDifferenceOrder","textDifference","szCombinedText","getTextSelectionWords","getSectionsWords","sort","sortWords","distinctWords","oSelectionWords","getTextSelectionCharacters","getSectionsCharacters","sortCharacters","distinctCharacters","oSelectionCharacters","textSelectionCharacter","updateDifferenceStatus","iDifferenceNumber","updateDifferenceStatusValue","updateStepDifferenceStatus","getFormattedTextForDifference","g_oDifferenceText","oSectionGroup","getFormattedTextForDifference_Words","getFormattedTextForDifference_Characters","szWordContent","bPreviousCharacterLastInWord","szCharacterContent","lastInWord","oApprovalSelections","oCompareSelections","calculateWordBoldItalicDifferences","calculateCharacterBoldItalicDifferences","oStylingChanges","oApprovalNoDifferenceWords","getWordsWithNoDifferences","oCompareNoDifferenceWords","eSubstitutionType","determineBoldItalicSubstitutionType","type","approvalWords","order","words","compareWords","previousDifference","getDifferenceNumberFromOrder","createGapForDifference","createWordGapForDifference","oApprovalStylingChangeContent","oCompareStylingChangeContent","oApprovalNoDifferenceWord","oCompareNoDifferenceWord","oApprovalNoDifferenceCharacters","getCharactersWithNoDifferences","oCompareNoDifferenceCharacters","approvalCharacters","characters","compareCharacters","createCharacterGapForDifference","oApprovalNoDifferenceCharacter","lastCharacterInWord","oCompareNoDifferenceCharacter","oSelectionGroups","oNoDifferenceWords","iCurrentWord","iPreviousDifference","oNoDifferenceCharacters","iCurrentCharacter","bLastCharacterInWord","oSelections","beginStepThroughDifferences","stepThroughToDifference","nextStepThroughDifferences","previousStepThroughDifferences","panToDifference","endStepThroughDifferences","c_szTextCompareDifferencesAll","c_szTextCompareStepThroughIndividual","g_bAnnotationCreated","showDifferencesSummary","moveDifferencesSummary","iPositionTop","iPositionLeft","left","hideDifferencesSummary","iTotalDifferences","iAdditionDifferences","iDeletionDifferences","iSubstitutionDifferences","iInitialDifferences","iIgnoredDifferences","iAcceptedDifferences","iRejectedDifferences","c_szTextCompareDifferenceTypeAdditions","c_szTextCompareDifferenceTypeDeletions","c_szTextCompareDifferenceTypeSubstitutions","c_szTextCompareDifferenceStatusIgnored","c_szTextCompareDifferenceStatusAccepted","c_szTextCompareDifferenceStatusRejected","g_iZoomLevel","synchroniseZoomPanProperties","g_oCanvasZoom","startZoomAnimate","iApprovalDifferencePage","getPageForDifference","iCompareDifferencePage","panToDifferenceCanvas","oTextSelectionsGroups","k","page","oPanBounds","oBoundsMidPoint","maxCanvasWidth","maxCanvasHeight","g_iTempDragOffset_x","g_iTempDragOffset_y","g_iDragXDiff","g_iDragOffset_x","g_iAnimateFrames","g_iDragYDiff","g_iDragOffset_y","createStepDifferenceAnnotation","createDifferenceAnnotationEdit","oDifferenceAnnotation","createDifferenceAnnotation","createAnnotationTextArea","g_iAuthor","g_szAuthorEmail","eFieldTypes","DifferenceHeader","g_szTextContent","Date","now","c_szTextCompareCancelAnnotation","c_szTextCompareCreateAnnotation","displayErrorBubble","saveDifferenceAnnotation","AnnotationSave","cancelDifferenceAnnotation","oAnnotationText","convertWordsToAnnotationText","convertCharactersToAnnotationText","oTextAnnotation","generateTextAnnotation","g_szColour","startingText","endingText","leftToRight","mergeSections_Words","mergeSections_Characters","iDifferenceType","bHasBoldDifference","bHasItalicDifference","populateTextData","oFullTextData","Order","getWordListText","getCharacterListText","getWordBoldSetting","getWordItalicSetting","getWordText","getCharacterLastInWord","getCharacterBoldSetting","getCharacterItalicSetting","getCharacterText","oComparison","oDifferenceTextList","window"],"mappings":"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","file":"GreenlightTextCompare-8c1becbdc6.js","sourcesContent":["/*\r\n * Copyright (c) 2021 SGS Europe. All rights reserved.\r\n *\r\n * This program is the CONFIDENTIAL and PROPRIETARY property of SGS Europe.\r\n * Any unauthorised use, reproduction, or transfer of this program is strictly\r\n * prohibited.\r\n *\r\n * File Name:\tGreenlightTextCompare.js\r\n *\r\n * Description:\tThe class containing the functionality required by the Greenlight for text compare.\r\n * \r\n */\r\n\r\n// The text compare object.\r\nvar g_oTextCompare = {};\r\n\r\n(function () {\r\n\t\"use strict\";\r\n\r\n\t/**\r\n\t * Load the text content for the page.\r\n\t */\r\n\tfunction TextCompare() {\r\n\r\n\t\t// Outline the compare handle types.\r\n\t\tthis.eTextCompareHandleTypes = {\r\n\t\t\tAddText: 0,\r\n\t\t\tAddParagraph: 1,\r\n\t\t\tAddArea: 2,\r\n\t\t\tRemoveText: 3,\r\n\t\t\tDelete: 4\r\n\t\t};\r\n\r\n\t\t// Outline the difference types.\r\n\t\tthis.eDifferenceTypes = {\r\n\t\t\tDeletion: -1,\r\n\t\t\tNoDifference: 0,\r\n\t\t\tAddition: 1,\r\n\t\t\tSubstitution: 2,\r\n\t\t\tWeightSubstitution: 3,\r\n\t\t\tStyleSubstitution: 4,\r\n\t\t\tWeightStyleSubstitution: 5,\r\n\t\t\tFailedToCalculate: 6\r\n\t\t};\r\n\r\n\t\t// Outline the marker types.\r\n\t\tthis.eMarkerTypes = {\r\n\t\t\tNoMarker: 0,\r\n\t\t\tMarkerBefore: 1,\r\n\t\t\tMarkerAfter: 2\r\n\t\t};\r\n\r\n\t\t// Difference mapping.\r\n\t\tthis.g_eDifferenceMapping = {\r\n\t\t\tBoth: 0,\r\n\t\t\tApprovalOnly: 1,\r\n\t\t\tCompareOnly: 2\r\n\t\t};\r\n\r\n\t\t// Outline the difference statuses.\r\n\t\tthis.eDifferenceStatuses = {\r\n\t\t\tInitial: 0,\r\n\t\t\tIgnore: 1,\r\n\t\t\tAccept: 2,\r\n\t\t\tReject: 3\r\n\t\t};\r\n\r\n\t\t// Outline the accuracy levels.\r\n\t\tthis.eAccuracyLevels = {\r\n\t\t\tWord: 1,\r\n\t\t\tCharacter: 2\r\n\t\t};\r\n\r\n\t\t// Outline the case sensitivity levels.\r\n\t\tthis.eCaseSensitivityLevels = {\r\n\t\t\tOff: 1,\r\n\t\t\tOn: 2\r\n\t\t};\r\n\r\n\t\t// Outline the bold italic detection levels.\r\n\t\tthis.eBoldItalicDetectionLevels = {\r\n\t\t\tOff: 1,\r\n\t\t\tOn: 2\r\n\t\t};\r\n\r\n\t\t// Outline the whitespace detection levels.\r\n\t\tthis.eWhitespaceDetectionLevels = {\r\n\t\t\tOff: 1,\r\n\t\t\tOn: 2\r\n\t\t};\r\n\r\n\t\t// Outline the auto selection levels.\r\n\t\tthis.eAutoSelectionLevels = {\r\n\t\t\tOff: 1,\r\n\t\t\tOn: 2\r\n\t\t};\r\n\r\n\t\t// Keeps track of if a text compare is in progress.\r\n\t\tthis.g_bTextCompareInProgress = false;\r\n\r\n\t\t// Keep track of if the text data has been loaded for each canvas.\r\n\t\tthis.g_bArtworkTextDataLoaded = false;\r\n\t\tthis.g_bCompareTextDataLoaded = false;\r\n\r\n\t\t// Keep track of stored text selection groups.\r\n\t\tthis.g_oStoredTextSelectionGroups = [];\r\n\r\n\t\t// Keep track of the text selection groups for both canvas.\r\n\t\tthis.g_oArtworkTextSelectionGroups = [];\r\n\t\tthis.g_oCompareTextSelectionGroups = [];\r\n\r\n\t\t// Keep track of if the text compare div is shown.\r\n\t\tthis.g_bTextCompareDivShown = false;\r\n\r\n\t\t// Keep track of any collapsed sections.\r\n\t\tthis.g_oCollapsedSectionOrders = [];\r\n\r\n\t\t// Keep track of the hidden separations.\r\n\t\tthis.g_oHiddenSeparations = [];\r\n\r\n\t\t// Keep track of if we have calcuated differences.\r\n\t\tthis.g_bDifferencesCalculated = false;\r\n\r\n\t\t// Keep track of the number of differences.\r\n\t\tthis.g_iNumberOfDifferences = 0;\r\n\r\n\t\t// Keep track of the step through difference.\r\n\t\tthis.g_iStepThroughDifference = null;\r\n\r\n\t\t// The size of the marker.\r\n\t\tthis.g_iMarkerSize = 25 * g_oViewer.c_iDPI;\r\n\r\n\t\t// The colour to highlight in.\r\n\t\tthis.g_szHighlightColour = \"yellow\";\r\n\r\n\t\t// Keep track of if we can leave difference annotations.\r\n\t\tthis.g_bDifferenceAnnotations = false;\r\n\r\n\t\t// Keep track of the accuracy.\r\n\t\tthis.g_iAccuracy = this.eAccuracyLevels.Word;\r\n\r\n\t\t// Keep track of the case sensitivity.\r\n\t\tthis.g_iCaseSensitivity = this.eCaseSensitivityLevels.On;\r\n\r\n\t\t// Keep track of the bold italic detection.\r\n\t\tthis.g_iBoldItalicDetection = this.eBoldItalicDetectionLevels.On;\r\n\r\n\t\t// Keep track of the whitespace detection.\r\n\t\tthis.g_iWhitespaceDetection = this.eWhitespaceDetectionLevels.On;\r\n\r\n\t\t// Keep track of the whitespace detection.\r\n\t\tthis.g_iAutoSelection = this.eAutoSelectionLevels.On;\r\n\r\n\t\t// Keep track of if we are drag scrolling.\r\n\t\tthis.g_bDragScrolling = false;\r\n\r\n\t\t// Update flag for automatically activating the pan tool on highlight end.\r\n\t\tthis.g_bAutoActivatePanTool = true;\r\n\r\n\t\t// Keep track of any auto activate text highlight object.\r\n\t\tthis.g_oAutoActivateTextHighlight = null;\r\n\r\n\t\t// Keep track of if the new highlight is being added to an existing group.\r\n\t\tthis.g_iAddHighlightToExistingGroup = null;\r\n\t};\r\n\r\n\t/**\r\n\t * Sets the text compare mode active.\r\n\t */\r\n\tTextCompare.prototype.setTextCompareActive = function () {\r\n\r\n\t\t// Set the initial settings.\r\n\t\tg_oTextCompare.setTextCompareSettings();\r\n\r\n\t\t// Update the settings.\r\n\t\tg_oTextCompare.updateTextCompareSettings();\r\n\r\n\t\t// Set that we are now in text compare mode.\r\n\t\tg_oTextCompare.g_bTextCompareInProgress = true;\r\n\t};\r\n\r\n\t/**\r\n\t * Sets the text compare settings.\r\n\t */\r\n\tTextCompare.prototype.setTextCompareSettings = function () {\r\n\r\n\t\t// Update the text compare settings levels to the users settings.\r\n\t\t$(\"#divTextComparisonAccuracy\").val(g_oSettings.g_oUserSettings.TextComparisonAccuracy);\r\n\t\t$(\"#divTextComparisonCaseSensitivity\").val(g_oSettings.g_oUserSettings.TextComparisonCaseSensitivity);\r\n\t\t$(\"#divTextComparisonBoldItalicDetection\").val(g_oSettings.g_oUserSettings.TextComparisonBoldItalicDetection);\r\n\t\t$(\"#divTextComparisonWhitespaceDetection\").val(g_oSettings.g_oUserSettings.TextComparisonWhitespaceDetection);\r\n\t\t$(\"#divTextComparisonAutoSelection\").val(g_oSettings.g_oUserSettings.TextComparisonAutoSelection);\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the text compare settings.\r\n\t */\r\n\tTextCompare.prototype.updateTextCompareSettings = function () {\r\n\r\n\t\t// Update the settings.\r\n\t\tg_oTextCompare.g_iAccuracy = parseInt($(\"#divTextComparisonAccuracy\").val());\r\n\t\tg_oTextCompare.g_iCaseSensitivity = parseInt($(\"#divTextComparisonCaseSensitivity\").val());\r\n\t\tg_oTextCompare.g_iBoldItalicDetection = parseInt($(\"#divTextComparisonBoldItalicDetection\").val());\r\n\t\tg_oTextCompare.g_iWhitespaceDetection = parseInt($(\"#divTextComparisonWhitespaceDetection\").val());\r\n\t\tg_oTextCompare.g_iAutoSelection = parseInt($(\"#divTextComparisonAutoSelection\").val());\r\n\r\n\t\t// Update the initial highlight colour.\r\n\t\tg_oTextCompare.g_szHighlightColour = g_oAnnotations.getStringColour(g_oSettings.g_oUserSettings.TextComparisonHighlightColour);\r\n\r\n\t\t// If we have the text compare div shown.\r\n\t\tif (g_oTextCompare.g_bTextCompareDivShown) {\r\n\r\n\t\t\t// Render the text compare sections to the new settings.\r\n\t\t\tg_oTextCompare.renderTextCompareSections();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Sets the text compare mode inactive.\r\n\t */\r\n\tTextCompare.prototype.setTextCompareUnactive = function () {\r\n\r\n\t\t// Reset the text selection groups.\r\n\t\tg_oTextCompare.g_oArtworkTextSelectionGroups = [];\r\n\t\tg_oTextCompare.g_oCompareTextSelectionGroups = [];\r\n\r\n\t\t// Reset the step through.\r\n\t\tg_oTextCompare.g_iStepThroughDifference = null;\r\n\r\n\t\t// Hide the differences bottom bar.\r\n\t\t$(\"#divTextDifferences\").hide();\r\n\r\n\t\t// Hide the text compare page navigations.\r\n\t\t$(\"#divTextCompare_ApprovalPageNavigation\").hide();\r\n\t\t$(\"#divTextCompare_ComparePageNavigation\").hide();\r\n\r\n\t\t// Set that we are no longer in text compare mode.\r\n\t\tg_oTextCompare.g_bTextCompareInProgress = false;\r\n\t};\r\n\r\n\t/**\r\n\t * Stores the active text selection groups.\r\n\t */\r\n\tTextCompare.prototype.storeActiveTextSelectionGroups = function () {\r\n\r\n\t\t// Store the active text selection groups for both canvas.\r\n\t\tg_oTextCompare.storeTextSelectionGroups(g_oTextCompare.g_oArtworkTextSelectionGroups, g_oViewer.g_oArtworkViewer);\r\n\t\tg_oTextCompare.storeTextSelectionGroups(g_oTextCompare.g_oCompareTextSelectionGroups, g_oCompare.g_oCompareViewer);\r\n\t};\r\n\r\n\t/**\r\n\t * Stores the text selection groups.\r\n\t * @param {object} oTextSelectionGroups - The text selection groups.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t */\r\n\tTextCompare.prototype.storeTextSelectionGroups = function (oTextSelectionGroups, oArtworkCanvas) {\r\n\r\n\t\t// If this artwork already has stored text selection groups, remove the old data.\r\n\t\tif (g_oTextCompare.getStoredTextSelectionGroupIndex(oArtworkCanvas) != -1) {\r\n\t\t\tg_oTextCompare.g_oStoredTextSelectionGroups.splice(g_oTextCompare.getStoredTextSelectionGroupIndex(oArtworkCanvas), 1);\r\n\t\t}\r\n\r\n\t\t// Store the text selection groups.\r\n\t\tg_oTextCompare.g_oStoredTextSelectionGroups.push(new g_oTextCompare.textSelectionGroups(deepCopyArray(oTextSelectionGroups), oArtworkCanvas));\r\n\t};\r\n\r\n\t/**\r\n\t * Retrieves the stored text selection groups.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t */\r\n\tTextCompare.prototype.retrieveTextSelectionGroups = function (oArtworkCanvas) {\r\n\t\tvar iIndex = g_oTextCompare.getStoredTextSelectionGroupIndex(oArtworkCanvas);\r\n\t\treturn iIndex > -1 ? deepCopyArray(g_oTextCompare.g_oStoredTextSelectionGroups[iIndex].g_oTextSelectionGroups) : [];\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the stored text selection index.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t */\r\n\tTextCompare.prototype.getStoredTextSelectionGroupIndex = function (oArtworkCanvas) {\r\n\t\tfor (var i = 0; i < g_oTextCompare.g_oStoredTextSelectionGroups.length; i++) {\r\n\t\t\tif (g_oTextCompare.g_oStoredTextSelectionGroups[i].g_szCanvasId == oArtworkCanvas.g_szCanvasId && g_oTextCompare.g_oStoredTextSelectionGroups[i].g_iDocumentId == oArtworkCanvas.g_oDoc.documentId) {\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn -1;\r\n\t};\r\n\r\n\t/**\r\n\t * Initialises text compare.\r\n\t */\r\n\tTextCompare.prototype.initialiseTextCompare = function () {\r\n\r\n\t\t// Close any active confirm bubbles as these may be related to text compare.\r\n\t\tg_oGreenlightMessages.closeBubbles(\"Confirm\");\r\n\r\n\t\t// If we have not yet loaded the text equivalents, load these now.\r\n\t\tif (g_oTextCompare_Equivalents.g_oTextEquivalents == null) {\r\n\t\t\tg_oTextCompare_Equivalents.loadTextEquivalents();\r\n\t\t}\r\n\r\n\t\t// Reset the loaded flags.\r\n\t\tg_oTextCompare.g_bArtworkTextDataLoaded = false;\r\n\t\tg_oTextCompare.g_bCompareTextDataLoaded = false;\r\n\r\n\t\t// Load the artwork and compare canvas.\r\n\t\tvar oArtworkCanvas = g_oViewer.g_oArtworkViewer;\r\n\t\tvar oCompareCanvas = g_oCompare.g_oCompareViewer;\r\n\r\n\t\t// Retrieve the stored text selection groups for both canvas.\r\n\t\tg_oTextCompare.g_oArtworkTextSelectionGroups = g_oTextCompare.retrieveTextSelectionGroups(oArtworkCanvas);\r\n\t\tg_oTextCompare.g_oCompareTextSelectionGroups = g_oTextCompare.retrieveTextSelectionGroups(oCompareCanvas);\r\n\r\n\t\t// Call to load the text data for the canvas.\r\n\t\tg_oTextData.loadFullTextData(oArtworkCanvas.g_oDoc, function () { g_oTextCompare.g_bArtworkTextDataLoaded = true; g_oTextCompare.initialiseTextCompare_CH(); });\r\n\t\tg_oTextData.loadFullTextData(oCompareCanvas.g_oDoc, function () { g_oTextCompare.g_bCompareTextDataLoaded = true; g_oTextCompare.initialiseTextCompare_CH(); });\r\n\t};\r\n\r\n\t/**\r\n\t * Callback for initialising text compare.\r\n\t */\r\n\tTextCompare.prototype.initialiseTextCompare_CH = function () {\r\n\r\n\t\t// Only continue once all text data has been loaded.\r\n\t\tif (!g_oTextCompare.g_bArtworkTextDataLoaded || !g_oTextCompare.g_bCompareTextDataLoaded) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Update the approval and compare document page navigations.\r\n\t\tg_oTextCompare.updatePageNavigation(\"divApprovalName\", \"divTextCompare_ApprovalPageNavigation\", g_oViewer.g_oArtworkViewer);\r\n\t\tg_oTextCompare.updatePageNavigation(\"divCompareName\", \"divTextCompare_ComparePageNavigation\", g_oCompare.g_oCompareViewer);\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\r\n\t\t// Show the text compare div.\r\n\t\tg_oTextCompare.showTextCompareDiv();\r\n\r\n\t\t// Re-activate any stored text selection tool.\r\n\t\tg_oTextCompare.setActiveTextSelectionTool();\r\n\r\n\t\t// Enable the select lists if these are not locked by the consumer.\r\n\t\t$(\"#divTextComparisonAccuracy\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonAccuracy ? \"disabled\" : \"\");\r\n\t\t$(\"#divTextComparisonCaseSensitivity\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonCaseSensitivity ? \"disabled\" : \"\");\r\n\t\t$(\"#divTextComparisonBoldItalicDetection\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonBoldItalicDetection ? \"disabled\" : \"\");\r\n\t\t$(\"#divTextComparisonWhitespaceDetection\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonWhitespaceDetection ? \"disabled\" : \"\");\r\n\t\t$(\"#divTextComparisonAutoSelection\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonAutoSelection ? \"disabled\" : \"\");\r\n\t};\r\n\r\n\t/**\r\n\t * Stores the active text selection tool.\r\n\t */\r\n\tTextCompare.prototype.storeActiveTextSelectionTool = function () {\r\n\r\n\t\t// Reset the active text selection tool.\r\n\t\tg_oTextCompare.resetActiveTextSelectionTool();\r\n\r\n\t\t// If we are actively adding to a text group on this page, store this so we can continue adding after changing page.\r\n\t\tif (g_oTextTools.g_bHighlightInProgress && g_oTextTools.g_eActiveToolType !== 3) {\r\n\r\n\t\t\t// Determine if we are adding to an existing group.\r\n\t\t\tvar iAddToExistingGroup = null;\r\n\t\t\tif (g_oTextCompare.g_iAddHighlightToExistingGroup != null) {\r\n\t\t\t\tiAddToExistingGroup = g_oTextCompare.g_iAddHighlightToExistingGroup;\r\n\t\t\t}\r\n\t\t\telse if (g_oTextTools.g_iExistingAnnotationId != null) {\r\n\t\t\t\tiAddToExistingGroup = g_oTextTools.g_iExistingAnnotationId.selectionGroup;\r\n\t\t\t}\r\n\r\n\t\t\t// Setup the auto activate object.\r\n\t\t\tg_oTextCompare.g_oAutoActivateTextHighlight = {\r\n\t\t\t\tbCompareCanvas: g_oTextTools.g_bHighlightOnCompareCanvas,\r\n\t\t\t\teActiveToolType: g_oTextTools.g_eActiveToolType,\r\n\t\t\t\tiAddToExistingGroup: iAddToExistingGroup\r\n\t\t\t};\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Sets the active text selection tool.\r\n\t */\r\n\tTextCompare.prototype.setActiveTextSelectionTool = function () {\r\n\r\n\t\t// If we want to automatically activate a text highlight tool, start this back up.\r\n\t\tif (g_oTextCompare.g_oAutoActivateTextHighlight != null) {\r\n\t\t\tsetTimeout(function () {\r\n\r\n\t\t\t\t// Re-activate the tool.\r\n\t\t\t\tswitch (g_oTextCompare.g_oAutoActivateTextHighlight.eActiveToolType) {\r\n\t\t\t\t\tcase g_oTextTools.g_eToolTypes.TextHighlight:\r\n\t\t\t\t\t\tg_oTextCompare.initialiseTextCompareHighlight(g_oTextCompare.g_oAutoActivateTextHighlight.bCompareCanvas, g_oTextCompare.g_oAutoActivateTextHighlight.iAddToExistingGroup);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase g_oTextTools.g_eToolTypes.ParagraphHighlight:\r\n\t\t\t\t\t\tg_oTextCompare.initialiseTextCompareParagraphHighlight(g_oTextCompare.g_oAutoActivateTextHighlight.bCompareCanvas, g_oTextCompare.g_oAutoActivateTextHighlight.iAddToExistingGroup);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase g_oTextTools.g_eToolTypes.AreaTextHighlight:\r\n\t\t\t\t\t\tg_oTextCompare.initialiseTextCompareAreaHighlight(g_oTextCompare.g_oAutoActivateTextHighlight.bCompareCanvas, g_oTextCompare.g_oAutoActivateTextHighlight.iAddToExistingGroup);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase g_oTextTools.g_eToolTypes.RemoveTextHighlight:\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Reset the active text selection tool.\r\n\t\t\t\tg_oTextCompare.resetActiveTextSelectionTool();\r\n\t\t\t}, 500);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Resets the text selection tool.\r\n\t */\r\n\tTextCompare.prototype.resetActiveTextSelectionTool = function () {\r\n\t\tg_oTextCompare.g_oAutoActivateTextHighlight = null;\r\n\t};\r\n\r\n\t/**\r\n\t * Shows the text compare div.\r\n\t */\r\n\tTextCompare.prototype.showTextCompareDiv = function () {\r\n\r\n\t\t// Set the bottom position and height of the div to match the canvas height.\r\n\t\t$(\"#divTextCompare\").css(\"bottom\", \"-\" + $(\"#divCanvasHolder\").height() + \"px\");\r\n\t\t$(\"#divTextCompareContent\").css(\"height\", $(\"#divCanvasHolder\").height());\r\n\r\n\t\t// Show the text compare div.\r\n\t\t$(\"#divTextCompare\").show();\r\n\t};\r\n\r\n\t/**\r\n\t * Hides the text compare div.\r\n\t */\r\n\tTextCompare.prototype.hideTextCompareDiv = function () {\r\n\r\n\t\t// Hide the text compare div.\r\n\t\t$(\"#divTextCompare\").hide();\r\n\t};\r\n\r\n\t/**\r\n\t * Toggles the text compare div.\r\n\t */\r\n\tTextCompare.prototype.toggleTextCompareDiv = function () {\r\n\r\n\t\t// If we have an active text highlight, end this.\r\n\t\tif (g_oTextTools.g_bHighlightInProgress) {\r\n\t\t\tg_oTextCompare.endTextCompareHighlight();\r\n\t\t}\r\n\r\n\t\t// Toggle the text compare div state.\r\n\t\tg_oTextCompare.g_bTextCompareDivShown = !g_oTextCompare.g_bTextCompareDivShown;\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\r\n\t\t// Update the size of the text compare div.\r\n\t\tg_oTextCompare.updateTextCompareDiv();\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the text compare div.\r\n\t */\r\n\tTextCompare.prototype.updateTextCompareDiv = function () {\r\n\r\n\t\t// Determine the div and icon position.\r\n\t\tvar iDivPosition = g_oTextCompare.g_bTextCompareDivShown ? 0 : 0 - $(\"#divCanvasHolder\").height();\r\n\t\tvar iIconMargin = g_oTextCompare.g_bTextCompareDivShown ? 0 : -40;\r\n\t\tvar iIconRotation = g_oTextCompare.g_bTextCompareDivShown ? 90 : -90;\r\n\t\tvar iIconBorderRadius = g_oTextCompare.g_bTextCompareDivShown ? \"0px 0px 0px 8px\" : \"8px 0px 0px 0px\";\r\n\r\n\t\t// Update the height of the text compare div.\r\n\t\t$(\"#divTextCompareContent\").css(\"height\", $(\"#divCanvasHolder\").height());\r\n\r\n\t\t// Slide the div to the correct position.\r\n\t\t$(\"#divTextCompare\").animate({\r\n\t\t\tbottom: iDivPosition + 'px'\r\n\t\t}, 800);\r\n\r\n\t\t// Move the icon to the correct position.\r\n\t\t$(\"#divTextCompareButton\").animate({\r\n\t\t\t\"margin-top\": iIconMargin + 'px'\r\n\t\t}, 800);\r\n\t\t$(\"#divTextCompareButton\").css(\"border-radius\", iIconBorderRadius);\r\n\t\t$(\"#divTextCompareArrow\").css(\"transform\", \"rotate(\" + iIconRotation + \"deg)\");\r\n\r\n\t\t// Update the height of the text compare sections.\r\n\t\tg_oTextCompare.updateTextCompareSectionsHeight();\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the height of the text comapare sections div.\r\n\t */\r\n\tTextCompare.prototype.updateTextCompareSectionsHeight = function () {\r\n\r\n\t\t// Set the height of the sections.\r\n\t\t$(\"#divTextCompareSections\").css(\"height\", ($(\".divTextCompareContent__Wrapper\").height() - $(\"#divTextCompareSections\").position().top - 20) + \"px\");\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the page navigation.\r\n\t * @param {string} szParentDiv - The parent div.\r\n\t * @param {string} szNavigationDiv - The navigation div.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t */\r\n\tTextCompare.prototype.updatePageNavigation = function (szParentDiv, szNavigationDiv, oArtworkCanvas) {\r\n\r\n\t\t// Ensure the navigation div exists.\r\n\t\tif ($(\"#\" + szParentDiv).children(\"#\" + szNavigationDiv).length == 0) {\r\n\t\t\t$(\"#\" + szParentDiv).append(\"\");\r\n\t\t}\r\n\r\n\t\t// If this doc does not have multiple pages, hide the navigation div.\r\n\t\tif (oArtworkCanvas.g_oDoc.pages.length < 2) {\r\n\t\t\t$(\"#\" + szNavigationDiv).css(\"display\", \"none\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Determine if the navigation buttons are enabled / disabled.\r\n\t\tvar bBackButtonDisabled = oArtworkCanvas.g_iCurrentPage == 1;\r\n\t\tvar bNextButtonDisabled = oArtworkCanvas.g_iCurrentPage == oArtworkCanvas.g_oDoc.pages.length;\r\n\r\n\t\t// Build the document page navigation for the control.\r\n\t\tvar szHTML = '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += 'Page ' + oArtworkCanvas.g_iCurrentPage + ' of ' + oArtworkCanvas.g_oDoc.pages.length + '';\r\n\t\tszHTML += '';\r\n\r\n\t\t// Apply the html.\r\n\t\t$(\"#\" + szNavigationDiv).html(szHTML);\r\n\r\n\t\t// Show the navigation div.\r\n\t\t$(\"#\" + szNavigationDiv).css(\"display\", \"inline-block\");\r\n\t};\r\n\r\n\t/**\r\n\t * Changes the document.\r\n\t */\r\n\tTextCompare.prototype.changeDocument = function () {\r\n\r\n\t\t// If the review screen is open, close this.\r\n\t\tif (g_oTextCompare.g_bTextCompareDivShown) {\r\n\t\t\tg_oTextCompare.toggleTextCompareDiv();\r\n\t\t}\r\n\r\n\t\t// Hide the text compare information.\r\n\t\tg_oTextCompare.hideTextCompareInformation();\r\n\r\n\t\t// Hide the separations.\r\n\t\tg_oTextCompare.hideTextCompareSeparations();\r\n\r\n\t\t// Store the active text selections.\r\n\t\tg_oTextCompare.storeActiveTextSelectionGroups();\r\n\r\n\t\t// Reset the loading status of both documents.\r\n\t\tg_oTextCompare.g_bArtworkTextDataLoaded = false;\r\n\t\tg_oTextCompare.g_bCompareTextDataLoaded = false;\r\n\t};\r\n\r\n\t/**\r\n\t * Changes the page to the next or previous page.\r\n\t * @param {boolean} bNextPage - If we are changing to the next or previous page.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.changePage = function (bNextPage, bCompareCanvas) {\r\n\r\n\t\t// Get the canvas we are going to change the page of.\r\n\t\tvar oArtworkCanvas = !bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\r\n\t\t// Determine the page we will be changing to.\r\n\t\tvar iNewPage = bNextPage ? oArtworkCanvas.g_iCurrentPage + 1 : oArtworkCanvas.g_iCurrentPage - 1;\r\n\r\n\t\t// Change to the new page.\r\n\t\tg_oTextCompare.changeToPage(iNewPage, bCompareCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Changes the page to an exact page.\r\n\t * @param {boolean} iNewPage - The page we are going to change to.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.changeToPage = function (iNewPage, bCompareCanvas) {\r\n\r\n\t\t// Store any active text selection tool.\r\n\t\tg_oTextCompare.storeActiveTextSelectionTool();\r\n\r\n\t\t// If we have an active text highlight, end this.\r\n\t\tif (g_oTextTools.g_bHighlightInProgress) {\r\n\t\t\tg_oTextTools.endhighlight(g_oViewer.g_oArtworkViewer, g_oViewer.g_oAnnotationViewer, true);\r\n\t\t}\r\n\r\n\t\t// If the review screen is open, close this.\r\n\t\tif (g_oTextCompare.g_bTextCompareDivShown) {\r\n\t\t\tg_oTextCompare.toggleTextCompareDiv();\r\n\t\t}\r\n\r\n\t\t// Hide the text compare information.\r\n\t\tg_oTextCompare.hideTextCompareInformation();\r\n\r\n\t\t// Hide the separations.\r\n\t\tg_oTextCompare.hideTextCompareSeparations();\r\n\r\n\t\t// Store the active text selections.\r\n\t\tg_oTextCompare.storeActiveTextSelectionGroups();\r\n\r\n\t\t// Get the canvas we are going to update the page of.\r\n\t\tvar oArtworkCanvas = !bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\tvar oAnnotationCanvas = !bCompareCanvas ? g_oViewer.g_oAnnotationViewer : g_oCompare.g_oCompareAnnotationViewer;\r\n\r\n\t\t// Ensure the new page exists.\r\n\t\tif (oArtworkCanvas.g_oDoc.pages[iNewPage - 1] == undefined) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Store the current page.\r\n\t\tvar iCurrentPage = oArtworkCanvas.g_iCurrentPage;\r\n\r\n\t\t// Update the page number.\r\n\t\toArtworkCanvas.g_iCurrentPage = iNewPage;\r\n\r\n\t\t// Determine if the two pages have the same resolution.\r\n\t\tif (oArtworkCanvas.g_oDoc.pages[iCurrentPage - 1].documentResolutionPPI == oArtworkCanvas.g_oDoc.pages[iNewPage - 1].documentResolutionPPI) {\r\n\r\n\t\t\t// Reset the canvas that is having its page changed.\r\n\t\t\toArtworkCanvas.resetCanvas();\r\n\r\n\t\t\t// Update the combo control.\r\n\t\t\tvar iControlIndex = comboControl_GetControlById((oArtworkCanvas.g_szCanvasId === \"ArtworkViewer\" ? \"approvalNameComboControl\" : \"approvalCompareComboControl\"), true);\r\n\t\t\tvar iDocumentIndex = comboControl_GetDocumentById(iControlIndex, oArtworkCanvas.g_oDoc.documentId, true);\r\n\t\t\tvar iPageIndex = comboControl_GetPageById(iControlIndex, iDocumentIndex, oArtworkCanvas.g_oDoc.pages[iNewPage - 1].documentPageId, true);\r\n\t\t\tcomboControl_SelectOption(iControlIndex, iDocumentIndex, iPageIndex, false);\r\n\r\n\t\t\t// Update the canvas files.\r\n\t\t\tvar iCanvasFileRequestId = Math.random();\r\n\t\t\tg_oCompare.g_iCanvasFileRequestId = iCanvasFileRequestId;\r\n\t\t\toArtworkCanvas.getCanvasFiles(true, iCanvasFileRequestId);\r\n\t\t}\r\n\t\t// If the two pages do not have the same resolution.\r\n\t\telse {\r\n\r\n\t\t\t// Change the current page fully reloading both documents.\r\n\t\t\toArtworkCanvas.changeCurrentPage();\r\n\t\t}\r\n\r\n\t\t// Publish the event to trigger a full reload of both documents.\r\n\t\tEventService.publish(\"changeCurrentPage\", oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Initialises a text compare highlight.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t * @param {int} iAddToExistingGroup - Int if we are adding to an existing group, null if we are not.\r\n\t */\r\n\tTextCompare.prototype.initialiseTextCompareHighlight = function (bCompareCanvas, iAddToExistingGroup) {\r\n\r\n\t\t// Re-render both annotation canvas before starting the highlight.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\r\n\t\t// Set that this will be a new annotation.\r\n\t\tg_oTextTools.g_iExistingAnnotationId = null;\r\n\r\n\t\t// Set if this will be added to an existing group.\r\n\t\tg_oTextCompare.g_iAddHighlightToExistingGroup = iAddToExistingGroup;\r\n\r\n\t\t// Set up the new annotation text.\r\n\t\tg_oTextTools.g_oAnnotationText = [];\r\n\r\n\t\t// Determine if this is at character level accuracy.\r\n\t\tvar bCharacterLevelAccuracy = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Character;\r\n\r\n\t\t// Initialise the text highlight.\r\n\t\tg_oTextTools.initialiseTextTool(g_oTextTools.g_eToolTypes.TextHighlight, eAnnotationTypes.TextHighlight, bCharacterLevelAccuracy, bCompareCanvas, g_oTextCompare.g_szHighlightColour);\r\n\t};\r\n\r\n\t/**\r\n\t * Initialises a text compare paragraph highlight.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t * @param {int} iAddToExistingGroup - Int if we are adding to an existing group, null if we are not.\r\n\t */\r\n\tTextCompare.prototype.initialiseTextCompareParagraphHighlight = function (bCompareCanvas, iAddToExistingGroup) {\r\n\r\n\t\t// Re-render both annotation canvas before starting the highlight.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\r\n\t\t// Set that this will be a new annotation.\r\n\t\tg_oTextTools.g_iExistingAnnotationId = null;\r\n\r\n\t\t// Set if this will be added to an existing group.\r\n\t\tg_oTextCompare.g_iAddHighlightToExistingGroup = iAddToExistingGroup;\r\n\r\n\t\t// Set up the new annotation text.\r\n\t\tg_oTextTools.g_oAnnotationText = [];\r\n\r\n\t\t// Determine if this is at character level accuracy.\r\n\t\tvar bCharacterLevelAccuracy = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Character;\r\n\r\n\t\t// Initialise the paragraph highlight.\r\n\t\tg_oTextTools.initialiseTextTool(g_oTextTools.g_eToolTypes.ParagraphHighlight, eAnnotationTypes.TextHighlight, bCharacterLevelAccuracy, bCompareCanvas, g_oTextCompare.g_szHighlightColour);\r\n\t};\r\n\r\n\t/**\r\n\t * Initialises the text compare add highlight.\r\n\t * @param {int} iSelectionGroup - The selection group.\r\n\t * @param {int} iSelection - The selection.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.initialiseTextCompareAddHighlight = function (iSelectionGroup, iSelection, bParagraphHighlight, bCompareCanvas) {\r\n\r\n\t\t// Set that this will be an edit to an existing annotation.\r\n\t\tg_oTextTools.g_iExistingAnnotationId = {\r\n\t\t\t\"selectionGroup\": iSelectionGroup,\r\n\t\t\t\"selection\": iSelection\r\n\t\t};\r\n\r\n\t\t// Set that this will not be added to an existing group.\r\n\t\tg_oTextCompare.g_iAddHighlightToExistingGroup = null;\r\n\r\n\t\t// Get the text selection group we are going to add to.\r\n\t\tvar oTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// Set up the new annotation text.\r\n\t\tg_oTextTools.g_oAnnotationText = bCompareCanvas ? oTextSelectionGroup[iSelectionGroup].g_oTextSelections[iSelection].g_oTextData : oTextSelectionGroup[iSelectionGroup].g_oTextSelections[iSelection].g_oTextData;\r\n\r\n\t\t// Determine the highlight tool to be used.\r\n\t\tvar eHighlightTool = !bParagraphHighlight ? g_oTextTools.g_eToolTypes.TextHighlight : g_oTextTools.g_eToolTypes.ParagraphHighlight;\r\n\r\n\t\t// Determine if this is at character level accuracy.\r\n\t\tvar bCharacterLevelAccuracy = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Character;\r\n\r\n\t\t// Initialise the text highlight.\r\n\t\tg_oTextTools.initialiseTextTool(eHighlightTool, eAnnotationTypes.TextHighlight, bCharacterLevelAccuracy, bCompareCanvas, g_oTextCompare.g_szHighlightColour);\r\n\t};\r\n\r\n\t/**\r\n\t * Initialises a text removal highlight.\r\n\t * @param {int} iSelectionGroup - The selection group.\r\n\t * @param {int} iSelection - The selection.\r\n\t * @param {bool} bParagraphHighlight - If this is a paragraph highlight.\r\n\t * @param {bool} bCompareCanvas - The compare canvas.\r\n\t */\r\n\tTextCompare.prototype.initialiseTextCompareRemoveHighlight = function (iSelectionGroup, iSelection, bParagraphHighlight, bCompareCanvas) {\r\n\r\n\t\t// Set that this will be an edit to an existing annotation.\r\n\t\tg_oTextTools.g_iExistingAnnotationId = {\r\n\t\t\t\"selectionGroup\": iSelectionGroup,\r\n\t\t\t\"selection\": iSelection\r\n\t\t};\r\n\r\n\t\t// Get the text selection group we are going to remove from.\r\n\t\tvar oTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// Set up the new annotation text.\r\n\t\tg_oTextTools.g_oAnnotationText = bCompareCanvas ? oTextSelectionGroup[iSelectionGroup].g_oTextSelections[iSelection].g_oTextData : oTextSelectionGroup[iSelectionGroup].g_oTextSelections[iSelection].g_oTextData;\r\n\r\n\t\t// Determine if this is at character level accuracy.\r\n\t\tvar bCharacterLevelAccuracy = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Character;\r\n\r\n\t\t// Initialise the text highlight removal.\r\n\t\tg_oTextTools.initialiseTextTool(g_oTextTools.g_eToolTypes.RemoveTextHighlight, eAnnotationTypes.TextHighlight, bCharacterLevelAccuracy, bCompareCanvas, g_oTextCompare.g_szHighlightColour);\r\n\t};\r\n\r\n\t/**\r\n\t * Initialises the text compare area highlight tool.\r\n\t * @param {bool} bCompareCanvas - If this is the compare canvas.\r\n\t * @param {int} iAddToExistingGroup - Id of an existing group if we are adding to an existing group.\r\n\t */\r\n\tTextCompare.prototype.initialiseTextCompareAreaHighlight = function (bCompareCanvas, iAddToExistingGroup) {\r\n\r\n\t\t// Re-render both annotation canvas before starting the highlight.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\r\n\t\t// Set that this will be a new annotation.\r\n\t\tg_oTextTools.g_iExistingAnnotationId = null;\r\n\r\n\t\t// Set if this will be added to an existing group.\r\n\t\tg_oTextCompare.g_iAddHighlightToExistingGroup = iAddToExistingGroup;\r\n\r\n\t\t// Set up the new annotation text.\r\n\t\tg_oTextTools.g_oAnnotationText = [];\r\n\r\n\t\t// Determine if this is at character level accuracy.\r\n\t\tvar bCharacterLevelAccuracy = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Character;\r\n\r\n\t\t// Initialise the text highlight.\r\n\t\tg_oTextTools.initialiseTextTool(g_oTextTools.g_eToolTypes.AreaTextHighlight, eAnnotationTypes.TextHighlight, bCharacterLevelAccuracy, bCompareCanvas, g_oTextCompare.g_szHighlightColour);\r\n\t};\r\n\r\n\t/**\r\n\t * Initialises the text compare add tool.\r\n\t * @param {int} iSelectionGroup - The selection group.\r\n\t * @param {int} iSelection - The selection.\r\n\t * @param {bool} bParagraphHighlight - If this is a paragraph highlight.\r\n\t * @param {bool} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.initialiseTextCompareAddArea = function (iSelectionGroup, iSelection, bParagraphHighlight, bCompareCanvas) {\r\n\r\n\t\t// Set that this will be an edit to an existing annotation.\r\n\t\tg_oTextTools.g_iExistingAnnotationId = {\r\n\t\t\t\"selectionGroup\": iSelectionGroup,\r\n\t\t\t\"selection\": iSelection\r\n\t\t};\r\n\r\n\t\t// Set that this will not be added to an existing group.\r\n\t\tg_oTextCompare.g_iAddHighlightToExistingGroup = null;\r\n\r\n\t\t// Get the text selection group we are going to add to.\r\n\t\tvar oTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// Set up the new annotation text.\r\n\t\tg_oTextTools.g_oAnnotationText = bCompareCanvas ? oTextSelectionGroup[iSelectionGroup].g_oTextSelections[iSelection].g_oTextData : oTextSelectionGroup[iSelectionGroup].g_oTextSelections[iSelection].g_oTextData;\r\n\r\n\t\t// Determine if this is at character level accuracy.\r\n\t\tvar bCharacterLevelAccuracy = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Character;\r\n\r\n\t\t// Initialise the text highlight.\r\n\t\tg_oTextTools.initialiseTextTool(g_oTextTools.g_eToolTypes.AreaTextHighlight, eAnnotationTypes.TextHighlight, bCharacterLevelAccuracy, bCompareCanvas, g_oTextCompare.g_szHighlightColour);\r\n\t};\r\n\r\n\t/**\r\n\t * Ends a text compare highlight.\r\n\t */\r\n\tTextCompare.prototype.endTextCompareHighlight = function () {\r\n\r\n\t\t// Set that the next highlight will not be added to an existing group.\r\n\t\tg_oTextCompare.g_iAddHighlightToExistingGroup = null;\r\n\r\n\t\t// If we want to automatically activate the pan tool.\r\n\t\tif (g_oTextCompare.g_bAutoActivatePanTool) {\r\n\r\n\t\t\t// Set the user back to the pan tool.\r\n\t\t\tsetTimeout(function () { $(\"#btnPan_Viewer_TextCompare\").click(); }, 500);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets a text selection group.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.getTextSelectionGroup = function (bCompare) {\r\n\t\treturn bCompare ? g_oTextCompare.g_oCompareTextSelectionGroups : g_oTextCompare.g_oArtworkTextSelectionGroups;\r\n\t};\r\n\r\n\t/**\r\n\t * Adds text data.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t * @param {boolean} bAutoSelect - If auto selection is enabled.\r\n\t * @param {boolean} bRenderAnnotations - If annotations should be rendered.\r\n\t */\r\n\tTextCompare.prototype.addTextData = function (oTextData, bCompareCanvas, bAutoSelect, bRenderAnnotations) {\r\n\r\n\t\t// Unselect the highlight buttons.\r\n\t\t$(\"#btnTextHighlight_Viewer_TextCompare\").removeClass(\"selectedButton\");\r\n\t\t$(\"#btnTextHighlight_Compare_TextCompare\").removeClass(\"selectedButton\");\r\n\r\n\t\t// Ensure we have text data to be added.\r\n\t\tif (oTextData.length == 0) {\r\n\r\n\t\t\t// Close any open info bubbles.\r\n\t\t\tg_oGreenlightMessages.closeBubbles();\r\n\r\n\t\t\t// End the compare highlight.\r\n\t\t\tg_oTextCompare.endTextCompareHighlight();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get the artwork and annotation canvas.\r\n\t\tvar oArtworkCanvas = !bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\tvar oAnnotationCanvas = !bCompareCanvas ? g_oViewer.g_oAnnotationViewer : g_oCompare.g_oCompareAnnotationViewer;\r\n\r\n\t\t// Get the text selection groups we are going to add to.\r\n\t\tvar oTextSelectionGroups = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// Determine the group order to be used.\r\n\t\tvar iGroupOrder = g_oTextCompare.getHighestTextSelectionGroup(!bCompareCanvas, bCompareCanvas) + 1;\r\n\r\n\t\t// If we are adding this to an existing group.\r\n\t\tif (g_oTextCompare.g_iAddHighlightToExistingGroup != null && g_oTextCompare.g_iAddHighlightToExistingGroup >= 0 && g_oTextCompare.g_iAddHighlightToExistingGroup < oTextSelectionGroups.length) {\r\n\r\n\t\t\t// Add the text selection to the existing group.\r\n\t\t\toTextSelectionGroups[g_oTextCompare.g_iAddHighlightToExistingGroup].g_oTextSelections.push(new g_oTextCompare.textSelection(oTextData, oArtworkCanvas, oAnnotationCanvas));\r\n\r\n\t\t\t// If we have auto selection enabled, start the auto selection process.\r\n\t\t\tif (bAutoSelect) {\r\n\t\t\t\tvar oCompareCanvas = bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\t\t\tvar szJoinedSelectionText = g_oTextCompare.getJoinedSelectionsText(oTextSelectionGroups[g_oTextCompare.g_iAddHighlightToExistingGroup].g_oTextSelections);\r\n\t\t\t\tg_oTextCompare_AutoSelection.startAutoSelection(szJoinedSelectionText, bCompareCanvas, oCompareCanvas, oArtworkCanvas, oTextSelectionGroups[g_oTextCompare.g_iAddHighlightToExistingGroup]);\r\n\t\t\t}\r\n\r\n\t\t\t// Dont add the next highlight to an existing group.\r\n\t\t\tg_oTextCompare.g_iAddHighlightToExistingGroup = null;\r\n\t\t}\r\n\t\t// If we are adding this to a new group.\r\n\t\telse {\r\n\t\t\t// Create a new selection group.\r\n\t\t\tvar oNewSelectionGroup = new g_oTextCompare.textSelectionGroup(iGroupOrder);\r\n\r\n\t\t\tvar selectionText = new g_oTextCompare.textSelection(oTextData, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t\t// Add a new selection to the group.\r\n\t\t\toNewSelectionGroup.g_oTextSelections.push(selectionText);\r\n\r\n\t\t\t// Add the new selection group to the list.\r\n\t\t\toTextSelectionGroups.push(oNewSelectionGroup);\r\n\r\n\t\t\t// If we have auto selection enabled, start the auto selection process.\r\n\t\t\tif (bAutoSelect) {\r\n\t\t\t\tvar oCompareCanvas = bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\t\t\tvar oSelectionText = g_oSettings.g_oUserSettings.TextComparisonAccuracy == 2 ? selectionText.g_oSelectionCharactersText : selectionText.g_oSelectionWordsText;\r\n\t\t\t\tg_oTextCompare_AutoSelection.startAutoSelection(oSelectionText, bCompareCanvas, oCompareCanvas, oArtworkCanvas, oNewSelectionGroup);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Render the text compare annotations if required.\r\n\t\tif (bRenderAnnotations) {\r\n\t\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t\t}\r\n\r\n\t\t// End the compare highlight.\r\n\t\tg_oTextCompare.endTextCompareHighlight();\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the text data.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.updateTextData = function (oTextData, bCompareCanvas, autoSelect) {\r\n\r\n\t\t// Get the artwork and annotation canvas.\r\n\t\tvar oArtworkCanvas = !bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\tvar oAnnotationCanvas = !bCompareCanvas ? g_oViewer.g_oAnnotationViewer : g_oCompare.g_oCompareAnnotationViewer;\r\n\r\n\t\t// Get the text selection groups for the canvas.\r\n\t\tvar oTextSelectionGroups = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// Get the selection group we are going to update.\r\n\t\tvar oTextSelectionGroup = oTextSelectionGroups[g_oTextTools.g_iExistingAnnotationId.selectionGroup];\r\n\r\n\t\t// Exit the function early if not found.\r\n\t\tif (!oTextSelectionGroup) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get and update the selection.\r\n\t\tvar selectionText = new g_oTextCompare.textSelection(oTextData, oArtworkCanvas, oAnnotationCanvas);\t\t\r\n\t\toTextSelectionGroup.g_oTextSelections[g_oTextTools.g_iExistingAnnotationId.selection] = selectionText;\r\n\r\n\t\t// If we have auto select enabled, start the auto selection if we are not a linked selection.\r\n\t\tif (autoSelect && (typeof oTextSelectionGroup.isAutoSelected === \"undefined\" || !oTextSelectionGroup.isAutoSelected)) {\t\t\r\n\t\t\tvar oCompareCanvas = bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\t\tvar szJoinedSelectionText = g_oTextCompare.getJoinedSelectionsText(oTextSelectionGroup.g_oTextSelections);\r\n\t\t\tg_oTextCompare_AutoSelection.startAutoSelection(szJoinedSelectionText, bCompareCanvas, oCompareCanvas, oArtworkCanvas, oTextSelectionGroup);\r\n\t\t}\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\r\n\t\t// End the compare highlight if we are not going to automatically activate this again.\r\n\t\tif (g_oTextCompare.g_oAutoActivateTextHighlight == null) {\r\n\t\t\tg_oTextCompare.endTextCompareHighlight();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t* Joins the text selections into a single string.\r\n\t* @param {Array} g_oTextSelections - The array of text selections.\r\n\t* @returns {string} - The joined selection text.\r\n\t*/\r\n\tTextCompare.prototype.getJoinedSelectionsText = function (g_oTextSelections) {\r\n\r\n\t\t// Outline the string to store the joined selections text.\r\n\t\tvar szJoinedSelectionText = \"\";\r\n\r\n\t\t// Loop through each of the selections and join the text.\r\n\t\tfor (var i = 0; i < g_oTextSelections.length; i++) {\r\n\r\n\t\t\t// Extract the selection.\r\n\t\t\tvar oSelection = g_oTextSelections[i];\r\n\r\n\t\t\t// Get the text based on the accuracy.\r\n\t\t\tvar oSelectionText = g_oSettings.g_oUserSettings.TextComparisonAccuracy == 2 ? oSelection.g_oSelectionCharactersText : oSelection.g_oSelectionWordsText;\r\n\r\n\t\t\t// Add the text to the joined selection text.\r\n\t\t\tszJoinedSelectionText += oSelectionText;\r\n\r\n\t\t\t// Add a space if this is not the last selection.\r\n\t\t\tif (i !== g_oTextSelections.length - 1) {\r\n\t\t\t\tszJoinedSelectionText += \" \";\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the joined selection text.\r\n\t\treturn szJoinedSelectionText;\r\n\t};\r\n\r\n\t/**\r\n\t * Deletes the text data by group order.\r\n\t * @param {int} iGroupOrder - The order of the group.\r\n\t * @param {int} iSelection - The selection.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.deleteTextDataByGroupOrder = function (iGroupOrder, iSelection, bCompareCanvas) {\r\n\r\n\t\t// Get the group index from the order.\r\n\t\tvar iGroupIndex = g_oTextCompare.getTextSelectionGroupIndexFromOrder(iGroupOrder, bCompareCanvas);\r\n\r\n\t\t// Delete the text data.\r\n\t\tg_oTextCompare.deleteTextData(iGroupIndex, iSelection, bCompareCanvas, false);\r\n\t};\r\n\r\n\t/**\r\n\t * Deletes the text data.\r\n\t * @param {int} iSelectionGroup - The selection group.\r\n\t * @param {int} iSelection - The selection.\r\n\t * @param {boolean} bCompareCanvas - The compare canvas.\r\n\t */\r\n\tTextCompare.prototype.deleteTextData = function (iSelectionGroup, iSelection, bCompareCanvas, bEnableAutoSelect) {\r\n\r\n\t\t// Get the text selection group we are going to remove from.\r\n\t\tvar oTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// If we have auto select enabled.\r\n\t\tvar bAutoSelect = bEnableAutoSelect && g_oTextCompare_AutoSelection.isAutoSelectionEnabled();\r\n\r\n\t\t// Remove the text from the selection group.\r\n\t\toTextSelectionGroup[iSelectionGroup].g_oTextSelections.splice(iSelection, 1);\r\n\r\n\t\t// If this is the last text selection in the group, remove the selection.\r\n\t\tif (oTextSelectionGroup[iSelectionGroup].g_oTextSelections.length == 0) {\r\n\t\t\tg_oTextCompare_AutoSelection.deleteLinkedSelectionTextData(oTextSelectionGroup[iSelectionGroup], bCompareCanvas, true);\r\n\t\t\tg_oTextCompare.deleteTextGroup(iSelectionGroup, bCompareCanvas);\t\t\t\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// If we have auto select enabled, start the auto selection if we did not delete the full group.\r\n\t\tif (bAutoSelect && !oTextSelectionGroup[iSelectionGroup].isAutoSelected) {\r\n\t\t\tvar oCompareCanvas = bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\t\tvar oArtworkCanvas = !bCompareCanvas ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\t\tvar szJoinedSelectionText = g_oTextCompare.getJoinedSelectionsText(oTextSelectionGroup[iSelectionGroup].g_oTextSelections);\r\n\r\n\t\t\tg_oTextCompare_AutoSelection.startAutoSelection(szJoinedSelectionText, bCompareCanvas, oCompareCanvas, oArtworkCanvas, oTextSelectionGroup[iSelectionGroup]);\r\n\t\t}\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Deletes a text group.\r\n\t * @param {int} iSelectionGroup - The selection.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.deleteTextGroup = function (iSelectionGroup, bCompareCanvas) {\r\n\r\n\t\t// Get the text selection group we are going to delete from.\r\n\t\tvar oTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// Remove the group.\r\n\t\toTextSelectionGroup.splice(iSelectionGroup, 1);\r\n\r\n\t\t// Drop any unused text groups.\r\n\t\tg_oTextCompare.dropUnusedTextGroups();\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Drops the unused text groups.\r\n\t */\r\n\tTextCompare.prototype.dropUnusedTextGroups = function () {\r\n\r\n\t\t// Get the highest text selection group.\r\n\t\tvar iHighestTextSelectionGroup = g_oTextCompare.getHighestTextSelectionGroup(true, true);\r\n\r\n\t\t// Loop through each of the sections up to the highest.\r\n\t\tfor (var i = 1; i <= iHighestTextSelectionGroup; i++) {\r\n\r\n\t\t\t// Get the section for the approval and compare.\r\n\t\t\tvar oApprovalSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(i, false);\r\n\t\t\tvar oCompareSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(i, true);\r\n\r\n\t\t\t// If the group does not exist on either side.\r\n\t\t\tif (oApprovalSectionGroup == null && oCompareSectionGroup == null) {\r\n\r\n\t\t\t\t// Drop this from both the approval and compare.\r\n\t\t\t\tg_oTextCompare.dropUnusedTextGroup(i, false);\r\n\t\t\t\tg_oTextCompare.dropUnusedTextGroup(i, true);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Drops the unused text group.\r\n\t * @param {int} iGroup - The group.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.dropUnusedTextGroup = function (iGroup, bCompareCanvas) {\r\n\r\n\t\t// Get the selection group we are going to drop from.\r\n\t\tvar oTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// Loop through each of the groups and drop these down if above the dropped group.\r\n\t\tfor (var i = 0; i < oTextSelectionGroup.length; i++) {\r\n\t\t\tif (oTextSelectionGroup[i].g_iGroupOrder > iGroup) {\r\n\t\t\t\toTextSelectionGroup[i].g_iGroupOrder--;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Clears the text data.\r\n\t * @param {boolean} bApprovalCanvas - If we are clearing the approval canvas.\r\n\t * @param {boolean} bCompareCanvas - If we are clearing the compare canvas.\r\n\t * @param {boolean} bConfirmed - If we have confirmed the clear.\r\n\t */\r\n\tTextCompare.prototype.clearTextData = function (bApprovalCanvas, bCompareCanvas, bConfirmed) {\r\n\r\n\t\t// If we have not yet confirmed, display the confirm dialog.\r\n\t\tif (!bConfirmed) {\r\n\r\n\t\t\t// Using in scope variables so these are not updated by references.\r\n\t\t\tvar oCallback = (function (bApprovalCanvas, bCompareCanvas) {\r\n\t\t\t\treturn function () {\r\n\t\t\t\t\tg_oTextCompare.clearTextData(bApprovalCanvas, bCompareCanvas, true);\r\n\t\t\t\t};\r\n\t\t\t})(bApprovalCanvas, bCompareCanvas);\r\n\r\n\t\t\t// Determine the confirmation text to be shown.\r\n\t\t\tvar szConfirmationText = g_oTextCompare.c_szClearText_All;\r\n\t\t\tszConfirmationText = bApprovalCanvas && !bCompareCanvas ? g_oTextCompare.c_szClearText_Approval : szConfirmationText;\r\n\t\t\tszConfirmationText = !bApprovalCanvas && bCompareCanvas ? g_oTextCompare.c_szClearText_Compare : szConfirmationText;\r\n\r\n\t\t\t// Display the confirm bubble.\r\n\t\t\tg_oGreenlightMessages.displayConfirmBubble(szConfirmationText, oCallback, null);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Keep track of if the linked selection has been deleted.\r\n\t\tvar bLinkedSelectionDeleted = false;\r\n\r\n\t\t// Get the text selection groups\r\n\t\tvar oApprovalTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(false);\r\n\t\tvar oCompareTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(true);\t\r\n\r\n\t\t// If we are clearing for the approval canvas.\r\n\t\tif (bApprovalCanvas) {\r\n\r\n\t\t\t// Loop through each of the approval text selection groups.\r\n\t\t\tfor (var i = 0; i < oApprovalTextSelectionGroup.length; i++) {\r\n\r\n\t\t\t\t// Delete the linked selection text data if the selection group is not auto-selected and has a valid autoSelectLinkId.\r\n\t\t\t\tvar bDeleteSuccess = g_oTextCompare_AutoSelection.deleteLinkedSelectionTextData(oApprovalTextSelectionGroup[i], false, false);\t\t\r\n\t\t\t\tif (!bLinkedSelectionDeleted) {\r\n\t\t\t\t\tbLinkedSelectionDeleted = bDeleteSuccess;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If we are clearing for the compare canvas.\r\n\t\tif (bCompareCanvas) {\r\n\r\n\t\t\t// Loop through each of the compare text selection groups.\r\n\t\t\tfor (var i = 0; i < oCompareTextSelectionGroup.length; i++) {\r\n\r\n\t\t\t\t// Delete the linked selection text data if the selection group is not auto-selected and has a valid autoSelectLinkId.\r\n\t\t\t\tvar bDeleteSuccess = g_oTextCompare_AutoSelection.deleteLinkedSelectionTextData(oCompareTextSelectionGroup[i], true, false);\r\n\t\t\t\tif (!bLinkedSelectionDeleted) {\r\n\t\t\t\t\tbLinkedSelectionDeleted = bDeleteSuccess;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Clear the text data from the canvas.\r\n\t\tif (bApprovalCanvas) {\r\n\t\t\toApprovalTextSelectionGroup.splice(0, oApprovalTextSelectionGroup.length);\r\n\t\t}\r\n\r\n\t\t// Clear the text data from the canvas.\r\n\t\tif (bCompareCanvas) {\r\n\t\t\toCompareTextSelectionGroup.splice(0, oCompareTextSelectionGroup.length);\r\n\t\t}\r\n\r\n\t\t// Display a message to the user.\r\n\t\tif (bLinkedSelectionDeleted) {\r\n\t\t\tg_oGreenlightMessages.displaySuccessBubble(g_oTextCompare_AutoSelection.c_szAutoSelectionDeleted);\r\n\t\t}\r\n\r\n\t\t// If we are clearing the approval canvas, reorder the groups for the compare canvas.\r\n\t\tif (bApprovalCanvas && !bCompareCanvas) {\r\n\t\t\tfor (var i = 0; i < oCompareTextSelectionGroup.length; i++) {\r\n\t\t\t\toCompareTextSelectionGroup[i].g_iGroupOrder = i + 1;\r\n\t\t\t}\r\n\t\t}\r\n\t\t// If we are clearing the compare canvas, reorder the groups for the approval canvas.\r\n\t\telse if (!bApprovalCanvas && bCompareCanvas) {\r\n\t\t\tfor (var i = 0; i < oApprovalTextSelectionGroup.length; i++) {\r\n\t\t\t\toApprovalTextSelectionGroup[i].g_iGroupOrder = i + 1;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare annotations.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareAnnotations = function () {\r\n\r\n\t\t// Ensure the canvas data has been loaded for both canvas before rendering.\r\n\t\tif (!g_oTextCompare.g_bArtworkTextDataLoaded || !g_oTextCompare.g_bCompareTextDataLoaded) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// If we have not calculated the differences.\r\n\t\tif (!g_oTextCompare.g_bDifferencesCalculated) {\r\n\r\n\t\t\t// If we are actively text highlighting on the approval canvas, call the mouse move event to re-draw the highlighted area.\r\n\t\t\tif (g_oTextTools.g_bHighlightInProgress && !g_oTextTools.g_bHighlightOnCompareCanvas) {\r\n\t\t\t\t$('#AnnotationViewer').trigger('pointermove');\r\n\t\t\t}\r\n\t\t\t// Render the text compare annotations for the approval canvas.\r\n\t\t\telse {\r\n\t\t\t\tg_oTextCompare.renderTextCompareCanvasAnnotations(g_oTextCompare.getTextSelectionGroup(false), g_oViewer.g_oArtworkViewer, g_oViewer.g_oAnnotationViewer);\r\n\t\t\t}\r\n\r\n\t\t\t// If we are actively text highlighting on the compare canvas, call the mouse move event to re-draw the highlighted area.\r\n\t\t\tif (g_oTextTools.g_bHighlightInProgress && g_oTextTools.g_bHighlightOnCompareCanvas) {\r\n\t\t\t\t$('#CompareViewer').trigger('pointermove');\r\n\t\t\t}\r\n\t\t\t// Render the text compare annotations for the compare canvas.\r\n\t\t\telse {\r\n\t\t\t\tg_oTextCompare.renderTextCompareCanvasAnnotations(g_oTextCompare.getTextSelectionGroup(true), g_oCompare.g_oCompareViewer, g_oCompare.g_oCompareAnnotationViewer);\r\n\t\t\t}\r\n\t\t}\r\n\t\t// If we have calculated the differences.\r\n\t\telse {\r\n\r\n\t\t\t// Render the text compare differences for both canvas.\r\n\t\t\tg_oTextCompare.renderTextCompareCanvasDifferences(g_oTextCompare.getTextSelectionGroup(false), g_oViewer.g_oArtworkViewer, g_oViewer.g_oAnnotationViewer);\r\n\t\t\tg_oTextCompare.renderTextCompareCanvasDifferences(g_oTextCompare.getTextSelectionGroup(true), g_oCompare.g_oCompareViewer, g_oCompare.g_oCompareAnnotationViewer);\r\n\r\n\t\t\t// Update the differences bar.\r\n\t\t\tg_oTextCompare.updateDifferencesBar();\r\n\r\n\t\t\t// Update the differences summary.\r\n\t\t\tg_oTextCompare.updateDifferencesSummary();\r\n\t\t}\r\n\r\n\t\t// If we have the text compare div shown.\r\n\t\tif (g_oTextCompare.g_bTextCompareDivShown) {\r\n\r\n\t\t\t// Render the text compare sections.\r\n\t\t\tg_oTextCompare.renderTextCompareSections();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare differences.\r\n\t * @param {object} oTextSelectionGroup - The text selection group.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareCanvasDifferences = function (oTextSelectionGroup, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Remove any existing highlights.\r\n\t\tg_oTextTools.removeHighlights(oAnnotationCanvas);\r\n\r\n\t\t// Check if we have selections.\r\n\t\tif (oTextSelectionGroup.length == 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelectionGroup.length; i++) {\r\n\r\n\t\t\t// Check we have differences.\r\n\t\t\tif (oTextSelectionGroup[i].g_oTextDifferences == null) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the differences.\r\n\t\t\tfor (var j = 0; j < oTextSelectionGroup[i].g_oTextDifferences.length; j++) {\r\n\r\n\t\t\t\t// Render the text compare difference.\r\n\t\t\t\tg_oTextCompare.renderTextCompareCanvasDifference(oTextSelectionGroup[i].g_oTextDifferences[j], oTextSelectionGroup[i].g_iGroupOrder, oTextSelectionGroup[i].g_oTextSelections, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare canvas differences.\r\n\t * @param {object} oDifference - The difference.\r\n\t * @param {int} iGroup - The group.\r\n\t * @param {object} oTextSelections - The text selections.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareCanvasDifference = function (oDifference, iGroup, oTextSelections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// If we are stepping through differences and this is not the matching difference, skip this render.\r\n\t\tif (g_oTextCompare.g_iStepThroughDifference != null && oDifference.g_iDifferenceNumber != g_oTextCompare.g_iStepThroughDifference) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// If we have calculated the differences to the word level.\r\n\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\r\n\t\t\t// Render the difference words.\r\n\t\t\tg_oTextCompare.renderTextCompareCanvasDifference_Words(oDifference, iGroup, oTextSelections, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t}\r\n\t\t// If we have calculated the differences to a character level.\r\n\t\telse {\r\n\r\n\t\t\t// Render the difference characters.\r\n\t\t\tg_oTextCompare.renderTextCompareCanvasDifference_Characters(oDifference, iGroup, oTextSelections, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare word canvas differences.\r\n\t * @param {object} oDifference - The difference.\r\n\t * @param {int} iGroup - The group.\r\n\t * @param {object} oTextSelections - The text selections.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareCanvasDifference_Words = function (oDifference, iGroup, oTextSelections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Keep track of a list of words that are part of this difference.\r\n\t\tvar oDifferenceWords = g_oTextCompare.getWordsForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t// Keep track of a list of markers that are part of this difference.\r\n\t\tvar oDifferenceMarkers = g_oTextCompare.getWordMarkersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t// Ensure we have words to highlight.\r\n\t\tif (oDifferenceWords.length == 0 && oDifferenceMarkers == 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// If we have markers for this difference.\r\n\t\tif (oDifferenceMarkers.length > 0) {\r\n\r\n\t\t\t// Highlight only the marker.\r\n\t\t\tg_oTextCompare.highlightTextCompareMarker(oDifference, iGroup, oDifferenceMarkers, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Highlight each of the difference words.\r\n\t\tg_oTextCompare.highlightTextCompareWords(oDifferenceWords, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Get the bounds of the word list for this difference.\r\n\t\tvar oWordBounds = g_oTextTools.getWordListBounds(oDifferenceWords, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Get the annotation context.\r\n\t\tvar oAnnotationContext = oAnnotationCanvas.g_oContext;\r\n\r\n\t\t// Get the width and shift of the artwork canvas.\r\n\t\tvar iImageObjW = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\tvar iImageObjH = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\tvar iCenterShift_x = oArtworkCanvas.g_iCenterShift_x;\r\n\t\tvar iCenterShift_y = oArtworkCanvas.g_iCenterShift_y;\r\n\r\n\t\t// Calculate the compare offset on the artwork canvas.\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\t\tvar compareOffset_x = co.x;\r\n\t\tvar compareOffset_y = co.y;\r\n\r\n\t\t// Get the compare rotation of the canvas.\r\n\t\tvar iCompareRotation = g_oCompare.getCompareRotation(oArtworkCanvas);\r\n\r\n\t\t// If we have a compare rotation of 90 or 270, swap the image object width and height.\r\n\t\tif (iCompareRotation == 90 || iCompareRotation == 270) {\r\n\t\t\tiImageObjW = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\t\tiImageObjH = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\t}\r\n\r\n\t\t// Determine the annotation colour.\r\n\t\tvar annotationColour = g_oTextCompare.getAnnotationColourFromDifferenceStatus(oDifference.g_iDifferenceStatus);\r\n\r\n\t\t// Set the highlight colour.\r\n\t\tg_oTextTools.setHighlightColour(annotationColour);\r\n\r\n\t\t// Extract the annotation bound points.\r\n\t\tvar newXBegin = ((oWordBounds.x1 * iImageObjW)) + iCenterShift_x + compareOffset_x;\r\n\t\tvar newYBegin = ((oWordBounds.y1 * iImageObjH)) + iCenterShift_y + compareOffset_y;\r\n\t\tvar newXEnd = ((oWordBounds.x2 * iImageObjW)) + iCenterShift_x + compareOffset_x;\r\n\t\tvar newYEnd = ((oWordBounds.y2 * iImageObjH)) + iCenterShift_y + compareOffset_y;\r\n\r\n\t\t// Determine the begin points and the distance.\r\n\t\tvar beginPoint_x = Math.min(newXBegin, newXEnd);\r\n\t\tvar beginPoint_y = Math.min(newYBegin, newYEnd);\r\n\t\tvar dist_x = Math.abs(newXBegin - newXEnd);\r\n\t\tvar dist_y = Math.abs(newYBegin - newYEnd);\r\n\r\n\t\t// Create the path.\r\n\t\toAnnotationContext.beginPath();\r\n\t\toAnnotationContext.rect(beginPoint_x, beginPoint_y, dist_x, dist_y);\r\n\t\toAnnotationContext.lineWidth = g_oAnnotations.g_iAnnotationWidth;\r\n\t\toAnnotationContext.strokeStyle = annotationColour;\r\n\t\toAnnotationContext.setLineDash([]);\r\n\r\n\t\t// Stroke.\r\n\t\toAnnotationContext.stroke();\r\n\r\n\t\t// Render the annotation number.\r\n\t\tvar szDifferenceText = g_oTextCompare.c_szTextCompareGroupText + \" \" + (iGroup).toString() + \" (\" + g_oTextCompare.c_szTextCompareDifferenceText + \" \" + (oDifference.g_iDifferenceOrder).toString() + \")\";\r\n\t\toAnnotationContext.font = g_oAnnotations.g_iAnnotationNumberFontSize + \"px Varela Round\";\r\n\t\toAnnotationContext.textBaseline = \"bottom\";\r\n\t\toAnnotationContext.textalign = \"center\";\r\n\t\tvar areaTextSize = oAnnotationContext.measureText(szDifferenceText);\r\n\r\n\t\t// Set the drawing style.\r\n\t\toAnnotationContext.fillStyle = annotationColour;\r\n\t\toAnnotationContext.setLineDash([]);\r\n\r\n\t\t// Determine the rotation to draw the difference text.\r\n\t\tswitch (oAnnotationCanvas.g_iRotDegrees) {\r\n\r\n\t\t\tcase 180:\r\n\t\t\t\t// Add the number background.\r\n\t\t\t\toAnnotationContext.beginPath();\r\n\t\t\t\toAnnotationContext.rect(oWordBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oWordBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY, areaTextSize.width + g_oAnnotations.g_oAnnotationNumberBox.iWidth, g_oAnnotations.g_oAnnotationNumberBox.iHeight);\r\n\t\t\t\toAnnotationContext.fill();\r\n\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.getHandleFillStyle(annotationColour);\r\n\r\n\t\t\t\t// Save the context.\r\n\t\t\t\toAnnotationContext.save();\r\n\r\n\t\t\t\t// Add the text.\r\n\t\t\t\toAnnotationContext.translate(oWordBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oWordBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY);\r\n\t\t\t\toAnnotationContext.scale(-1, -1);\r\n\t\t\t\toAnnotationContext.fillText(szDifferenceText, -areaTextSize.width, 0);\r\n\r\n\t\t\t\t// Restore the context.\r\n\t\t\t\toAnnotationContext.restore();\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\t// Add the number background.\r\n\t\t\t\toAnnotationContext.beginPath();\r\n\t\t\t\toAnnotationContext.rect(oWordBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oWordBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY, areaTextSize.width + g_oAnnotations.g_oAnnotationNumberBox.iWidth, g_oAnnotations.g_oAnnotationNumberBox.iHeight);\r\n\t\t\t\toAnnotationContext.fill();\r\n\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.getHandleFillStyle(annotationColour);\r\n\r\n\t\t\t\t// Add the text.\r\n\t\t\t\toAnnotationContext.fillText(szDifferenceText, oWordBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberText.iBeginX, oWordBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberText.iBeginY);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare character canvas differences.\r\n\t * @param {object} oDifference - The difference.\r\n\t * @param {int} iGroup - The group.\r\n\t * @param {object} oTextSelections - The text selections.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareCanvasDifference_Characters = function (oDifference, iGroup, oTextSelections, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Keep track of a list of characters that are part of this difference.\r\n\t\tvar oDifferenceCharacters = g_oTextCompare.getCharactersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t// Keep track of a list of markers that are part of this difference.\r\n\t\tvar oDifferenceMarkers = g_oTextCompare.getCharacterMarkersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t// Ensure we have characters to highlight.\r\n\t\tif (oDifferenceCharacters.length == 0 && oDifferenceMarkers.length == 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// If these characters are markers.\r\n\t\tif (oDifferenceMarkers.length > 0) {\r\n\r\n\t\t\t// Highlight only the marker.\r\n\t\t\tg_oTextCompare.highlightTextCompareMarker(oDifference, iGroup, oDifferenceMarkers, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Highlight each of the difference characters.\r\n\t\tg_oTextCompare.highlightTextCompareCharacters(oDifferenceCharacters, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Get the bounds of the character list for this difference.\r\n\t\tvar oCharacterBounds = g_oTextTools.getCharacterListBounds(oDifferenceCharacters, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Get the annotation context.\r\n\t\tvar oAnnotationContext = oAnnotationCanvas.g_oContext;\r\n\r\n\t\t// Get the width and shift of the artwork canvas.\r\n\t\tvar iImageObjW = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\tvar iImageObjH = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\tvar iCenterShift_x = oArtworkCanvas.g_iCenterShift_x;\r\n\t\tvar iCenterShift_y = oArtworkCanvas.g_iCenterShift_y;\r\n\r\n\t\t// Calculate the compare offset on the artwork canvas.\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\t\tvar compareOffset_x = co.x;\r\n\t\tvar compareOffset_y = co.y;\r\n\r\n\t\t// Get the compare rotation of the canvas.\r\n\t\tvar iCompareRotation = g_oCompare.getCompareRotation(oArtworkCanvas);\r\n\r\n\t\t// If we have a compare rotation of 90 or 270, swap the image object width and height.\r\n\t\tif (iCompareRotation == 90 || iCompareRotation == 270) {\r\n\t\t\tiImageObjW = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\t\tiImageObjH = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\t}\r\n\r\n\t\t// Determine the annotation colour.\r\n\t\tvar annotationColour = g_oTextCompare.getAnnotationColourFromDifferenceStatus(oDifference.g_iDifferenceStatus);\r\n\r\n\t\t// Set the highlight colour.\r\n\t\tg_oTextTools.setHighlightColour(annotationColour);\r\n\r\n\t\t// Extract the annotation bound points.\r\n\t\tvar newXBegin = ((oCharacterBounds.x1 * iImageObjW)) + iCenterShift_x + compareOffset_x;\r\n\t\tvar newYBegin = ((oCharacterBounds.y1 * iImageObjH)) + iCenterShift_y + compareOffset_y;\r\n\t\tvar newXEnd = ((oCharacterBounds.x2 * iImageObjW)) + iCenterShift_x + compareOffset_x;\r\n\t\tvar newYEnd = ((oCharacterBounds.y2 * iImageObjH)) + iCenterShift_y + compareOffset_y;\r\n\r\n\t\t// Determine the begin points and the distance.\r\n\t\tvar beginPoint_x = Math.min(newXBegin, newXEnd);\r\n\t\tvar beginPoint_y = Math.min(newYBegin, newYEnd);\r\n\t\tvar dist_x = Math.abs(newXBegin - newXEnd);\r\n\t\tvar dist_y = Math.abs(newYBegin - newYEnd);\r\n\r\n\t\t// Create the path.\r\n\t\toAnnotationContext.beginPath();\r\n\t\toAnnotationContext.rect(beginPoint_x, beginPoint_y, dist_x, dist_y);\r\n\t\toAnnotationContext.lineWidth = g_oAnnotations.g_iAnnotationWidth;\r\n\t\toAnnotationContext.strokeStyle = annotationColour;\r\n\t\toAnnotationContext.setLineDash([]);\r\n\r\n\t\t// Stroke.\r\n\t\toAnnotationContext.stroke();\r\n\r\n\t\t// Render the annotation number.\r\n\t\tvar szDifferenceText = g_oTextCompare.c_szTextCompareGroupText + \" \" + (iGroup).toString() + \" (\" + g_oTextCompare.c_szTextCompareDifferenceText + \" \" + (oDifference.g_iDifferenceOrder).toString() + \")\";\r\n\t\toAnnotationContext.font = g_oAnnotations.g_iAnnotationNumberFontSize + \"px Varela Round\";\r\n\t\toAnnotationContext.textBaseline = \"bottom\";\r\n\t\toAnnotationContext.textalign = \"center\";\r\n\t\tvar areaTextSize = oAnnotationContext.measureText(szDifferenceText);\r\n\r\n\t\t// Start the drawing.\r\n\t\toAnnotationContext.fillStyle = annotationColour;\r\n\t\toAnnotationContext.setLineDash([]);\r\n\r\n\t\t// Determine the rotation to draw the difference text.\r\n\t\tswitch (oAnnotationCanvas.g_iRotDegrees) {\r\n\r\n\t\t\tcase 180:\r\n\t\t\t\t// Add the number background.\r\n\t\t\t\toAnnotationContext.beginPath();\r\n\t\t\t\toAnnotationContext.rect(oCharacterBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oCharacterBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY, areaTextSize.width + g_oAnnotations.g_oAnnotationNumberBox.iWidth, g_oAnnotations.g_oAnnotationNumberBox.iHeight);\r\n\t\t\t\toAnnotationContext.fill();\r\n\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.getHandleFillStyle(annotationColour);\r\n\r\n\t\t\t\t// Save the context.\r\n\t\t\t\toAnnotationContext.save();\r\n\r\n\t\t\t\t// Add the text.\r\n\t\t\t\toAnnotationContext.translate(oCharacterBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oCharacterBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY);\r\n\t\t\t\toAnnotationContext.scale(-1, -1);\r\n\t\t\t\toAnnotationContext.fillText(szDifferenceText, -areaTextSize.width, 0);\r\n\r\n\t\t\t\t// Restore the context.\r\n\t\t\t\toAnnotationContext.restore();\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\t// Add the number background.\r\n\t\t\t\toAnnotationContext.beginPath();\r\n\t\t\t\toAnnotationContext.rect(oCharacterBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oCharacterBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY, areaTextSize.width + g_oAnnotations.g_oAnnotationNumberBox.iWidth, g_oAnnotations.g_oAnnotationNumberBox.iHeight);\r\n\t\t\t\toAnnotationContext.fill();\r\n\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.getHandleFillStyle(annotationColour);\r\n\r\n\t\t\t\t// Add the number text.\r\n\t\t\t\toAnnotationContext.fillText(szDifferenceText, oCharacterBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberText.iBeginX, oCharacterBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberText.iBeginY);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights a text compare marker.\r\n\t * @param {object} oDifference - The difference.\r\n\t * @param {int} iGroup - The group.\r\n\t * @param {object} oMarkerWords - The marker words.\r\n\t * @param {object} oArtworkCanvas - The artwork canvcas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.highlightTextCompareMarker = function (oDifference, iGroup, oMarkerWords, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the bounds of the word list for this difference.\r\n\t\tvar oWordBounds = g_oTextTools.getWordListBounds(oMarkerWords, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Get the annotation context.\r\n\t\tvar oAnnotationContext = oAnnotationCanvas.g_oContext;\r\n\r\n\t\t// Get the width and shift of the artwork canvas.\r\n\t\tvar iImageObjW = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\tvar iImageObjH = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\tvar iCenterShift_x = oArtworkCanvas.g_iCenterShift_x;\r\n\t\tvar iCenterShift_y = oArtworkCanvas.g_iCenterShift_y;\r\n\r\n\t\t// Calculate the compare offset on the artwork canvas.\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\t\tvar compareOffset_x = co.x;\r\n\t\tvar compareOffset_y = co.y;\r\n\r\n\t\t// Get the compare rotation of the canvas.\r\n\t\tvar iCompareRotation = g_oCompare.getCompareRotation(oArtworkCanvas);\r\n\r\n\t\t// If we have a compare rotation of 90 or 270, swap the image object width and height.\r\n\t\tif (iCompareRotation == 90 || iCompareRotation == 270) {\r\n\t\t\tiImageObjW = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\t\tiImageObjH = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\t}\r\n\r\n\t\t// Set the annotation colour.\r\n\t\tvar annotationColour = g_oTextCompare.getAnnotationColourFromDifferenceStatus(oDifference.g_iDifferenceStatus);\r\n\r\n\t\t// Set the fill and stroke style.\r\n\t\toAnnotationContext.strokeStyle = annotationColour;\r\n\t\toAnnotationContext.fillStyle = annotationColour;\r\n\r\n\t\t// Extract the annotation bound points.\r\n\t\tvar newXBegin = ((oWordBounds.x1 * iImageObjW)) + iCenterShift_x + compareOffset_x;\r\n\t\tvar newYBegin = ((oWordBounds.y1 * iImageObjH)) + iCenterShift_y + compareOffset_y;\r\n\t\tvar newXEnd = ((oWordBounds.x2 * iImageObjW)) + iCenterShift_x + compareOffset_x;\r\n\t\tvar newYEnd = ((oWordBounds.y2 * iImageObjH)) + iCenterShift_y + compareOffset_y;\r\n\r\n\t\t// Calculate the points to be used.\r\n\t\tvar beginPoint_x = 0;\r\n\t\tvar beginPoint_y = 0;\r\n\r\n\t\t// If this is a marker before, use the minumum.\r\n\t\tif (oMarkerWords[0].marker == g_oTextCompare.eMarkerTypes.MarkerBefore) {\r\n\t\t\tbeginPoint_x = Math.min(newXBegin, newXEnd) - (g_oTextCompare.g_iMarkerSize / 2);\r\n\t\t\tbeginPoint_y = Math.min(newYBegin, newYEnd) - (g_oTextCompare.g_iMarkerSize / 2);\r\n\t\t}\r\n\t\t// If this is a marker after, use the maximum.\r\n\t\telse {\r\n\t\t\tbeginPoint_x = Math.max(newXBegin, newXEnd) - (g_oTextCompare.g_iMarkerSize / 2);\r\n\t\t\tbeginPoint_y = Math.min(newYBegin, newYEnd) - (g_oTextCompare.g_iMarkerSize / 2);\r\n\t\t}\r\n\r\n\t\t// Create the marker triangle.\r\n\t\toAnnotationContext.beginPath();\r\n\t\toAnnotationContext.moveTo(beginPoint_x, beginPoint_y);\r\n\t\toAnnotationContext.lineTo(beginPoint_x + g_oTextCompare.g_iMarkerSize, beginPoint_y);\r\n\t\toAnnotationContext.lineTo(beginPoint_x + (g_oTextCompare.g_iMarkerSize / 2), beginPoint_y + (g_oTextCompare.g_iMarkerSize / 2));\r\n\t\toAnnotationContext.lineTo(beginPoint_x, beginPoint_y);\r\n\r\n\t\t// Fill the triangle.\r\n\t\toAnnotationContext.fill();\r\n\r\n\t\t// Render the annotation number.\r\n\t\tvar szMarkerText = g_oTextCompare.c_szTextCompareGroupText + \" \" + (iGroup).toString() + \" (\" + g_oTextCompare.c_szTextCompareDifferenceText + \" \" + (oDifference.g_iDifferenceOrder).toString() + \")\";\r\n\t\toAnnotationContext.font = g_oAnnotations.g_iAnnotationNumberFontSize + \"px Varela Round\";\r\n\t\toAnnotationContext.textBaseline = \"bottom\";\r\n\t\toAnnotationContext.textalign = \"center\";\r\n\t\tvar areaTextSize = oAnnotationContext.measureText(szMarkerText);\r\n\r\n\t\t// Start the drawing.\r\n\t\toAnnotationContext.fillStyle = annotationColour;\r\n\t\toAnnotationContext.setLineDash([]);\r\n\r\n\t\t// Determine the rotation to draw the difference text.\r\n\t\tswitch (oAnnotationCanvas.g_iRotDegrees) {\r\n\r\n\t\t\tcase 180:\r\n\t\t\t\t// Add the number background.\r\n\t\t\t\toAnnotationContext.beginPath();\r\n\t\t\t\toAnnotationContext.rect(beginPoint_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oWordBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY, areaTextSize.width + g_oAnnotations.g_oAnnotationNumberBox.iWidth, g_oAnnotations.g_oAnnotationNumberBox.iHeight);\r\n\t\t\t\toAnnotationContext.fill();\r\n\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.getHandleFillStyle(annotationColour);\r\n\r\n\t\t\t\t// Save the context.\r\n\t\t\t\toAnnotationContext.save();\r\n\r\n\t\t\t\t// Add the number text.\r\n\t\t\t\toAnnotationContext.translate(beginPoint_x - g_oAnnotations.g_oAnnotationNumberText.iBeginX, oWordBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY);\r\n\t\t\t\toAnnotationContext.scale(-1, -1);\r\n\t\t\t\toAnnotationContext.fillText(szMarkerText, -areaTextSize.width, 0);\r\n\r\n\t\t\t\t// Restore the context.\r\n\t\t\t\toAnnotationContext.restore();\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\t// Add the number background.\r\n\t\t\t\toAnnotationContext.beginPath();\r\n\t\t\t\toAnnotationContext.rect(beginPoint_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oWordBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY, areaTextSize.width + g_oAnnotations.g_oAnnotationNumberBox.iWidth, g_oAnnotations.g_oAnnotationNumberBox.iHeight);\r\n\t\t\t\toAnnotationContext.fill();\r\n\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.getHandleFillStyle(annotationColour);\r\n\r\n\t\t\t\t// Add the number text.\r\n\t\t\t\toAnnotationContext.fillText(szMarkerText, beginPoint_x - g_oAnnotations.g_oAnnotationNumberText.iBeginX, oWordBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberText.iBeginY);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the words for a text difference.\r\n\t * @param {object} oTextSelections - The text selections.\r\n\t * @param {int} iDifferece - The difference.\r\n\t * @param {int} iPage - The page.\r\n\t */\r\n\tTextCompare.prototype.getWordsForTextDifference = function (oTextSelections, iDifferece, iPage) {\r\n\r\n\t\t// Keep track of a list of words that are part of this difference.\r\n\t\tvar oDifferenceWords = [];\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelections.length; i++) {\r\n\r\n\t\t\t// Ensure this selection is on the current page.\r\n\t\t\tif (iPage != null && oTextSelections[i].g_iPage != iPage) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the words in the text selection.\r\n\t\t\tfor (var j = 0; j < oTextSelections[i].g_oSelectionWords.length; j++) {\r\n\r\n\t\t\t\t// Add this word to the list if it is part of the difference.\r\n\t\t\t\tif (oTextSelections[i].g_oSelectionWords[j].difference == iDifferece) {\r\n\t\t\t\t\toDifferenceWords.push(oTextSelections[i].g_oSelectionWords[j]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the difference words.\r\n\t\treturn oDifferenceWords;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the word markers for a text difference.\r\n\t * @param {object} oTextSelections - The text selections.\r\n\t * @param {int} iDifferece - The difference.\r\n\t * @param {int} iPage - The page.\r\n\t */\r\n\tTextCompare.prototype.getWordMarkersForTextDifference = function (oTextSelections, iDifferece, iPage) {\r\n\r\n\t\t// Keep track of a list of markers that are part of this difference.\r\n\t\tvar oDifferenceMarkers = [];\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelections.length; i++) {\r\n\r\n\t\t\t// Ensure this selection is on the current page.\r\n\t\t\tif (oTextSelections[i].g_iPage != iPage) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the words in the text selection.\r\n\t\t\tfor (var j = 0; j < oTextSelections[i].g_oSelectionWords.length; j++) {\r\n\r\n\t\t\t\t// Add this marker word to the list if it is part of the difference.\r\n\t\t\t\tif (oTextSelections[i].g_oSelectionWords[j].markerDifference == iDifferece) {\r\n\t\t\t\t\toDifferenceMarkers.push(oTextSelections[i].g_oSelectionWords[j]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the difference markers.\r\n\t\treturn oDifferenceMarkers;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the characters for a text difference.\r\n\t * @param {object} oTextSelections - The text selections.\r\n\t * @param {int} iDifferece - The difference.\r\n\t * @param {int} iPage - The page.\r\n\t */\r\n\tTextCompare.prototype.getCharactersForTextDifference = function (oTextSelections, iDifferece, iPage) {\r\n\r\n\t\t// Keep track of a list of characters that are part of this difference.\r\n\t\tvar oDifferenceCharacters = [];\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelections.length; i++) {\r\n\r\n\t\t\t// Ensure this selection is on the current page.\r\n\t\t\tif (oTextSelections[i].g_iPage != iPage) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the characters in the text selection.\r\n\t\t\tfor (var j = 0; j < oTextSelections[i].g_oSelectionCharacters.length; j++) {\r\n\r\n\t\t\t\t// Add this character to the list if it is part of the difference.\r\n\t\t\t\tif (oTextSelections[i].g_oSelectionCharacters[j].difference == iDifferece) {\r\n\t\t\t\t\toDifferenceCharacters.push(oTextSelections[i].g_oSelectionCharacters[j]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the difference characters.\r\n\t\treturn oDifferenceCharacters;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the character markers for a text difference.\r\n\t * @param {object} oTextSelections - The text selections.\r\n\t * @param {int} iDifferece - The difference.\r\n\t * @param {int} iPage - The page.\r\n\t */\r\n\tTextCompare.prototype.getCharacterMarkersForTextDifference = function (oTextSelections, iDifferece, iPage) {\r\n\r\n\t\t// Keep track of a list of marker characters that are part of this difference.\r\n\t\tvar oMarkerCharacters = [];\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelections.length; i++) {\r\n\r\n\t\t\t// Ensure this selection is on the current page.\r\n\t\t\tif (oTextSelections[i].g_iPage != iPage) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the characters in the text selection.\r\n\t\t\tfor (var j = 0; j < oTextSelections[i].g_oSelectionCharacters.length; j++) {\r\n\r\n\t\t\t\t// Add this character to the list if it is a marker of the difference.\r\n\t\t\t\tif (oTextSelections[i].g_oSelectionCharacters[j].markerDifference == iDifferece) {\r\n\t\t\t\t\toMarkerCharacters.push(oTextSelections[i].g_oSelectionCharacters[j]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the marker characters.\r\n\t\treturn oMarkerCharacters;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets a word list from a character list.\r\n\t * @param {object} oCharacterList - The character list.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.getWorldListFromCharacterList = function (oCharacterList, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Keep track of a list of words that are part of this difference.\r\n\t\tvar oDifferenceWords = [];\r\n\r\n\t\t// Loop through each of the characters.\r\n\t\tfor (var i = 0; i < oCharacterList.length; i++) {\r\n\r\n\t\t\t// Check if we already have this word in the list.\r\n\t\t\tvar bWordInList = false;\r\n\r\n\t\t\t// Loop through each of the words, and check if this is already in the list.\r\n\t\t\tfor (var j = 0; j < oDifferenceWords.length; j++) {\r\n\t\t\t\tif (oCharacterList[i].paragraph == oDifferenceWords[j].paragraph && oCharacterList[i].line == oDifferenceWords[j].line && oCharacterList[i].word == oDifferenceWords[j].word) {\r\n\t\t\t\t\tbWordInList = true;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// If the word was not in the list.\r\n\t\t\tif (!bWordInList) {\r\n\r\n\t\t\t\t// Extract the word.\r\n\t\t\t\tvar oWord = { paragraph: oCharacterList[i].paragraph, line: oCharacterList[i].line, word: oCharacterList[i].word };\r\n\r\n\t\t\t\t// Add the word to the list.\r\n\t\t\t\toDifferenceWords.push(new g_oTextCompare.textSelectionWord(oWord, oArtworkCanvas, oAnnotationCanvas));\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the difference words.\r\n\t\treturn oDifferenceWords;\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare canvas annotations.\r\n\t * @param {object} oTextSelectionGroup - The text selection group.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareCanvasAnnotations = function (oTextSelectionGroup, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the annotation context.\r\n\t\tvar oAnnotationContext = oAnnotationCanvas.g_oContext;\r\n\r\n\t\t// Remove any existing highlights.\r\n\t\tg_oTextTools.removeHighlights(oAnnotationCanvas);\r\n\r\n\t\t// Check if we have selections.\r\n\t\tif (oTextSelectionGroup.length == 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get the width and shift of the artwork canvas.\r\n\t\tvar iImageObjW = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\tvar iImageObjH = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\tvar iCenterShift_x = oArtworkCanvas.g_iCenterShift_x;\r\n\t\tvar iCenterShift_y = oArtworkCanvas.g_iCenterShift_y;\r\n\r\n\t\t// Calculate the compare offset on the artwork canvas.\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\t\tvar compareOffset_x = co.x;\r\n\t\tvar compareOffset_y = co.y;\r\n\r\n\t\t// Get the compare rotation of the canvas.\r\n\t\tvar iCompareRotation = g_oCompare.getCompareRotation(oArtworkCanvas);\r\n\r\n\t\t// If we have a compare rotation of 90 or 270, swap the image object width and height.\r\n\t\tif (iCompareRotation == 90 || iCompareRotation == 270) {\r\n\t\t\tiImageObjW = oArtworkCanvas.g_iScaledImageHeight;\r\n\t\t\tiImageObjH = oArtworkCanvas.g_iScaledImageWidth;\r\n\t\t}\r\n\r\n\t\t// Render each of the text selection groups.\r\n\t\tfor (var i = 0; i < oTextSelectionGroup.length; i++) {\r\n\r\n\t\t\t// Render each of the text selections.\r\n\t\t\tfor (var j = 0; j < oTextSelectionGroup[i].g_oTextSelections.length; j++) {\r\n\r\n\t\t\t\t// Extract the selection.\r\n\t\t\t\tvar oSelectionGroup = oTextSelectionGroup[i].g_oTextSelections[j];\r\n\r\n\t\t\t\t// Ensure the selection group is on the current page.\r\n\t\t\t\tif (oSelectionGroup.g_iPage != oArtworkCanvas.g_iCurrentPage) {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Set the highlight colour.\r\n\t\t\t\tg_oTextTools.setHighlightColour(g_oTextCompare.g_szHighlightColour);\r\n\r\n\t\t\t\t// Highlight the text content.\r\n\t\t\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\t\t\t\t\tg_oTextCompare.highlightTextCompareWords(oSelectionGroup.g_oSelectionWords, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t\t}\r\n\t\t\t\telse {\r\n\t\t\t\t\tg_oTextCompare.highlightTextCompareCharacters(oSelectionGroup.g_oSelectionCharacters, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Extract the bounds to be used.\r\n\t\t\t\tvar oSelectionBounds = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word ? oSelectionGroup.g_oSelectionWordsBounds : oSelectionGroup.g_oSelectionCharacterBounds;\r\n\r\n\t\t\t\t// Extract the annotation bound points.\r\n\t\t\t\tvar newXBegin = ((oSelectionBounds.x1 * iImageObjW)) + iCenterShift_x + compareOffset_x;\r\n\t\t\t\tvar newYBegin = ((oSelectionBounds.y1 * iImageObjH)) + iCenterShift_y + compareOffset_y;\r\n\t\t\t\tvar newXEnd = ((oSelectionBounds.x2 * iImageObjW)) + iCenterShift_x + compareOffset_x;\r\n\t\t\t\tvar newYEnd = ((oSelectionBounds.y2 * iImageObjH)) + iCenterShift_y + compareOffset_y;\r\n\r\n\t\t\t\t// Determine the begin points and the distance.\r\n\t\t\t\tvar beginPoint_x = Math.min(newXBegin, newXEnd);\r\n\t\t\t\tvar beginPoint_y = Math.min(newYBegin, newYEnd);\r\n\t\t\t\tvar dist_x = Math.abs(newXBegin - newXEnd);\r\n\t\t\t\tvar dist_y = Math.abs(newYBegin - newYEnd);\r\n\r\n\t\t\t\t// Create the path.\r\n\t\t\t\toAnnotationContext.beginPath();\r\n\t\t\t\toAnnotationContext.rect(beginPoint_x, beginPoint_y, dist_x, dist_y);\r\n\t\t\t\toAnnotationContext.lineWidth = g_oAnnotations.g_iAnnotationWidth;\r\n\t\t\t\toAnnotationContext.strokeStyle = g_oTextCompare.g_szHighlightColour;\r\n\t\t\t\toAnnotationContext.setLineDash([]);\r\n\r\n\t\t\t\t// Stroke.\r\n\t\t\t\toAnnotationContext.stroke();\r\n\r\n\t\t\t\t// Render the annotation number.\r\n\t\t\t\tvar annText = (oTextSelectionGroup[i].g_iGroupOrder).toString();\r\n\t\t\t\toAnnotationContext.font = g_oAnnotations.g_iAnnotationNumberFontSize + \"px Varela Round\";\r\n\t\t\t\toAnnotationContext.textBaseline = \"bottom\";\r\n\t\t\t\toAnnotationContext.textalign = \"center\";\r\n\t\t\t\tvar areaTextSize = oAnnotationContext.measureText(annText);\r\n\r\n\t\t\t\t// Start the drawing.\r\n\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.g_szHighlightColour;\r\n\t\t\t\toAnnotationContext.setLineDash([]);\r\n\t\t\t\toAnnotationContext.beginPath();\r\n\r\n\t\t\t\t// Add the number background.\r\n\t\t\t\toAnnotationContext.rect(oSelectionBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX, oSelectionBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY, areaTextSize.width + g_oAnnotations.g_oAnnotationNumberBox.iWidth, g_oAnnotations.g_oAnnotationNumberBox.iHeight);\r\n\t\t\t\toAnnotationContext.fill();\r\n\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.getHandleFillStyle(g_oTextCompare.g_szHighlightColour);\r\n\r\n\t\t\t\t// Add the number text.\r\n\t\t\t\toAnnotationContext.fillText(annText, oSelectionBounds.x1 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberText.iBeginX, oSelectionBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberText.iBeginY);\r\n\r\n\t\t\t\t// Draw each of the annotation handles.\r\n\t\t\t\tfor (var iHandleType in Object.keys(g_oTextCompare.eTextCompareHandleTypes)) {\r\n\r\n\t\t\t\t\t// Calculate the coordinate.\r\n\t\t\t\t\tvar handleXCoordinate = oSelectionBounds.x2 * iImageObjW + iCenterShift_x + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX;\r\n\t\t\t\t\tvar handleYCoordinate = oSelectionBounds.y1 * iImageObjH + iCenterShift_y + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY;\r\n\r\n\t\t\t\t\t// Move right based on the handle number.\r\n\t\t\t\t\thandleXCoordinate += (parseInt(iHandleType) * (g_oAnnotationActions.g_iAnnotationDragRectSize + (g_oAnnotations.g_oAnnotationNumberBox.iBeginX / 2)));\r\n\r\n\t\t\t\t\t// Draw handle.\r\n\t\t\t\t\toAnnotationContext.save();\r\n\t\t\t\t\toAnnotationContext.beginPath();\r\n\t\t\t\t\toAnnotationContext.fillStyle = g_oTextCompare.g_szHighlightColour;\r\n\t\t\t\t\toAnnotationContext.strokeStyle = g_oTextCompare.g_szHighlightColour;\r\n\t\t\t\t\toAnnotationContext.rect(handleXCoordinate, handleYCoordinate, g_oAnnotationActions.g_iAnnotationDragRectSize, g_oAnnotationActions.g_iAnnotationDragRectSize);\r\n\t\t\t\t\toAnnotationContext.closePath();\r\n\t\t\t\t\toAnnotationContext.fill();\r\n\r\n\t\t\t\t\t// Draw the handle image.\r\n\t\t\t\t\toAnnotationContext.drawImage(g_oTextCompare.getHandleImage(iHandleType, g_oTextCompare.g_szHighlightColour, oAnnotationCanvas.g_iRotDegrees), handleXCoordinate + 4, handleYCoordinate + 4, g_oAnnotationActions.g_iAnnotationDragRectSize - 8, g_oAnnotationActions.g_iAnnotationDragRectSize - 8);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights the words for a text compare.\r\n\t * @param {object} oWords - The words to highlight.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.highlightTextCompareWords = function (oWords, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text for the document page.\r\n\t\tvar oDocumentText = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t// Ensure we have the text.\r\n\t\tif (oDocumentText == null) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = oDocumentText.textData;\r\n\r\n\t\t// Keep track of the current and previous word statuses.\r\n\t\tvar iPreviousWordStatus = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\t\tvar iCurrentWordStatus = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\r\n\t\t// Highlight each of the words.\r\n\t\tfor (var i = 0; i < oWords.length; i++) {\r\n\r\n\t\t\t// Extract the status of the current word.\r\n\t\t\tiCurrentWordStatus = oWords[i].status;\r\n\r\n\t\t\t// If we have highlighted the previous word on this paragraph line.\r\n\t\t\tif (i > 0 && oWords[i].word == oWords[i - 1].word + 1 && oWords[i].line == oWords[i - 1].line && oWords[i].paragraph == oWords[i - 1].paragraph) {\r\n\r\n\t\t\t\t// Get the previous word.\r\n\t\t\t\tvar oWord = oTextData.Paragraphs[oWords[i].paragraph].Lines[oWords[i].line].Words[oWords[i].word];\r\n\t\t\t\tvar oPreviousWord = oTextData.Paragraphs[oWords[i - 1].paragraph].Lines[oWords[i - 1].line].Words[oWords[i - 1].word];\r\n\r\n\t\t\t\t// Determine the coordinates to be used for the space based on the text direction.\r\n\t\t\t\tvar iX1 = oPreviousWord.X2 < oWord.X1 ? oPreviousWord.X2 : oPreviousWord.X1;\r\n\t\t\t\tvar iX2 = oPreviousWord.X2 < oWord.X1 ? oWord.X1 : oWord.X2;\r\n\t\t\t\tvar iY1 = oPreviousWord.Y1 < oWord.Y2 ? oPreviousWord.Y2 : oPreviousWord.Y1;\r\n\t\t\t\tvar iY2 = oPreviousWord.Y1 < oWord.Y2 ? oWord.Y1 : oWord.Y2;\r\n\r\n\t\t\t\t// If both this and the previous word have the same status, use this for the space.\r\n\t\t\t\tif (iCurrentWordStatus == iPreviousWordStatus) {\r\n\t\t\t\t\tg_oTextTools.setHighlightColour(g_oTextCompare.getAnnotationColourFromDifferenceType(iCurrentWordStatus));\r\n\t\t\t\t}\r\n\t\t\t\t// Otherwise use the highlight colour.\r\n\t\t\t\telse {\r\n\t\t\t\t\tg_oTextTools.setHighlightColour(g_oTextCompare.g_szHighlightColour);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Highlight the space between the two words.\r\n\t\t\t\tg_oTextTools.highlightElement(iX1, iX2, iY1, iY2, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t}\r\n\r\n\t\t\t// Highlight the word in the correct colour.\r\n\t\t\tg_oTextTools.setHighlightColour(g_oTextCompare.getAnnotationColourFromDifferenceType(iCurrentWordStatus));\r\n\t\t\tg_oTextTools.highlightWord(oWords[i].paragraph, oWords[i].line, oWords[i].word, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t\t// Update the status of the previous word.\r\n\t\t\tiPreviousWordStatus = iCurrentWordStatus;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Highlights the characters for a text compare.\r\n\t * @param {object} oCharacters - The characters to highlight.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.highlightTextCompareCharacters = function (oCharacters, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text for the document page.\r\n\t\tvar oDocumentText = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t// Ensure we have the text.\r\n\t\tif (oDocumentText == null) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oTextData = oDocumentText.textData;\r\n\r\n\t\t// Keep track of the current and previous character statuses.\r\n\t\tvar iPreviousCharacterStatus = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\t\tvar iCurrentCharacterStatus = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\r\n\t\t// Highlight each of the characters.\r\n\t\tfor (var i = 0; i < oCharacters.length; i++) {\r\n\r\n\t\t\t// Extract the status of the current character.\r\n\t\t\tiCurrentCharacterStatus = oCharacters[i].status;\r\n\r\n\t\t\t// If we have highlighted the previous character on this paragraph line.\r\n\t\t\tif (i > 0 && oCharacters[i].word == oCharacters[i - 1].word + 1 && oCharacters[i].line == oCharacters[i - 1].line && oCharacters[i].paragraph == oCharacters[i - 1].paragraph) {\r\n\r\n\t\t\t\t// Get the previous character.\r\n\t\t\t\tvar oCharacter = oTextData.Paragraphs[oCharacters[i].paragraph].Lines[oCharacters[i].line].Words[oCharacters[i].word].Characters[oCharacters[i].character];\r\n\t\t\t\tvar oPreviousCharacter = oTextData.Paragraphs[oCharacters[i - 1].paragraph].Lines[oCharacters[i - 1].line].Words[oCharacters[i - 1].word].Characters[oCharacters[i - 1].character];\r\n\r\n\t\t\t\t// Determine the coordinates to be used for the space based on the text direction.\r\n\t\t\t\tvar iX1 = oPreviousCharacter.X2 < oCharacter.X1 ? oPreviousCharacter.X2 : oPreviousCharacter.X1;\r\n\t\t\t\tvar iX2 = oPreviousCharacter.X2 < oCharacter.X1 ? oCharacter.X1 : oCharacter.X2;\r\n\t\t\t\tvar iY1 = oPreviousCharacter.Y1 < oCharacter.Y2 ? oPreviousCharacter.Y2 : oPreviousCharacter.Y1;\r\n\t\t\t\tvar iY2 = oPreviousCharacter.Y1 < oCharacter.Y2 ? oCharacter.Y1 : oCharacter.Y2;\r\n\r\n\t\t\t\t// If both this and the previous character have the same status, use this for the space.\r\n\t\t\t\tif (iCurrentCharacterStatus == iPreviousCharacterStatus) {\r\n\t\t\t\t\tg_oTextTools.setHighlightColour(g_oTextCompare.getAnnotationColourFromDifferenceType(iCurrentCharacterStatus));\r\n\t\t\t\t}\r\n\t\t\t\t// Otherwise use the highlight colour.\r\n\t\t\t\telse {\r\n\t\t\t\t\tg_oTextTools.setHighlightColour(g_oTextCompare.g_szHighlightColour);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Highlight the space between the two characters.\r\n\t\t\t\tg_oTextTools.highlightElement(iX1, iX2, iY1, iY2, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t}\r\n\r\n\t\t\t// Highlight the character in the correct colour.\r\n\t\t\tg_oTextTools.setHighlightColour(g_oTextCompare.getAnnotationColourFromDifferenceType(iCurrentCharacterStatus));\r\n\t\t\tg_oTextTools.highlightCharacter(oCharacters[i].paragraph, oCharacters[i].line, oCharacters[i].word, oCharacters[i].character, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t\t// Update the status of the previous word.\r\n\t\t\tiPreviousCharacterStatus = iCurrentCharacterStatus;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the annotation colour from the difference type.\r\n\t * @param {enum} eDifferenceType - The difference type.\r\n\t */\r\n\tTextCompare.prototype.getAnnotationColourFromDifferenceType = function (eDifferenceType) {\r\n\t\tvar szColour;\r\n\r\n\t\tswitch (eDifferenceType) {\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.Addition: szColour = \"green\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.Deletion: szColour = \"red\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.Substitution: szColour = \"orange\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.WeightSubstitution: szColour = \"orange\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.StyleSubstitution: szColour = \"orange\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.WeightStyleSubstitution: szColour = \"orange\"; break;\r\n\t\t\tdefault: szColour = g_oTextCompare.g_szHighlightColour; break;\r\n\t\t}\r\n\r\n\t\treturn szColour;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the annotation colour from the difference status.\r\n\t * @param {enum} eDifferenceStatus - The difference status.\r\n\t */\r\n\tTextCompare.prototype.getAnnotationColourFromDifferenceStatus = function (eDifferenceStatus) {\r\n\t\tvar szColour;\r\n\r\n\t\tswitch (eDifferenceStatus) {\r\n\t\t\tcase g_oTextCompare.eDifferenceStatuses.Ignore: szColour = \"grey\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceStatuses.Accept: szColour = \"green\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceStatuses.Reject: szColour = \"red\"; break;\r\n\t\t\tdefault: szColour = \"orange\"; break;\r\n\t\t}\r\n\r\n\t\treturn szColour;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the handle fill style.\r\n\t * @param {string} handleColour - The handle colour.\r\n\t */\r\n\tTextCompare.prototype.getHandleFillStyle = function (handleColour) {\r\n\t\treturn (handleColour === \"yellow\" || handleColour === \"#FFFF00\" || handleColour === \"cyan\" || handleColour === \"#00FFFF\") ? \"#000000\" : \"#FFFFFF\";\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the handle image.\r\n\t * @param {int} handleType - The handle type.\r\n\t * @param {int} handleColour - The handle colour.\r\n\t * @param {int} rotation - The canvas rotation.\r\n\t */\r\n\tTextCompare.prototype.getHandleImage = function (handleType, handleColour, rotation) {\r\n\r\n\t\t// Determine the colour.\r\n\t\tvar bBrightColor = handleColour === \"yellow\" || handleColour === \"#FFFF00\" || handleColour === \"cyan\" || handleColour === \"#00FFFF\";\r\n\r\n\t\t// Determine the image.\r\n\t\tswitch (parseInt(handleType)) {\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.AddText:\r\n\t\t\t\tswitch (rotation) {\r\n\t\t\t\t\tcase 90: return bBrightColor ? g_oAnnotationActions.g_oAddTextIconBlk270 : g_oAnnotationActions.g_oAddTextIcon270; break;\r\n\t\t\t\t\tcase 180: return bBrightColor ? g_oAnnotationActions.g_oAddTextIconBlk180 : g_oAnnotationActions.g_oAddTextIcon180; break;\r\n\t\t\t\t\tcase 270: return bBrightColor ? g_oAnnotationActions.g_oAddTextIconBlk90 : g_oAnnotationActions.g_oAddTextIcon90; break;\r\n\t\t\t\t\tdefault: return bBrightColor ? g_oAnnotationActions.g_oAddTextIconBlk : g_oAnnotationActions.g_oAddTextIcon; break;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.AddParagraph:\r\n\t\t\t\tswitch (rotation) {\r\n\t\t\t\t\tcase 90: return bBrightColor ? g_oAnnotationActions.g_oAddParagraphIconBlk270 : g_oAnnotationActions.g_oAddParagraphIcon270; break;\r\n\t\t\t\t\tcase 180: return bBrightColor ? g_oAnnotationActions.g_oAddParagraphIconBlk180 : g_oAnnotationActions.g_oAddParagraphIcon180; break;\r\n\t\t\t\t\tcase 270: return bBrightColor ? g_oAnnotationActions.g_oAddParagraphIconBlk90 : g_oAnnotationActions.g_oAddParagraphIcon90; break;\r\n\t\t\t\t\tdefault: return bBrightColor ? g_oAnnotationActions.g_oAddParagraphIconBlk : g_oAnnotationActions.g_oAddParagraphIcon; break;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.AddArea:\r\n\t\t\t\tswitch (rotation) {\r\n\t\t\t\t\tcase 90: return bBrightColor ? g_oAnnotationActions.g_oAddAreaIconBlk270 : g_oAnnotationActions.g_oAddAreaIcon270; break;\r\n\t\t\t\t\tcase 180: return bBrightColor ? g_oAnnotationActions.g_oAddAreaIconBlk180 : g_oAnnotationActions.g_oAddAreaIcon180; break;\r\n\t\t\t\t\tcase 270: return bBrightColor ? g_oAnnotationActions.g_oAddAreaIconBlk90 : g_oAnnotationActions.g_oAddAreaIcon90; break;\r\n\t\t\t\t\tdefault: return bBrightColor ? g_oAnnotationActions.g_oAddAreaIconBlk : g_oAnnotationActions.g_oAddAreaIcon; break;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.RemoveText:\r\n\t\t\t\tswitch (rotation) {\r\n\t\t\t\t\tcase 90: return bBrightColor ? g_oAnnotationActions.g_oRemoveTextIconBlk270 : g_oAnnotationActions.g_oRemoveTextIcon270; break;\r\n\t\t\t\t\tcase 180: return bBrightColor ? g_oAnnotationActions.g_oRemoveTextIconBlk180 : g_oAnnotationActions.g_oRemoveTextIcon180; break;\r\n\t\t\t\t\tcase 270: return bBrightColor ? g_oAnnotationActions.g_oRemoveTextIconBlk90 : g_oAnnotationActions.g_oRemoveTextIcon90; break;\r\n\t\t\t\t\tdefault: return bBrightColor ? g_oAnnotationActions.g_oRemoveTextIconBlk : g_oAnnotationActions.g_oRemoveTextIcon; break;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.Delete:\r\n\t\t\t\tswitch (rotation) {\r\n\t\t\t\t\tcase 90: return bBrightColor ? g_oAnnotationActions.g_oDeleteIconBlk270 : g_oAnnotationActions.g_oDeleteIcon270; break;\r\n\t\t\t\t\tcase 180: return bBrightColor ? g_oAnnotationActions.g_oDeleteIconBlk180 : g_oAnnotationActions.g_oDeleteIcon180; break;\r\n\t\t\t\t\tcase 270: return bBrightColor ? g_oAnnotationActions.g_oDeleteIconBlk90 : g_oAnnotationActions.g_oDeleteIcon90; break;\r\n\t\t\t\t\tdefault: return bBrightColor ? g_oAnnotationActions.g_oDeleteIconBlk : g_oAnnotationActions.g_oDeleteIcon; break;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Cheks if a handle has been clicked.\r\n\t * @param {object} event - The click event.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.checkHandleClicked = function (event, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the click coordinates.\r\n\t\tvar oClick = g_oAnnotations.getClick(event, oArtworkCanvas);\r\n\r\n\t\t// Transform the click for the rotation.\r\n\t\tvar oTransformedClick = g_oAnnotations.transformClickForRotation(oClick[0], oClick[1], oArtworkCanvas);\r\n\r\n\t\t// Convert the clicks to percentages.\r\n\t\tvar iClickPercentage_X = oTransformedClick[0] / oArtworkCanvas.g_iScaledImageWidth;\r\n\t\tvar iClickPercentage_Y = oTransformedClick[1] / oArtworkCanvas.g_iScaledImageHeight;\r\n\r\n\t\t// Calculate the compare offset on the artwork canvas.\r\n\t\tvar co = g_oCompare.calculateCompareOffsetInPx(oArtworkCanvas);\r\n\t\tvar compareOffset_x = co.x;\r\n\t\tvar compareOffset_y = co.y;\r\n\r\n\t\t// Get the text selection group we are going to check.\r\n\t\tvar oTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(oArtworkCanvas.g_szCanvasId == \"CompareViewer\");\r\n\r\n\t\t// Check if we have selections.\r\n\t\tif (oTextSelectionGroup.length == 0) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Loop through each of the selection groups.\r\n\t\tfor (var i = 0; i < oTextSelectionGroup.length; i++) {\r\n\r\n\t\t\t// Loop through each of the text selections.\r\n\t\t\tfor (var j = 0; j < oTextSelectionGroup[i].g_oTextSelections.length; j++) {\r\n\r\n\t\t\t\t// If this text selecction is not on this page, ignore it.\r\n\t\t\t\tif (oTextSelectionGroup[i].g_oTextSelections[j].g_iPage != oArtworkCanvas.g_iCurrentPage) {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Extract the selection group.\r\n\t\t\t\tvar oSelectionGroup = oTextSelectionGroup[i].g_oTextSelections[j];\r\n\r\n\t\t\t\t// Detemine the selection bounds to be used.\r\n\t\t\t\tvar oSelectionBounds = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word ? oSelectionGroup.g_oSelectionWordsBounds : oSelectionGroup.g_oSelectionCharacterBounds;\r\n\r\n\t\t\t\t// Loop through each of the annotation handles.\r\n\t\t\t\tfor (var iHandleType in Object.keys(g_oTextCompare.eTextCompareHandleTypes)) {\r\n\r\n\t\t\t\t\t// Extract the handle positions.\r\n\t\t\t\t\tvar iHandlePosition_X = oSelectionBounds.x2 * oArtworkCanvas.g_iScaledImageWidth + compareOffset_x - g_oAnnotations.g_oAnnotationNumberBox.iBeginX;\r\n\t\t\t\t\tvar iHandlePosition_Y = oSelectionBounds.y1 * oArtworkCanvas.g_iScaledImageHeight + compareOffset_y - g_oAnnotations.g_oAnnotationNumberBox.iBeginY;\r\n\r\n\t\t\t\t\t// Move the handle right by the handle type.\r\n\t\t\t\t\tiHandlePosition_X += (parseInt(iHandleType) * (g_oAnnotationActions.g_iAnnotationDragRectSize + (g_oAnnotations.g_oAnnotationNumberBox.iBeginX / 2)));\r\n\r\n\t\t\t\t\t// Convert the handle positions to percentages.\r\n\t\t\t\t\tvar iHandlePercentageStart_X = (iHandlePosition_X) / oArtworkCanvas.g_iScaledImageWidth;\r\n\t\t\t\t\tvar iHandlePercentageStart_Y = (iHandlePosition_Y) / oArtworkCanvas.g_iScaledImageHeight;\r\n\t\t\t\t\tvar iHandlePercentageEnd_X = (iHandlePosition_X + g_oAnnotationActions.g_iAnnotationDragRectSize) / oArtworkCanvas.g_iScaledImageWidth;\r\n\t\t\t\t\tvar iHandlePercentageEnd_Y = (iHandlePosition_Y + g_oAnnotationActions.g_iAnnotationDragRectSize) / oArtworkCanvas.g_iScaledImageHeight;\r\n\r\n\t\t\t\t\t// Check the click is within the handle.\r\n\t\t\t\t\tif (iClickPercentage_X > iHandlePercentageStart_X && iClickPercentage_X < iHandlePercentageEnd_X && iClickPercentage_Y > iHandlePercentageStart_Y && iClickPercentage_Y < iHandlePercentageEnd_Y) {\r\n\r\n\t\t\t\t\t\t// Call to click the annotation handle.\r\n\t\t\t\t\t\tg_oTextCompare.clickAnnotationHandle(i, j, iHandleType, oArtworkCanvas.g_szCanvasId == \"CompareViewer\");\r\n\t\t\t\t\t\treturn;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Clicks an annotation handle.\r\n\t * @param {int} iSelectionGroup - The selection group.\r\n\t * @param {int} iSelection - The selection.\r\n\t * @param {int} iHandle - The handle.\r\n\t * @param {boolean} bCompareCanvas - The compare canvas.\r\n\t */\r\n\tTextCompare.prototype.clickAnnotationHandle = function (iSelectionGroup, iSelection, iHandle, bCompareCanvas) {\r\n\r\n\t\t// Call the corret annotation handle click event.\r\n\t\tswitch (parseInt(iHandle)) {\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.AddText:\r\n\t\t\t\tg_oTextCompare.initialiseTextCompareAddHighlight(iSelectionGroup, iSelection, false, bCompareCanvas);\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.AddParagraph:\r\n\t\t\t\tg_oTextCompare.initialiseTextCompareAddHighlight(iSelectionGroup, iSelection, true, bCompareCanvas);\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.AddArea:\r\n\t\t\t\tg_oTextCompare.initialiseTextCompareAddArea(iSelectionGroup, iSelection, true, bCompareCanvas);\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.RemoveText:\r\n\t\t\t\tg_oTextCompare.initialiseTextCompareRemoveHighlight(iSelectionGroup, iSelection, false, bCompareCanvas);\r\n\t\t\t\tbreak;\r\n\t\t\tcase g_oTextCompare.eTextCompareHandleTypes.Delete:\r\n\t\t\t\tg_oTextCompare.deleteTextData(iSelectionGroup, iSelection, bCompareCanvas, true);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare sections.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareSections = function () {\r\n\r\n\t\t// Get the highest text selection group.\r\n\t\tvar iHighestTextSelectionGroup = g_oTextCompare.getHighestTextSelectionGroup(true, true);\r\n\r\n\t\t// If we have no text selection groups, show this.\r\n\t\tif (iHighestTextSelectionGroup == 0) {\r\n\t\t\t$(\"#divTextCompareSections\").html('
' + g_oTextCompare.c_szTextCompareNoTextSelections + '
');\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Build up the HTML.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Add the top drag scroll zone.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Loop through each of the sections up to the highest.\r\n\t\tfor (var i = 1; i <= iHighestTextSelectionGroup; i++) {\r\n\r\n\t\t\t// Get the difference class for this group.\r\n\t\t\tvar szDifferencesClass = g_oTextCompare.getGroupDifferencesClass(i);\r\n\r\n\t\t\t// Add the section.\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Render the text compare section.\r\n\t\t\tszHTML += g_oTextCompare.renderTextCompareSection(i);\r\n\r\n\t\t\t// Close the section.\r\n\t\t\tszHTML += '
';\r\n\t\t}\r\n\r\n\t\t// Add the hidden new group section for drag and drop.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
New Group
';\r\n\r\n\t\t// Render the text selection approval drop zone.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Render the text selection compare drop zone.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Close the new group for the drag and drop.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the bottom drag scroll zone.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Apply the HTML.\r\n\t\t$(\"#divTextCompareSections\").html(szHTML);\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare section.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareSection = function (iGroupOrder) {\r\n\r\n\t\t// Outline the HTML to be returned.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Determine the collapsed state of the group.\r\n\t\tvar bCollapsed = g_oTextCompare.g_oCollapsedSectionOrders.indexOf(iGroupOrder) != -1;\r\n\r\n\t\t// Get the section for the approval and compare.\r\n\t\tvar oApprovalSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(iGroupOrder, false);\r\n\t\tvar oCompareSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(iGroupOrder, true);\r\n\r\n\t\t// Add the section title.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '';\r\n\t\tszHTML += g_oTextCompare.c_szTextCompareGroupText + ' ' + iGroupOrder.toString();\r\n\r\n\t\t// If we have calculated differences.\r\n\t\tif (g_oTextCompare.g_bDifferencesCalculated) {\r\n\r\n\t\t\t// If we failed to calculate for this group.\r\n\t\t\tif (oApprovalSectionGroup == null || oCompareSectionGroup == null) {\r\n\t\t\t\tszHTML += ' (' + g_oTextCompare.c_szTextCompareFailedToCalculateDifferencesText + ')';\r\n\t\t\t}\r\n\t\t\t// If we successfully calculated for this group.\r\n\t\t\telse {\r\n\t\t\t\tvar iDifferences = g_oTextCompare.countDifferences(iGroupOrder, null, null);\r\n\t\t\t\tswitch (iDifferences) {\r\n\t\t\t\t\tcase 0: szHTML += ' (' + g_oTextCompare.c_szTextCompareNoDifferencesText + ')'; break;\r\n\t\t\t\t\tcase 1: szHTML += ' (' + iDifferences + ' ' + g_oTextCompare.c_szTextCompareDifferenceText + ')'; break;\r\n\t\t\t\t\tdefault: szHTML += ' (' + iDifferences + ' ' + g_oTextCompare.c_szTextCompareDifferencesText + ')'; break;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Close the section title.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the columns collapsable wrapper.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the approval section.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += g_oTextCompare.renderTextSelections(oApprovalSectionGroup, iGroupOrder, false);\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the compare section.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += g_oTextCompare.renderTextSelections(oCompareSectionGroup, iGroupOrder, true);\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the differences section.\r\n\t\tif (g_oTextCompare.g_bDifferencesCalculated) {\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += g_oTextCompare.renderTextDifferences(oApprovalSectionGroup);\r\n\t\t\tszHTML += '
';\r\n\t\t}\r\n\r\n\t\t// Close the columns collapsable wrapper.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Return the HTML.\r\n\t\treturn szHTML;\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text selections.\r\n\t * @param {object} oSelectionGroup - The selection group.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.renderTextSelections = function (oSelectionGroup, iGroupOrder, bCompare) {\r\n\r\n\t\t// Outline the HTML to be returned.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Renders the text selection words.\r\n\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\t\t\tszHTML += g_oTextCompare.renderTextSelections_Words(oSelectionGroup, iGroupOrder, bCompare);\r\n\t\t}\r\n\t\t// Renders the text selection characters.\r\n\t\telse {\r\n\t\t\tszHTML += g_oTextCompare.renderTextSelections_Characters(oSelectionGroup, iGroupOrder, bCompare);\r\n\t\t}\r\n\r\n\t\t// Return the HTML.\r\n\t\treturn szHTML;\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text selection words.\r\n\t * @param {object} oSelectionGroup - The selection group.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.renderTextSelections_Words = function (oSelectionGroup, iGroupOrder, bCompare) {\r\n\r\n\t\t// Outline the HTML to be returned.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Determine the drop zone class to be used.\r\n\t\tvar szDropZoneClass = bCompare ? \"textCompareDropZoneWrapper--compare\" : \"textCompareDropZoneWrapper--approval\";\r\n\r\n\t\t// If this selection group does not exist, return that this is an orphaned statement.\r\n\t\tif (oSelectionGroup == null) {\r\n\r\n\t\t\t// Render the text selection orphaned statement.\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += g_oTextCompare.c_szTextCompareOrphanedStatement;\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Render the text selection drop zone.\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Return the orphaned statement html.\r\n\t\t\treturn szHTML;\r\n\t\t}\r\n\r\n\t\t// Render the text selection drop zone.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oSelectionGroup.g_oTextSelections.length; i++) {\r\n\r\n\t\t\t// Keep track of the current and previous word status.\r\n\t\t\tvar iPreviousWordStatus = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\t\t\tvar iCurrentWordStatus = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\r\n\t\t\t// Determine if we need a drag event for this div.\r\n\t\t\tvar szDragEvent = !g_oTextCompare.g_bDifferencesCalculated ? 'draggable=\"true\" ondragstart=\"g_oTextCompare.startTextDrag(event, ' + bCompare + ', false);\" ondragend=\"g_oTextCompare.endTextDrag(event);\"' : '';\r\n\r\n\t\t\t// Render the text selection.\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Render the selection text.\r\n\t\t\tfor (var j = 0; j < oSelectionGroup.g_oTextSelections[i].g_oSelectionWords.length; j++) {\r\n\r\n\t\t\t\t// Ensure we have content for the word.\r\n\t\t\t\tif (oSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].content == \"\") {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Determine the current word status.\r\n\t\t\t\tiCurrentWordStatus = oSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].status;\r\n\r\n\t\t\t\t// Add a space if needed.\r\n\t\t\t\tif (j > 0) {\r\n\r\n\t\t\t\t\t// Determine the class to be used for the space.\r\n\t\t\t\t\tvar szSpaceClass = \"divTextSection__word\";\r\n\t\t\t\t\tif (iPreviousWordStatus == g_oTextCompare.eDifferenceTypes.Addition && iCurrentWordStatus == g_oTextCompare.eDifferenceTypes.Addition) {\r\n\t\t\t\t\t\tszSpaceClass += \" divTextSection__word--addition\";\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse if (iPreviousWordStatus == g_oTextCompare.eDifferenceTypes.Deletion && iCurrentWordStatus == g_oTextCompare.eDifferenceTypes.Deletion) {\r\n\t\t\t\t\t\tszSpaceClass += \" divTextSection__word--deletion\";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the space.\r\n\t\t\t\t\tszHTML += ' ';\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Determine the class to be used for the text.\r\n\t\t\t\tvar szWordClass = \"divTextSection__word\";\r\n\t\t\t\tif (iCurrentWordStatus == g_oTextCompare.eDifferenceTypes.Addition) {\r\n\t\t\t\t\tszWordClass += \" divTextSection__word--addition\";\r\n\t\t\t\t}\r\n\t\t\t\telse if (iCurrentWordStatus == g_oTextCompare.eDifferenceTypes.Deletion) {\r\n\t\t\t\t\tszWordClass += \" divTextSection__word--deletion\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Determine if we are in bold or italic, and detecting this.\r\n\t\t\t\tif (g_oTextCompare.g_iBoldItalicDetection == g_oTextCompare.eBoldItalicDetectionLevels.On && oSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].bold) {\r\n\t\t\t\t\tszWordClass += \" divTextSection__word--bold\";\r\n\t\t\t\t}\r\n\t\t\t\tif (g_oTextCompare.g_iBoldItalicDetection == g_oTextCompare.eBoldItalicDetectionLevels.On && oSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].italic) {\r\n\t\t\t\t\tszWordClass += \" divTextSection__word--italic\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Extract the word content to be added based on the case sensitivity.\r\n\t\t\t\tvar szWordContent = g_oTextCompare.g_iCaseSensitivity == g_oTextCompare.eCaseSensitivityLevels.On ? oSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].content : oSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].content.toLowerCase();\r\n\r\n\t\t\t\t// Add the word.\r\n\t\t\t\tszHTML += '' + szWordContent + '';\r\n\r\n\t\t\t\t// Update the previous word status for the next loop.\r\n\t\t\t\tiPreviousWordStatus = iCurrentWordStatus;\r\n\t\t\t}\r\n\r\n\t\t\t// Render the options if we are not in differences mode.\r\n\t\t\tif (!g_oTextCompare.g_bDifferencesCalculated) {\r\n\t\t\t\tszHTML += '';\r\n\t\t\t\tszHTML += '';\r\n\t\t\t}\r\n\r\n\t\t\t// Close the text selection.\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Render the text selection drop zone.\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += '
';\r\n\t\t}\r\n\r\n\t\t// Return the HTML.\r\n\t\treturn szHTML;\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text selection characters.\r\n\t * @param {object} oSelectionGroup - The selection group.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.renderTextSelections_Characters = function (oSelectionGroup, iGroupOrder, bCompare) {\r\n\r\n\t\t// Outline the HTML to be returned.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Determine the drop zone class to be used.\r\n\t\tvar szDropZoneClass = bCompare ? \"textCompareDropZoneWrapper--compare\" : \"textCompareDropZoneWrapper--approval\";\r\n\r\n\t\t// If this selection group does not exist, return that this is an orphaned statement.\r\n\t\tif (oSelectionGroup == null) {\r\n\r\n\t\t\t// Render the text selection orphaned statement.\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += g_oTextCompare.c_szTextCompareOrphanedStatement;\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Render the text selection drop zone.\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Return the orphaned statement html.\r\n\t\t\treturn szHTML;\r\n\t\t}\r\n\r\n\t\t// Render the text selection drop zone.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oSelectionGroup.g_oTextSelections.length; i++) {\r\n\r\n\t\t\t// Keep track of the current and previous character status.\r\n\t\t\tvar iPreviousCharacterStatus = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\t\t\tvar iCurrentCharacterStatus = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\r\n\t\t\t// Determine if we need a drag event for this div.\r\n\t\t\tvar szDragEvent = !g_oTextCompare.g_bDifferencesCalculated ? 'draggable=\"true\" ondragstart=\"g_oTextCompare.startTextDrag(event, ' + bCompare + ', false);\" ondragend=\"g_oTextCompare.endTextDrag(event);\"' : '';\r\n\r\n\t\t\t// Render the text selection.\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Render the selection text.\r\n\t\t\tfor (var j = 0; j < oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters.length; j++) {\r\n\r\n\t\t\t\t// Ensure we have content for the character.\r\n\t\t\t\tif (oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].content == \"\") {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Determine the current character status.\r\n\t\t\t\tiCurrentCharacterStatus = oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].status;\r\n\r\n\t\t\t\t// Add a space if needed.\r\n\t\t\t\tif (oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].character == 0 && j > 0) {\r\n\r\n\t\t\t\t\t// Determine the class to be used for the space.\r\n\t\t\t\t\tvar szSpaceClass = \"divTextSection__word\";\r\n\t\t\t\t\tif (iPreviousCharacterStatus == g_oTextCompare.eDifferenceTypes.Addition && iCurrentCharacterStatus == g_oTextCompare.eDifferenceTypes.Addition) {\r\n\t\t\t\t\t\tszSpaceClass += \" divTextSection__word--addition\";\r\n\t\t\t\t\t}\r\n\t\t\t\t\telse if (iPreviousCharacterStatus == g_oTextCompare.eDifferenceTypes.Deletion && iCurrentCharacterStatus == g_oTextCompare.eDifferenceTypes.Deletion) {\r\n\t\t\t\t\t\tszSpaceClass += \" divTextSection__word--deletion\";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the space.\r\n\t\t\t\t\tszHTML += ' ';\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Determine the class to be used for the text.\r\n\t\t\t\tvar szCharacterClass = \"divTextSection__word\";\r\n\t\t\t\tif (iCurrentCharacterStatus == g_oTextCompare.eDifferenceTypes.Addition) {\r\n\t\t\t\t\tszCharacterClass += \" divTextSection__word--addition\";\r\n\t\t\t\t}\r\n\t\t\t\telse if (iCurrentCharacterStatus == g_oTextCompare.eDifferenceTypes.Deletion) {\r\n\t\t\t\t\tszCharacterClass += \" divTextSection__word--deletion\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Determine if we are in bold or italic, and detecting this.\r\n\t\t\t\tif (g_oTextCompare.g_iBoldItalicDetection == g_oTextCompare.eBoldItalicDetectionLevels.On && oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].bold) {\r\n\t\t\t\t\tszCharacterClass += \" divTextSection__word--bold\";\r\n\t\t\t\t}\r\n\t\t\t\tif (g_oTextCompare.g_iBoldItalicDetection == g_oTextCompare.eBoldItalicDetectionLevels.On && oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].italic) {\r\n\t\t\t\t\tszCharacterClass += \" divTextSection__word--italic\";\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Extract the character content to be added based on the case sensitivity.\r\n\t\t\t\tvar szCharacterContent = g_oTextCompare.g_iCaseSensitivity == g_oTextCompare.eCaseSensitivityLevels.On ? oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].content : oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].content.toLowerCase();\r\n\r\n\t\t\t\t// Add the character.\r\n\t\t\t\tszHTML += '' + szCharacterContent + '';\r\n\r\n\t\t\t\t// Update the previous character status for the next loop.\r\n\t\t\t\tiPreviousCharacterStatus = iCurrentCharacterStatus;\r\n\t\t\t}\r\n\r\n\t\t\t// Render the options if we are not in differences mode.\r\n\t\t\tif (!g_oTextCompare.g_bDifferencesCalculated) {\r\n\t\t\t\tszHTML += '';\r\n\t\t\t\tszHTML += '';\r\n\t\t\t}\r\n\r\n\t\t\t// Close the text selection.\r\n\t\t\tszHTML += '
';\r\n\r\n\t\t\t// Render the text selection drop zone.\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += '
';\r\n\t\t\tszHTML += '
';\r\n\t\t}\r\n\r\n\t\t// Return the HTML.\r\n\t\treturn szHTML;\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text differences.\r\n\t * @param {object} oSelectionGroup - The selection group.\r\n\t */\r\n\tTextCompare.prototype.renderTextDifferences = function (oSelectionGroup) {\r\n\r\n\t\t// Outline the HTML to be returned.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// If we have failed to calcuate the differences.\r\n\t\tif (g_oTextCompare.g_bDifferencesCalculated && (oSelectionGroup == null || oSelectionGroup.g_oTextDifferences == null)) {\r\n\t\t\tszHTML += '
' + g_oTextCompare.c_szTextCompareUnableToCalculateDifferences + '
';\r\n\t\t\treturn szHTML;\r\n\t\t}\r\n\r\n\t\t// If we have no differences.\r\n\t\tif (oSelectionGroup.g_oTextDifferences.length == 0) {\r\n\t\t\tszHTML += '
' + g_oTextCompare.c_szTextCompareNoDifferencesText + '
';\r\n\t\t\treturn szHTML;\r\n\t\t}\r\n\r\n\t\t// Loop through each of the differences.\r\n\t\tfor (var i = 0; i < oSelectionGroup.g_oTextDifferences.length; i++) {\r\n\r\n\t\t\t// Render the difference.\r\n\t\t\tszHTML += g_oTextCompare.renderTextDifference(oSelectionGroup.g_oTextDifferences[i]);\r\n\t\t}\r\n\r\n\t\t// Return the HTML.\r\n\t\treturn szHTML;\r\n\t};\r\n\r\n\t/**\r\n\t * Renders a text difference.\r\n\t * @param {object} oDifference - The difference.\r\n\t */\r\n\tTextCompare.prototype.renderTextDifference = function (oDifference) {\r\n\r\n\t\t// Outline the HTML to be returned.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Determine the class to be used.\r\n\t\tvar szStatusClass = \"divTextSection\";\r\n\t\tswitch (oDifference.g_iDifferenceStatus) {\r\n\t\t\tcase g_oTextCompare.eDifferenceStatuses.Initial: szStatusClass += \" divTextSection--initial\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceStatuses.Ignore: szStatusClass += \" divTextSection--ignore\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceStatuses.Accept: szStatusClass += \" divTextSection--accept\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceStatuses.Reject: szStatusClass += \" divTextSection--reject\"; break;\r\n\t\t}\r\n\r\n\t\t// Render the text difference.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the difference order.\r\n\t\tszHTML += '
' + oDifference.g_iDifferenceOrder + '
';\r\n\r\n\t\t// Add the difference step to.\r\n\t\tszHTML += '';\r\n\r\n\t\t// Add the status dropdown.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Render the difference type.\r\n\t\tszHTML += '
' + g_oTextCompare.getDifferenceText(oDifference.g_eDifferenceType) + '
';\r\n\r\n\t\t// If this is a substitution, add the compare heading.\r\n\t\tif (g_oTextCompare.differenceTypeIsSubstitution(oDifference.g_eDifferenceType)) {\r\n\t\t\tszHTML += '
' + g_oTextCompare.c_szTextCompareCompareDocument + ':
';\r\n\t\t}\r\n\r\n\t\t// Add the difference text.\r\n\t\tszHTML += '
' + oDifference.g_oFormattedDifferenceText[0] + '
';\r\n\r\n\t\t// If this is a substitution, add the approval text.\r\n\t\tif (g_oTextCompare.differenceTypeIsSubstitution(oDifference.g_eDifferenceType)) {\r\n\t\t\tszHTML += '
' + g_oTextCompare.c_szTextCompareApprovalDocument + ':
';\r\n\t\t\tszHTML += '
' + oDifference.g_oFormattedDifferenceText[1] + '
';\r\n\t\t}\r\n\r\n\t\t// Close the text difference.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Return the result.\r\n\t\treturn szHTML;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the difference text.\r\n\t * @param {enum} eDifferenceType - The difference type.\r\n\t */\r\n\tTextCompare.prototype.getDifferenceText = function (eDifferenceType) {\r\n\t\tvar szDifferenceText = \"\";\r\n\r\n\t\tswitch (eDifferenceType) {\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.Addition: szDifferenceText = g_oTextCompare.c_szTextCompareDifferenceTypeAddition; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.Deletion: szDifferenceText = g_oTextCompare.c_szTextCompareDifferenceTypeDeletion; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.Substitution: szDifferenceText = g_oTextCompare.c_szTextCompareDifferenceTypeSubstitution; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.WeightSubstitution: szDifferenceText = g_oTextCompare.c_szTextCompareDifferenceTypeSubstitution + \" (\" + g_oTextCompare.c_szTextCompareDifferenceTypeFontWeight + \")\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.StyleSubstitution: szDifferenceText = g_oTextCompare.c_szTextCompareDifferenceTypeSubstitution + \" (\" + g_oTextCompare.c_szTextCompareDifferenceTypeFontStyle + \")\"; break;\r\n\t\t\tcase g_oTextCompare.eDifferenceTypes.WeightStyleSubstitution: szDifferenceText = g_oTextCompare.c_szTextCompareDifferenceTypeSubstitution + \" (\" + g_oTextCompare.c_szTextCompareDifferenceTypeFontWeightAndStyle + \")\"; break;\r\n\t\t}\r\n\r\n\t\treturn szDifferenceText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text selection group from the order.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.getTextSelectionGroupFromOrder = function (iGroupOrder, bCompare) {\r\n\r\n\t\t// Get the approval text selections.\r\n\t\tvar oApprovalTextSelections = g_oTextCompare.getTextSelectionGroup(bCompare);\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oApprovalTextSelections.length; i++) {\r\n\r\n\t\t\t// If this is the correct group, return it.\r\n\t\t\tif (oApprovalTextSelections[i].g_iGroupOrder == iGroupOrder) {\r\n\t\t\t\treturn oApprovalTextSelections[i];\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If not found, return null.\r\n\t\treturn null;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text selection group index from the order.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.getTextSelectionGroupIndexFromOrder = function (iGroupOrder, bCompare) {\r\n\r\n\t\t// Get the approval text selections.\r\n\t\tvar oApprovalTextSelections = g_oTextCompare.getTextSelectionGroup(bCompare);\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oApprovalTextSelections.length; i++) {\r\n\r\n\t\t\t// If this is the correct group, return the index.\r\n\t\t\tif (oApprovalTextSelections[i].g_iGroupOrder == iGroupOrder) {\r\n\t\t\t\treturn i;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If not found, return -1.\r\n\t\treturn -1;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the highest text selection group.\r\n\t * @param {boolean} bApproval - If we are including the approval canvas.\r\n\t * @param {boolean} bCompare - If we are including the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.getHighestTextSelectionGroup = function (bApproval, bCompare) {\r\n\r\n\t\t// Outline the highest text selection group to be tracked.\r\n\t\tvar iHighestTextSelectionGroup = 0;\r\n\r\n\t\t// If we want to include the approval canvas.\r\n\t\tif (bApproval) {\r\n\r\n\t\t\t// Get the approval text selections.\r\n\t\t\tvar oApprovalTextSelections = g_oTextCompare.getTextSelectionGroup(false);\r\n\r\n\t\t\t// Loop through each of the approval text selections.\r\n\t\t\tfor (var i = 0; i < oApprovalTextSelections.length; i++) {\r\n\r\n\t\t\t\t// Update the highest if required.\r\n\t\t\t\tiHighestTextSelectionGroup = oApprovalTextSelections[i].g_iGroupOrder > iHighestTextSelectionGroup ? oApprovalTextSelections[i].g_iGroupOrder : iHighestTextSelectionGroup;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// If we want to include the compare canvas.\r\n\t\tif (bCompare) {\r\n\r\n\t\t\t// Get the compare text selections.\r\n\t\t\tvar oCompareTextSelections = g_oTextCompare.getTextSelectionGroup(true);\r\n\r\n\t\t\t// Loop through each of the compare text selections.\r\n\t\t\tfor (var i = 0; i < oCompareTextSelections.length; i++) {\r\n\r\n\t\t\t\t// Update the highest if required.\r\n\t\t\t\tiHighestTextSelectionGroup = oCompareTextSelections[i].g_iGroupOrder > iHighestTextSelectionGroup ? oCompareTextSelections[i].g_iGroupOrder : iHighestTextSelectionGroup;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the result.\r\n\t\treturn iHighestTextSelectionGroup;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the group differences class for an order.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t */\r\n\tTextCompare.prototype.getGroupDifferencesClass = function (iGroupOrder) {\r\n\r\n\t\t// Check if we have calculated differences.\r\n\t\tif (!g_oTextCompare.g_bDifferencesCalculated) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Get the groups for the order.\r\n\t\tvar oApprovalSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(iGroupOrder, false);\r\n\t\tvar oCompareSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(iGroupOrder, true);\r\n\r\n\t\t// If we have an orphaned statement, return rejected.\r\n\t\tif (oApprovalSectionGroup == null || oCompareSectionGroup == null) {\r\n\t\t\treturn \"divCompareSection--rejected\";\r\n\t\t}\r\n\r\n\t\t// If we have no differences, return accepted.\r\n\t\tif (oApprovalSectionGroup.g_oTextDifferences.length == 0) {\r\n\t\t\treturn \"divCompareSection--accepted\";\r\n\t\t}\r\n\r\n\t\t// Keep track of the worst status.\r\n\t\tvar szDifferenceClass = \"divCompareSection--ignore\";\r\n\r\n\t\t// Loop through each of the differences.\r\n\t\tfor (var i = 0; i < oApprovalSectionGroup.g_oTextDifferences.length; i++) {\r\n\r\n\t\t\t// If we have a status of rejected.\r\n\t\t\tif (oApprovalSectionGroup.g_oTextDifferences[i].g_iDifferenceStatus == g_oTextCompare.eDifferenceStatuses.Reject) {\r\n\r\n\t\t\t\t// Set to the rejected status and stop.\r\n\t\t\t\tszDifferenceClass = \"divCompareSection--rejected\";\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t// If we have an initial status.\r\n\t\t\telse if (oApprovalSectionGroup.g_oTextDifferences[i].g_iDifferenceStatus == g_oTextCompare.eDifferenceStatuses.Initial) {\r\n\r\n\t\t\t\t// Set to the initial status.\r\n\t\t\t\tszDifferenceClass = \"divCompareSection--initial\";\r\n\t\t\t}\r\n\t\t\t// If we have a status of accepted, and we have not updated to an initial status.\r\n\t\t\telse if (oApprovalSectionGroup.g_oTextDifferences[i].g_iDifferenceStatus == g_oTextCompare.eDifferenceStatuses.Accept && szDifferenceClass != \"divCompareSection--initial\") {\r\n\r\n\t\t\t\t// Set to the accepted status.\r\n\t\t\t\tszDifferenceClass = \"divCompareSection--accepted\";\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the difference class.\r\n\t\treturn szDifferenceClass;\r\n\t};\r\n\r\n\t/**\r\n\t * Toggles the text compare information.\r\n\t */\r\n\tTextCompare.prototype.toggleTextCompareInformation = function () {\r\n\r\n\t\t// If the info bubble does not exist.\r\n\t\tif ($(\".speechbubble__paragraph:contains(\" + g_oTextCompare.c_szTextCompareInfo_Intro + \")\").length == 0) {\r\n\r\n\t\t\t// Show the text alignment info bubble.\r\n\t\t\tg_oTextCompare.showTextCompareInformation();\r\n\t\t}\r\n\t\t// If the info bubble already exists.\r\n\t\telse {\r\n\r\n\t\t\t// Hide the text alignment info bubble.\r\n\t\t\tg_oTextCompare.hideTextCompareInformation();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Toggles the text compare separations.\r\n\t */\r\n\tTextCompare.prototype.toggleTextCompareSeparations = function () {\r\n\r\n\t\t// If the drop down is currently hidden.\r\n\t\tif ($(\"#divTextCompareSeparationsDropDown\").css(\"display\") == \"none\") {\r\n\r\n\t\t\t// Show the separations.\r\n\t\t\tg_oTextCompare.showTextCompareSeparations();\r\n\t\t}\r\n\t\t// If the drop down is currently shown.\r\n\t\telse {\r\n\r\n\t\t\t// Hide the separations.\r\n\t\t\tg_oTextCompare.hideTextCompareSeparations();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Shows the text compare separations.\r\n\t */\r\n\tTextCompare.prototype.showTextCompareSeparations = function () {\r\n\t\t// Hide the auto auto options and highlight colour.\r\n\t\tg_oTextCompare.hideTextCompareFullDocumentSelectionOptions();\r\n\t\tg_oTextCompare.hideTextCompareHighlightColour();\r\n\r\n\t\t// Render the text compare separations.\r\n\t\tg_oTextCompare.renderTextCompareSeparations();\r\n\r\n\t\t// Show the drop down.\r\n\t\t$(\"#divTextCompareSeparationsDropDown\").css(\"display\", \"block\");\r\n\t};\r\n\r\n\t/**\r\n\t * Hides the text compare separations.\r\n\t */\r\n\tTextCompare.prototype.hideTextCompareSeparations = function () {\r\n\r\n\t\t// Hide the drop down.\r\n\t\t$(\"#divTextCompareSeparationsDropDown\").css(\"display\", \"none\");\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare separations.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareSeparations = function () {\r\n\r\n\t\t// Outline the HTML to be built.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Get the canvas separations.\r\n\t\tvar oSeparationList = g_oSeparations.GetSeparationElements(g_oViewer.g_oArtworkViewer, g_oCompare.getSyncCanvas(g_oViewer.g_oArtworkViewer), []);\r\n\r\n\t\t// Create the table for the separations.\r\n\t\tszHTML += '';\r\n\r\n\t\t// Loop through each of the separations.\r\n\t\tfor (var i = 0; i < oSeparationList.length; i++) {\r\n\r\n\t\t\t// Create the separation row.\r\n\t\t\tszHTML += '';\r\n\r\n\t\t\t// Add the separation square.\r\n\t\t\tszHTML += '';\r\n\r\n\t\t\t// Add the separation name.\r\n\t\t\tszHTML += '';\r\n\r\n\t\t\t// Add the separation checkbox.\r\n\t\t\tszHTML += '';\r\n\r\n\t\t\t// Close the separation row.\r\n\t\t\tszHTML += '';\r\n\t\t}\r\n\r\n\t\t// Close the table for the separations.\r\n\t\tszHTML += '
' + '
' + '
' + oSeparationList[i].SeparationName + '' + '' + '
';\r\n\r\n\t\t// Apply the HTML.\r\n\t\t$(\"#divTextCompareSeparationsDropDown\").html(szHTML);\r\n\r\n\t\t// Update the div position.\r\n\t\t$(\"#divTextCompareSeparationsDropDown\").css(\"margin-left\", (\"-\" + (($(\"#divTextCompareSeparationsDropDown\").width() / 2) - ($(\"#btnSeparations_Common_TextCompare\").width() / 2) + 2) + \"px\"));\r\n\t};\r\n\r\n\t/**\r\n\t * Toggles the text compare auto auto options.\r\n\t */\r\n\tTextCompare.prototype.toggleTextCompareFullDocumentSelectionOptions = function () {\r\n\r\n\t\t// If the drop down is currently hidden.\r\n\t\tif ($(\"#divTextCompareFullDocumentSelectionDropDown\").css(\"display\") == \"none\") {\r\n\r\n\t\t\t// Show the auto auto options.\r\n\t\t\tg_oTextCompare.showTextCompareFullDocumentSelectionOptions();\r\n\t\t}\r\n\t\t// If the drop down is currently shown.\r\n\t\telse {\r\n\r\n\t\t\t// Hide the auto auto options.\r\n\t\t\tg_oTextCompare.hideTextCompareFullDocumentSelectionOptions();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Shows the text compare auto auto options.\r\n\t */\r\n\tTextCompare.prototype.showTextCompareFullDocumentSelectionOptions = function () {\r\n\t\t// Hide the separations and highlight colour.\r\n\t\tg_oTextCompare.hideTextCompareSeparations();\r\n\t\tg_oTextCompare.hideTextCompareHighlightColour();\r\n\r\n\t\t// Render the text compare auto auto options.\r\n\t\tg_oTextCompare.renderTextCompareFullDocumentSelectionOptions();\r\n\r\n\t\t// Show the drop down.\r\n\t\t$(\"#divTextCompareFullDocumentSelectionDropDown\").css(\"display\", \"block\");\r\n\t};\r\n\r\n\t/**\r\n\t * Hides the text compare auto auto options.\r\n\t */\r\n\tTextCompare.prototype.hideTextCompareFullDocumentSelectionOptions = function () {\r\n\r\n\t\t// Hide the drop down.\r\n\t\t$(\"#divTextCompareFullDocumentSelectionDropDown\").css(\"display\", \"none\");\r\n\t};\r\n\r\n\t/**\r\n\t * Handles the change event for the minimum match words input field.\r\n\t * @param {HTMLElement} element - The input element that triggered the change event.\r\n\t */\r\n\tTextCompare.prototype.inputMinMatchWordsOnChange = function (element) {\r\n\t\tvar value = parseInt($(element).val(), 10);\r\n\r\n\t\t// Ensure the value is between 0 and 100\r\n\t\tif (isNaN(value) || value < 2) {\r\n\t\t\tvalue = 2;\r\n\t\t} else if (value > 99) {\r\n\t\t\tvalue = 99;\r\n\t\t}\r\n\r\n\t\t$(this).val(value);\r\n\r\n\t\t// Update the fuzzy threshold setting\r\n\t\tg_oSettings.g_oUserSettings.TextComparisonFullDocumentSelectionMinMatchWords = value;\r\n\t\t\r\n\t\tg_oSettings.updateSettingTextComparisonMinMatchWords(true);\r\n\t}\r\n\r\n\t/**\r\n\t * Handles the change event for the \"Match From Document\" select element.\r\n\t * @param {HTMLElement} element - The select element that triggered the change event.\r\n\t */\r\n\tTextCompare.prototype.MatchFromDocumentOnChange = function (element) {\r\n\t\tvar value = parseInt($(element).val(), 10);\r\n\r\n\t\t// Update the fuzzy threshold setting\r\n\t\tg_oSettings.g_oUserSettings.TextComparisonFullDocumentSelectionMatchFromDocument = value;\r\n\r\n\t\tg_oSettings.updateSettingTextComparisonMatchFromDocument(true);\r\n\t}\r\n\r\n\t/**\r\n\t * Renders the text auto auto options.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareFullDocumentSelectionOptions = function () {\r\n\t\t// Retreive the user settings.\r\n\t\tvar iMatchWords = (g_oSettings.g_oUserSettings.TextComparisonFullDocumentSelectionMinMatchWords !== undefined) \r\n\t\t\t? g_oSettings.g_oUserSettings.TextComparisonFullDocumentSelectionMinMatchWords \r\n\t\t\t: 2;\r\n\r\n\t\tvar iSelectedMatchFromDocument = (g_oSettings.g_oUserSettings.TextComparisonFullDocumentSelectionMatchFromDocument !== undefined) \r\n\t\t\t? g_oSettings.g_oUserSettings.TextComparisonFullDocumentSelectionMatchFromDocument \r\n\t\t\t: 1;\r\n\r\n\t\tvar szHTML = '';\r\n\t\tszHTML += '';\r\n\r\n\t\t// Create the row for the Selection Document.\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\r\n\t\t// Create the row for the Minimum Words.\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\r\n\t\t// Create the row for the Confirm button.\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\r\n\t\tszHTML += '
Match From (Document):
Min. Match Words:';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
Perform Match
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Apply the HTML.\r\n\t\t$(\"#divTextCompareFullDocumentSelectionDropDown\").html(szHTML);\r\n\r\n\t\t// Update the div position.\r\n\t\t$(\"#divTextCompareFullDocumentSelectionDropDown\").css(\"margin-left\", (\"-\" + (($(\"#divTextCompareFullDocumentSelectionDropDown\").width() / 2) - ($(\"#btnFullDocumentSelection_Common_TextCompare\").width() / 2) + 2) + \"px\"));\r\n\t};\r\n\r\n\t/**\r\n\t * Toggles the text compare highlight colour.\r\n\t */\r\n\tTextCompare.prototype.toggleTextCompareHighlightColour = function () {\r\n\r\n\t\t// If the drop down is currently hidden.\r\n\t\tif ($(\"#divTextCompareHighlightColourDropDown\").css(\"display\") == \"none\") {\r\n\r\n\t\t\t// Show the highlight colour.\r\n\t\t\tg_oTextCompare.showTextCompareHighlightColour();\r\n\t\t}\r\n\t\t// If the drop down is currently shown.\r\n\t\telse {\r\n\r\n\t\t\t// Hide the highlight colour.\r\n\t\t\tg_oTextCompare.hideTextCompareHighlightColour();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Shows the text compare highlight colour.\r\n\t */\r\n\tTextCompare.prototype.showTextCompareHighlightColour = function () {\r\n\t\t// Hide the auto auto options and separations.\r\n\t\tg_oTextCompare.hideTextCompareFullDocumentSelectionOptions();\r\n\t\tg_oTextCompare.hideTextCompareSeparations();\r\n\r\n\t\t// Render the text compare highlight colours.\r\n\t\tg_oTextCompare.renderTextCompareHighlightColour();\r\n\r\n\t\t// Show the drop down.\r\n\t\t$(\"#divTextCompareHighlightColourDropDown\").css(\"display\", \"block\");\r\n\t};\r\n\r\n\t/**\r\n\t * Hides the text compare highlight colour.\r\n\t */\r\n\tTextCompare.prototype.hideTextCompareHighlightColour = function () {\r\n\r\n\t\t// Hide the drop down.\r\n\t\t$(\"#divTextCompareHighlightColourDropDown\").css(\"display\", \"none\");\r\n\t};\r\n\r\n\t/**\r\n\t * Renders the text compare highlight colour.\r\n\t */\r\n\tTextCompare.prototype.renderTextCompareHighlightColour = function () {\r\n\r\n\t\t// Outline the HTML to be built.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Create the table for the highlight colours.\r\n\t\tszHTML += '';\r\n\r\n\t\t// Add the colours.\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\t\tszHTML += '';\r\n\r\n\t\t// Close the table for the separations.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Apply the HTML.\r\n\t\t$(\"#divTextCompareHighlightColourDropDown\").html(szHTML);\r\n\r\n\t\t// Update the div position.\r\n\t\t$(\"#divTextCompareHighlightColourDropDown\").css(\"margin-left\", (\"-\" + (($(\"#divTextCompareHighlightColourDropDown\").width() / 2) - ($(\"#btnColour_Common_TextCompare\").width() / 2) + 6) + \"px\"));\r\n\r\n\t\t// Set the selected colour.\r\n\t\t$(\"#dropDownTextComparisonHighlightColourPopup\").find(\".annotationColorSelection\").css(\"border-color\", \"transparent\");\r\n\t\t$(\"#dropDownTextComparisonHighlightColourPopup\").find(\".annotationColorSelection.\" + g_oAnnotations.getStringColour(g_oSettings.g_oUserSettings.TextComparisonHighlightColour)).css(\"border-color\", g_oSettings.c_iSkinType == 0 ? \"white\" : \"black\");\r\n\r\n\t\t// Update the click event of the colour tiles.\r\n\t\t$(\"#dropDownTextComparisonHighlightColourPopup\").find(\".annotationColorSelection\").off('click').on('click', function () {\r\n\t\t\tg_oTextCompare.updateTextCompareHighlightColour(event.target.getAttribute('data-annotationcolour'));\r\n\t\t});\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the text compare highlight colour.\r\n\t * @param {any} szHighlightColour - The highlight colour.\r\n\t */\r\n\tTextCompare.prototype.updateTextCompareHighlightColour = function (szHighlightColour) {\r\n\r\n\t\t// Update the text comparison highlight colour.\r\n\t\tg_oTextCompare.g_szHighlightColour = g_oAnnotations.getStringColour(szHighlightColour);\r\n\r\n\t\t// Update the text comparison highlight colour setting and sync.\r\n\t\tg_oSettings.g_oUserSettings.TextComparisonHighlightColour = g_oAnnotations.getHexColour(szHighlightColour);\r\n\t\tg_oSettings.updateSettingTextComparisonHighlightColour(true);\r\n\r\n\t\t// Hide any shown highlight colour panels.\r\n\t\tg_oTextCompare.hideTextCompareHighlightColour();\r\n\t\t$(\"#settingTextComparisonHighlightColourPopup\").remove();\r\n\r\n\t\t// If a text compare is in progress, render any text compare annotations.\r\n\t\tif (g_oTextCompare.g_bTextCompareInProgress) {\r\n\t\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the text compare separation visibility.\r\n\t * @param {string} szSeparationName - The separation name.\r\n\t * @param {int} iCheckboxId - The checkbox id.\r\n\t */\r\n\tTextCompare.prototype.updateTextCompareSeparationVisibility = function (iCheckboxId) {\r\n\r\n\t\t// Determine the visibility from the checkbox.\r\n\t\tvar bVisible = $('#chkSeparation_' + iCheckboxId).is(\":checked\");\r\n\r\n\t\t// Determine the separation name.\r\n\t\tvar szSeparationName = $('#chkSeparation_' + iCheckboxId).attr(\"data-SeparationName\");\r\n\r\n\t\t// If we have turned off the visibility, check we have at least one separation visible, otherwise turn this back on.\r\n\t\tif (!bVisible && $('#divTextCompareSeparationsDropDown input:checked').length == 0) {\r\n\t\t\t$('#chkSeparation_' + iCheckboxId).prop('checked', true);\r\n\t\t\tg_oGreenlightMessages.displayWarningBubble(g_oTextCompare.c_szTextCompareOneSeparation);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Set the separation visbility.\r\n\t\tg_oSeparations.SetSeparationVisibility(g_oViewer.g_oArtworkViewer, g_oCompare.getSyncCanvas(g_oViewer.g_oArtworkViewer), szSeparationName, bVisible);\r\n\r\n\t\t// Update the stored hidden separations.\r\n\t\tg_oTextCompare.updateTextCompareHiddenSeparations();\r\n\t};\r\n\r\n\t/**\r\n\t * Resets the text compare hidden separations.\r\n\t */\r\n\tTextCompare.prototype.resetTextCompareHiddenSeparations = function () {\r\n\r\n\t\t// Reset the list of hidden separations.\r\n\t\tg_oTextCompare.g_oHiddenSeparations = [];\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the text compare hidden separations.\r\n\t */\r\n\tTextCompare.prototype.updateTextCompareHiddenSeparations = function () {\r\n\r\n\t\t// Reset the list of hidden separations.\r\n\t\tg_oTextCompare.resetTextCompareHiddenSeparations();\r\n\r\n\t\t// Get a list of the hidden separatins.\r\n\t\tvar oHiddenSeparations = $('#divTextCompareSeparationsDropDown input:not(:checked)');\r\n\r\n\t\t// Add each of the hidden separations to the list.\r\n\t\tfor (var i = 0; i < oHiddenSeparations.length; i++) {\r\n\t\t\tg_oTextCompare.g_oHiddenSeparations.push($(oHiddenSeparations[i]).attr(\"data-SeparationName\"));\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Shows the text compare information.\r\n\t */\r\n\tTextCompare.prototype.showTextCompareInformation = function () {\r\n\r\n\t\t// Show the text compare info bubble.\r\n\t\tg_oGreenlightMessages.displayInfoBubble(\r\n\t\t\t'
' + g_oTextCompare.c_szTextCompareInfo_Intro + '
' +\r\n\t\t\t'
' + g_oTextCompare.c_szTextCompareInfo_Add + '
' +\r\n\t\t\t'
' + g_oTextCompare.c_szTextCompareInfo_Remove + '
' +\r\n\t\t\t'
' + g_oTextCompare.c_szTextCompareInfo_Review + '
' +\r\n\t\t\t'
' + g_oTextCompare.c_szTextCompareInfo_Exit + '
'\r\n\t\t\t, false);\r\n\t};\r\n\r\n\t/**\r\n\t * Hides the text compare information.\r\n\t */\r\n\tTextCompare.prototype.hideTextCompareInformation = function () {\r\n\r\n\t\t// Hide the alignment info bubble.\r\n\t\tg_oGreenlightMessages.closeBubbles(\"Info\");\r\n\t};\r\n\r\n\t/**\r\n\t * Starts the text drag.\r\n\t * @param {object} event - The event.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.startTextDrag = function (event, bCompare) {\r\n\r\n\t\t// Get the id of the dragged div.\r\n\t\tvar szDivId = event.target.id == \"\" ? event.target.parentNode.id : event.target.id;\r\n\r\n\t\t// Set the data of the drag.\r\n\t\tevent.dataTransfer.setData(\"text\", szDivId);\r\n\r\n\t\t// Give the div the dragging class.\r\n\t\t$(\"#\" + szDivId).addClass(\"divTextSection--dragging\");\r\n\r\n\t\t// Have to delay the call to initialise the drag function as Chrome fires the event before the initialisation.\r\n\t\tsetTimeout(function () {\r\n\r\n\t\t\t// Determine if we are showing the drop zones for the approval or compare.\r\n\t\t\tvar szCanvasDropZoneClass = bCompare ? \"textCompareDropZoneWrapper--compare\" : \"textCompareDropZoneWrapper--approval\";\r\n\r\n\t\t\t// Activate the drop zones and wrappers.\r\n\t\t\t$(\".\" + szCanvasDropZoneClass).addClass(\"textCompareDropZoneWrapper--active\");\r\n\r\n\t\t\t// Activate the drag drop new group.\r\n\t\t\t$(\"#divDragDropNewGroup\").show();\r\n\r\n\t\t\t// Activate the drag scroll zones.\r\n\t\t\t$(\".divScrollZoneTop\").show();\r\n\t\t\t$(\".divScrollZoneBottom\").show();\r\n\t\t}, 10);\r\n\t};\r\n\r\n\t/**\r\n\t * Move text drag event.\r\n\t * @param {object} event - The event.\r\n\t * @param {boolean} moveUp - If we are moving up or down.\r\n\t */\r\n\tTextCompare.prototype.moveTextDrag = function (event, moveUp) {\r\n\r\n\t\t// Ensure we are not already drag scrolling.\r\n\t\tif (g_oTextCompare.g_bDragScrolling) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Set that we are drag scrolling.\r\n\t\tg_oTextCompare.g_bDragScrolling = true;\r\n\r\n\t\t// Get the current scroll position of the sections div.\r\n\t\tvar iCurrentScrollTop = $(\"#divTextCompareSections\").scrollTop();\r\n\r\n\t\t// Determine the amount to be scrolled.\r\n\t\tvar iScrollAmount = (moveUp ? -100 : 100);\r\n\r\n\t\t// Scroll the div.\r\n\t\t$(\"#divTextCompareSections\").animate({ scrollTop: iCurrentScrollTop + iScrollAmount }, 200, function () { g_oTextCompare.g_bDragScrolling = false; });\r\n\t};\r\n\r\n\t/**\r\n\t * End the text drag.\r\n\t * @param {object} event - The event.\r\n\t */\r\n\tTextCompare.prototype.endTextDrag = function (event) {\r\n\r\n\t\t// Remove any dragging classes.\r\n\t\t$(\".divTextSection--dragging\").removeClass(\"divTextSection--dragging\");\r\n\r\n\t\t// Deactivate the drag drop new group.\r\n\t\t$(\"#divDragDropNewGroup\").hide();\r\n\r\n\t\t// Deactivates the drop zones.\r\n\t\t$(\".textCompareDropZoneWrapper--active\").removeClass(\"textCompareDropZoneWrapper--active\");\r\n\r\n\t\t// Deactivate the drag scroll zones.\r\n\t\t$(\".divScrollZoneTop\").hide();\r\n\t\t$(\".divScrollZoneBottom\").hide();\r\n\t};\r\n\r\n\t/**\r\n\t * Text drag over event.\r\n\t * @param {object} event - The event.\r\n\t */\r\n\tTextCompare.prototype.textDragOver = function (event) {\r\n\t\tevent.preventDefault();\r\n\t\tevent.stopPropagation();\r\n\t\t$(event.target).addClass(\"textCompareDropZone--hover\");\r\n\t};\r\n\r\n\t/**\r\n\t * Text drag out event.\r\n\t * @param {object} event - The event.\r\n\t */\r\n\tTextCompare.prototype.textDragOut = function (event) {\r\n\t\tevent.preventDefault();\r\n\t\tevent.stopPropagation();\r\n\t\t$(event.target).removeClass(\"textCompareDropZone--hover\");\r\n\t};\r\n\r\n\t/**\r\n\t * Text drop event.\r\n\t * @param {object} event - The event.\r\n\t */\r\n\tTextCompare.prototype.textDrop = function (event) {\r\n\t\tevent.preventDefault();\r\n\t\tevent.stopPropagation();\r\n\r\n\t\t// End the text drag.\r\n\t\tg_oTextCompare.endTextDrag();\r\n\r\n\t\t// Get the dragged item and destination ids.\r\n\t\tvar oDraggedItemId = event.dataTransfer.getData(\"text\");\r\n\t\tvar oDragDestination = event.target.id;\r\n\r\n\t\t// Split these into the individual properties.\r\n\t\tvar iDestinationGroupOrder = parseInt(oDragDestination.split(\"_\")[1]);\r\n\t\tvar iDestinationSelectionOrder = parseInt(oDragDestination.split(\"_\")[2]);\r\n\t\tvar iDraggedGroupOrder = parseInt(oDraggedItemId.split(\"_\")[1]);\r\n\t\tvar iDraggedTextData = parseInt(oDraggedItemId.split(\"_\")[2]);\r\n\t\tvar bCompareCanvas = (oDraggedItemId.split(\"_\")[3] == \"true\");\r\n\r\n\t\t// Get the group indexes from the group order.\r\n\t\tvar iDestinationGroupIndex = g_oTextCompare.getTextSelectionGroupIndexFromOrder(iDestinationGroupOrder, bCompareCanvas);\r\n\t\tvar iDraggedGroupIndex = g_oTextCompare.getTextSelectionGroupIndexFromOrder(iDraggedGroupOrder, bCompareCanvas);\r\n\r\n\t\t// Move the text data.\r\n\t\tg_oTextCompare.moveTextData(iDestinationGroupOrder, iDestinationGroupIndex, iDestinationSelectionOrder, iDraggedGroupIndex, iDraggedTextData, bCompareCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Moves the text data.\r\n\t * @param {int} iTargetGroupOrder - The target group order.\r\n\t * @param {int} iTargetGroup - The target group.\r\n\t * @param {int} iTargetGroupSelection - The target group selection.\r\n\t * @param {int} iSelectionGroup - The selection group.\r\n\t * @param {int} iSelection - The selection.\r\n\t * @param {boolean} bCompareCanvas - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.moveTextData = function (iTargetGroupOrder, iTargetGroup, iTargetGroupSelection, iSelectionGroup, iSelection, bCompareCanvas) {\r\n\r\n\t\t// Get the text selection group we are going to add to.\r\n\t\tvar oTextSelectionGroup = g_oTextCompare.getTextSelectionGroup(bCompareCanvas);\r\n\r\n\t\t// Take a copy of the text data.\r\n\t\tvar oCopiedTextData = deepCopyArray(oTextSelectionGroup[iSelectionGroup].g_oTextSelections[iSelection]);\r\n\r\n\t\t// If the target group does not exist, add this.\r\n\t\tif (iTargetGroup == -1) {\r\n\t\t\toTextSelectionGroup.push(new g_oTextCompare.textSelectionGroup(iTargetGroupOrder));\r\n\t\t\tiTargetGroup = oTextSelectionGroup.length - 1;\r\n\t\t}\r\n\r\n\t\t// Add the text data to the group at the required position.\r\n\t\toTextSelectionGroup[iTargetGroup].g_oTextSelections.splice(iTargetGroupSelection, 0, oCopiedTextData);\r\n\r\n\t\t// If we have moved this text data into the same group before the existing item, update the index being removed.\r\n\t\tif (iTargetGroup == iSelectionGroup && iTargetGroupSelection < iSelection) {\r\n\t\t\tiSelection++;\r\n\t\t}\r\n\r\n\t\t// Delete the text data.\r\n\t\tg_oTextCompare.deleteTextData(iSelectionGroup, iSelection, bCompareCanvas, false);\r\n\r\n\t\t// Drop any unused text groups.\r\n\t\tg_oTextCompare.dropUnusedTextGroups();\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Toggles the text section.\r\n\t * @param {int} iSelectionGroup - The section to toggle.\r\n\t */\r\n\tTextCompare.prototype.toggleTextSection = function (iSelectionGroup) {\r\n\r\n\t\t// Clear the filter box input value.\r\n\t\t$(\"#txtTextComparison_FilterBox\").val(\"\");\r\n\r\n\t\t// If this group is already collapsed.\r\n\t\tif (g_oTextCompare.g_oCollapsedSectionOrders.indexOf(iSelectionGroup) != -1) {\r\n\r\n\t\t\t// Expand the group.\r\n\t\t\tg_oTextCompare.expandTextSection(iSelectionGroup);\r\n\t\t}\r\n\t\t// If this group is not already collapsed.\r\n\t\telse {\r\n\r\n\t\t\t// Collapse the group.\r\n\t\t\tg_oTextCompare.collapseTextSection(iSelectionGroup);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Collapses the text section.\r\n\t * @param {int} iSelectionGroup - The text section.\r\n\t */\r\n\tTextCompare.prototype.collapseTextSection = function (iSelectionGroup) {\r\n\r\n\t\t// Add the group to the collapsed list.\r\n\t\tg_oTextCompare.g_oCollapsedSectionOrders.push(iSelectionGroup);\r\n\r\n\t\t// Update the group toggle icon.\r\n\t\t$(\"#divCompareSectionIcon_\" + iSelectionGroup).attr(\"src\", \"img/Arrow_Right_16.png\");\r\n\r\n\t\t// Collapse the group.\r\n\t\t$(\"#divCompareSections_\" + iSelectionGroup).slideToggle();\r\n\t};\r\n\r\n\t/**\r\n\t * Expands the text section.\r\n\t * @param {int} iSelectionGroup - The text section.\r\n\t */\r\n\tTextCompare.prototype.expandTextSection = function (iSelectionGroup) {\r\n\r\n\t\t// Remove the group from the collapsed list.\r\n\t\tvar iIndex = g_oTextCompare.g_oCollapsedSectionOrders.indexOf(iSelectionGroup);\r\n\t\tif (iIndex > -1) {\r\n\t\t\tg_oTextCompare.g_oCollapsedSectionOrders.splice(iIndex, 1);\r\n\t\t}\r\n\r\n\t\t// Update the group toggle icon.\r\n\t\t$(\"#divCompareSectionIcon_\" + iSelectionGroup).attr(\"src\", \"img/Arrow_Down_16.png\");\r\n\r\n\t\t// Expand the group.\r\n\t\t$(\"#divCompareSections_\" + iSelectionGroup).slideToggle();\r\n\t};\r\n\r\n\t/**\r\n\t * Toggles the filter.\r\n\t */\r\n\tTextCompare.prototype.toggleFilter = function () {\r\n\r\n\t\t// If the filter is currently hidden.\r\n\t\tif ($('#txtTextComparison_FilterBox').css(\"opacity\") == \"0\") {\r\n\r\n\t\t\t// Show the filter box.\r\n\t\t\t$('#txtTextComparison_FilterBox').css(\"display\", \"block\")\r\n\r\n\t\t\t// Animate in the filter box.\r\n\t\t\t$('#txtTextComparison_FilterBox').animate({\r\n\t\t\t\t\"opacity\": '1',\r\n\t\t\t\t\"margin-right\": '16px',\r\n\t\t\t});\r\n\t\t}\r\n\t\t// If the filter is currently shown.\r\n\t\telse {\r\n\r\n\t\t\t// Clear the filter box input value.\r\n\t\t\t$(\"#txtTextComparison_FilterBox\").val(\"\");\r\n\r\n\t\t\t// Animate out the filter box.\r\n\t\t\t$('#txtTextComparison_FilterBox').animate({\r\n\t\t\t\t\"opacity\": '0',\r\n\t\t\t\t\"margin-right\": '0px',\r\n\t\t\t}, \"\", function () { $('#txtTextComparison_FilterBox').css(\"display\", \"none\") });\r\n\t\t}\r\n\r\n\t\t// Apply the filter.\r\n\t\tg_oTextCompare.applyFilter();\r\n\t};\r\n\r\n\t/**\r\n\t * Applies the filter.\r\n\t */\r\n\tTextCompare.prototype.applyFilter = function () {\r\n\r\n\t\t// Clear any collapsed sections as these will be collapsed based on the filter.\r\n\t\tg_oTextCompare.g_oCollapsedSectionOrders = [];\r\n\r\n\t\t// Get the filter value.\r\n\t\tvar szFilter = $(\"#txtTextComparison_FilterBox\").val();\r\n\r\n\t\t// If we have a filter.\r\n\t\tif (szFilter.length > 0) {\r\n\r\n\t\t\t// Get the highest text selection group.\r\n\t\t\tvar iHighestTextSelectionGroup = g_oTextCompare.getHighestTextSelectionGroup(true, true);\r\n\r\n\t\t\t// Loop through each text selection group.\r\n\t\t\tfor (var i = 1; i <= iHighestTextSelectionGroup; i++) {\r\n\r\n\t\t\t\t// If this group does not match our filter.\r\n\t\t\t\tif (!g_oTextCompare.groupMatchesFilter(i, szFilter)) {\r\n\r\n\t\t\t\t\t// Add the group to the collapsed list.\r\n\t\t\t\t\tg_oTextCompare.g_oCollapsedSectionOrders.push(i);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Checks if the group matches the filter.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t * @param {string} szFilter - The filter.\r\n\t */\r\n\tTextCompare.prototype.groupMatchesFilter = function (iGroupOrder, szFilter) {\r\n\r\n\t\t// Get the approval group for the order.\r\n\t\tvar oApprovalSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(iGroupOrder, false);\r\n\r\n\t\t// If we have an approval selection group.\r\n\t\tif (oApprovalSectionGroup != null) {\r\n\r\n\t\t\t// Loop through each of the text selections.\r\n\t\t\tfor (var i = 0; i < oApprovalSectionGroup.g_oTextSelections.length; i++) {\r\n\r\n\t\t\t\t// Determine the text to be compared.\r\n\t\t\t\tvar oSelectionText = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word ? oApprovalSectionGroup.g_oTextSelections[i].g_oSelectionWordsText : oApprovalSectionGroup.g_oTextSelections[i].g_oSelectionCharactersText;\r\n\r\n\t\t\t\t// If this text selection matches the filter.\r\n\t\t\t\tif (oSelectionText.toLowerCase().indexOf(szFilter.toLowerCase()) != -1) {\r\n\r\n\t\t\t\t\t// Return that we have a match.\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Get the compare group for the order.\r\n\t\tvar oCompareSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(iGroupOrder, true);\r\n\r\n\t\t// If we have a compare selection group.\r\n\t\tif (oCompareSectionGroup != null) {\r\n\r\n\t\t\t// Loop through each of the text selections.\r\n\t\t\tfor (var i = 0; i < oCompareSectionGroup.g_oTextSelections.length; i++) {\r\n\r\n\t\t\t\t// Determine the text to be compared.\r\n\t\t\t\tvar oSelectionText = g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word ? oCompareSectionGroup.g_oTextSelections[i].g_oSelectionWordsText : oCompareSectionGroup.g_oTextSelections[i].g_oSelectionCharactersText;\r\n\r\n\t\t\t\t// If this text selection matches the filter.\r\n\t\t\t\tif (oSelectionText.toLowerCase().indexOf(szFilter.toLowerCase()) != -1) {\r\n\r\n\t\t\t\t\t// Return that we have a match.\r\n\t\t\t\t\treturn true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return no match was found.\r\n\t\treturn false;\r\n\t};\r\n\r\n\t/**\r\n\t * Calculates the differences.\r\n\t */\r\n\tTextCompare.prototype.calculateDifferences = function () {\r\n\r\n\t\t// If we have already calculated the differences, do nothing.\r\n\t\tif (g_oTextCompare.g_bDifferencesCalculated) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get the highest text selection group.\r\n\t\tvar iHighestTextSelectionGroup = g_oTextCompare.getHighestTextSelectionGroup(true, true);\r\n\r\n\t\t// Ensure we have at least one selection group to calculate.\r\n\t\tif (iHighestTextSelectionGroup < 1) {\r\n\t\t\tg_oGreenlightMessages.displayWarningBubble(g_oTextCompare.c_szTextCompareDifferenceNoSelections);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Set that we have calculated differences.\r\n\t\tg_oTextCompare.g_bDifferencesCalculated = true;\r\n\r\n\t\t// Set the approval combo control to read only.\r\n\t\tvar iApprovalComboControlId = comboControl_GetControlById(\"approvalNameComboControl\", true);\r\n\t\tcomboControl_UpdateReadOnly(iApprovalComboControlId, true);\r\n\r\n\t\t// Set the compare combo control to read only.\r\n\t\tvar iCompareComboControlId = comboControl_GetControlById(\"approvalCompareComboControl\", true);\r\n\t\tcomboControl_UpdateReadOnly(iCompareComboControlId, true);\r\n\r\n\t\t// Get the accuracy to calculate the differences to.\r\n\t\tg_oTextCompare.g_iAccuracy = parseInt($(\"#divTextComparisonAccuracy\").val());\r\n\r\n\t\t// Get the case sensitivity to calculate the differences to.\r\n\t\tg_oTextCompare.g_iCaseSensitivity = parseInt($(\"#divTextComparisonCaseSensitivity\").val());\r\n\r\n\t\t// Get the bold italic detection to calculate differences to.\r\n\t\tg_oTextCompare.g_iBoldItalicDetection = parseInt($(\"#divTextComparisonBoldItalicDetection\").val());\r\n\r\n\t\t// Get the whitespace detection setting to calculate differences to.\r\n\t\tg_oTextCompare.g_iWhitespaceDetection = parseInt($(\"#divTextComparisonWhitespaceDetection\").val());\r\n\r\n\t\t// Get the auto selection setting to calculate differences to.\r\n\t\tg_oTextCompare.g_iAutoSelection = parseInt($(\"#divTextComparisonAutoSelection\").val());\r\n\r\n\t\t// Update the active tab.\r\n\t\t$(\"#divTextComparisonTitle_Review\").removeClass(\"divTextComparisonTitle__Text--active\");\r\n\t\t$(\"#divTextComparisonTitle_Comparison\").addClass(\"divTextComparisonTitle__Text--active\");\r\n\r\n\t\t// Show the differences bottom bar.\r\n\t\t$(\"#divTextDifferences\").show();\r\n\r\n\t\t// Disable the icons that edit text selections.\r\n\t\t$(\"#btnTextHighlight_Viewer_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnTextHighlight_Compare_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnParagraphHighlight_Viewer_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnParagraphHighlight_Compare_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnAreaTextHighlight_Viewer_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnAreaTextHighlight_Compare_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnTextClear_Viewer_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnTextClear_Compare_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnTextClear_Common_TextCompare\").addClass(\"ToolbarImage--disabled\");\r\n\r\n\t\t// Enable the step through icon.\r\n\t\t$(\"#imgTextComparison_StepThrough\").removeClass(\"divTextComparisonTitle__Option--disabled\");\r\n\r\n\t\t// Disable the select lists.\r\n\t\t$(\"#divTextComparisonAccuracy\").prop(\"disabled\", \"disabled\");\r\n\t\t$(\"#divTextComparisonCaseSensitivity\").prop(\"disabled\", \"disabled\");\r\n\t\t$(\"#divTextComparisonBoldItalicDetection\").prop(\"disabled\", \"disabled\");\r\n\t\t$(\"#divTextComparisonWhitespaceDetection\").prop(\"disabled\", \"disabled\");\r\n\t\t$(\"#divTextComparisonAutoSelection\").prop(\"disabled\", \"disabled\");\r\n\r\n\t\t// Reset the collpased sections.\r\n\t\tg_oTextCompare.g_oCollapsedSectionOrders = [];\r\n\r\n\t\t// Update the difference calculations.\r\n\t\tg_oTextCompare.updateDifferenceCalculations();\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\r\n\t\t// Collapse the sections with no differences.\r\n\t\tfor (var i = 1; i <= iHighestTextSelectionGroup; i++) {\r\n\t\t\tif (g_oTextCompare.countDifferences(i, null, null) == 0) {\r\n\t\t\t\t$(\"#divCompareSectionIcon_\" + i).click();\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the difference calculations.\r\n\t */\r\n\tTextCompare.prototype.updateDifferenceCalculations = function () {\r\n\r\n\t\t// Reset the difference counter.\r\n\t\tg_oTextCompare.g_iNumberOfDifferences = 0;\r\n\r\n\t\t// Get the highest text selection group.\r\n\t\tvar iHighestTextSelectionGroup = g_oTextCompare.getHighestTextSelectionGroup(true, true);\r\n\r\n\t\t// Loop through each of the sections up to the highest.\r\n\t\tfor (var i = 1; i <= iHighestTextSelectionGroup; i++) {\r\n\r\n\t\t\t// Calculate the differences for this group.\r\n\t\t\tg_oTextCompare.calculateGroupDifferences(i);\r\n\t\t}\r\n\r\n\t\t// Outline the summary icon to be added.\r\n\t\tvar szSummaryIcon = '';\r\n\r\n\t\t// Outline the print annotations icon to be added.\r\n\t\tvar szPrintIcon = '';\r\n\r\n\t\t// Update the differences heading.\r\n\t\tvar iDifferencesCount = g_oTextCompare.countDifferences(null, null, null);\r\n\t\t$(\"#divTextCompareHeadingDifferences\").html(iDifferencesCount.toString() + ' ' + (iDifferencesCount == 1 ? g_oTextCompare.c_szTextCompareDifferenceLocated : g_oTextCompare.c_szTextCompareDifferencesLocated) + szSummaryIcon + szPrintIcon);\r\n\t};\r\n\r\n\t/**\r\n\t * Resets the differences.\r\n\t */\r\n\tTextCompare.prototype.resetDifferences = function () {\r\n\r\n\t\t// If we have not calculated the differences, do nothing.\r\n\t\tif (!g_oTextCompare.g_bDifferencesCalculated) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Set that we have not calculated differences.\r\n\t\tg_oTextCompare.g_bDifferencesCalculated = false;\r\n\r\n\t\t// Set the approval combo control to not read only.\r\n\t\tvar iApprovalComboControlId = comboControl_GetControlById(\"approvalNameComboControl\", true);\r\n\t\tcomboControl_UpdateReadOnly(iApprovalComboControlId, false);\r\n\r\n\t\t// Set the compare combo control to not read only.\r\n\t\tvar iCompareComboControlId = comboControl_GetControlById(\"approvalCompareComboControl\", true);\r\n\t\tcomboControl_UpdateReadOnly(iCompareComboControlId, false);\r\n\r\n\t\t// Update the active tab.\r\n\t\t$(\"#divTextComparisonTitle_Review\").addClass(\"divTextComparisonTitle__Text--active\");\r\n\t\t$(\"#divTextComparisonTitle_Comparison\").removeClass(\"divTextComparisonTitle__Text--active\");\r\n\r\n\t\t// Clear the collapsed sections.\r\n\t\tg_oTextCompare.g_oCollapsedSectionOrders = [];\r\n\r\n\t\t// Reset the differences heading.\r\n\t\t$(\"#divTextCompareHeadingDifferences\").html(g_oTextCompare.c_szTextCompareDifferencesNotCalculated);\r\n\r\n\t\t// Hide the differences bottom bar.\r\n\t\t$(\"#divTextDifferences\").hide();\r\n\r\n\t\t// Enable the icons that edit text selections.\r\n\t\t$(\"#btnTextHighlight_Viewer_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnTextHighlight_Compare_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnParagraphHighlight_Viewer_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnParagraphHighlight_Compare_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnAreaTextHighlight_Viewer_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnAreaTextHighlight_Compare_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnTextClear_Viewer_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnTextClear_Compare_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\t\t$(\"#btnTextClear_Common_TextCompare\").removeClass(\"ToolbarImage--disabled\");\r\n\r\n\t\t// Disable the step through icon.\r\n\t\t$(\"#imgTextComparison_StepThrough\").addClass(\"divTextComparisonTitle__Option--disabled\");\r\n\r\n\t\t// Enable the select lists if these are not locked by the consumer.\r\n\t\t$(\"#divTextComparisonAccuracy\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonAccuracy ? \"disabled\" : \"\");\r\n\t\t$(\"#divTextComparisonCaseSensitivity\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonCaseSensitivity ? \"disabled\" : \"\");\r\n\t\t$(\"#divTextComparisonBoldItalicDetection\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonBoldItalicDetection ? \"disabled\" : \"\");\r\n\t\t$(\"#divTextComparisonWhitespaceDetection\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonWhitespaceDetection ? \"disabled\" : \"\");\r\n\t\t$(\"#divTextComparisonAutoSelection\").prop(\"disabled\", g_oSettings.g_oConsumerSettings.LockTextComparisonAutoSelection ? \"disabled\" : \"\");\r\n\r\n\t\t// Reset all approval section differences.\r\n\t\tfor (var i = 0; i < g_oTextCompare.g_oArtworkTextSelectionGroups.length; i++) {\r\n\t\t\tg_oTextCompare.g_oArtworkTextSelectionGroups[i].g_oTextModifications = [];\r\n\t\t\tg_oTextCompare.g_oArtworkTextSelectionGroups[i].g_oTextDifferences = [];\r\n\t\t\tg_oTextCompare.resetListStatuses(g_oTextCompare.g_oArtworkTextSelectionGroups[i]);\r\n\t\t}\r\n\r\n\t\t// Reset all compare section differences.\r\n\t\tfor (var j = 0; j < g_oTextCompare.g_oCompareTextSelectionGroups.length; j++) {\r\n\t\t\tg_oTextCompare.g_oCompareTextSelectionGroups[j].g_oTextModifications = [];\r\n\t\t\tg_oTextCompare.g_oCompareTextSelectionGroups[j].g_oTextDifferences = [];\r\n\t\t\tg_oTextCompare.resetListStatuses(g_oTextCompare.g_oCompareTextSelectionGroups[j]);\r\n\t\t}\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Counts the differences.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t * @param {enum} eDifferenceType - The difference type to limit to.\r\n\t * @param {enum} eDifferenceStatuses - The status type to limit to.\r\n\t */\r\n\tTextCompare.prototype.countDifferences = function (iGroupOrder, eDifferenceType, eDifferenceStatus) {\r\n\r\n\t\t// Keep track of the number of differences.\r\n\t\tvar iDifferences = 0;\r\n\r\n\t\t// Get the highest text selection group.\r\n\t\tvar iHighestTextSelectionGroup = g_oTextCompare.getHighestTextSelectionGroup(true, true);\r\n\r\n\t\t// Loop through each of the sections up to the highest.\r\n\t\tfor (var i = 1; i <= iHighestTextSelectionGroup; i++) {\r\n\r\n\t\t\t// If we have passed a group order and this does not match.\r\n\t\t\tif (iGroupOrder != null && iGroupOrder != i) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Get the approval group for the order.\r\n\t\t\tvar oApprovalSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(i, false);\r\n\r\n\t\t\t// If the group exists and differences have been calculated.\r\n\t\t\tif (oApprovalSectionGroup != null && oApprovalSectionGroup.g_oTextDifferences != null) {\r\n\r\n\t\t\t\t// Loop through each of the differences.\r\n\t\t\t\tfor (var j = 0; j < oApprovalSectionGroup.g_oTextDifferences.length; j++) {\r\n\r\n\t\t\t\t\t// If we have passed a difference type and this does not match.\r\n\t\t\t\t\tif (eDifferenceType != null && eDifferenceType != oApprovalSectionGroup.g_oTextDifferences[j].g_eDifferenceType) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// If we have passed a status type and this does not match.\r\n\t\t\t\t\tif (eDifferenceStatus != null && eDifferenceStatus != oApprovalSectionGroup.g_oTextDifferences[j].g_iDifferenceStatus) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the difference.\r\n\t\t\t\t\tiDifferences++;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the number of differences.\r\n\t\treturn iDifferences;\r\n\t};\r\n\r\n\t/**\r\n\t * Calculates the group differences.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t */\r\n\tTextCompare.prototype.calculateGroupDifferences = function (iGroupOrder) {\r\n\r\n\t\t// Get the approval and compare selection group for the order.\r\n\t\tvar oApprovalSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(iGroupOrder, false);\r\n\t\tvar oCompareSectionGroup = g_oTextCompare.getTextSelectionGroupFromOrder(iGroupOrder, true);\r\n\r\n\t\t// If we do not have both sections.\r\n\t\tif (oApprovalSectionGroup == null || oCompareSectionGroup == null) {\r\n\r\n\t\t\t// Set that differences could not be calculated.\r\n\t\t\tif (oApprovalSectionGroup != null) {\r\n\t\t\t\toApprovalSectionGroup.g_oTextModifications = null;\r\n\t\t\t\toApprovalSectionGroup.g_oTextDifferences = null;\r\n\t\t\t\tg_oTextCompare.resetListStatuses(oApprovalSectionGroup);\r\n\t\t\t}\r\n\r\n\t\t\t// Set that differences could not be calculated.\r\n\t\t\tif (oCompareSectionGroup != null) {\r\n\t\t\t\toCompareSectionGroup.g_oTextModifications = null;\r\n\t\t\t\toCompareSectionGroup.g_oTextDifferences = null;\r\n\t\t\t\tg_oTextCompare.resetListStatuses(oCompareSectionGroup);\r\n\t\t\t}\r\n\r\n\t\t\t// Do not process the differences.\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get the approval and compare combined text.\r\n\t\tvar szApprovalText = g_oTextCompare.combineTextSelections(oApprovalSectionGroup.g_oTextSelections);\r\n\t\tvar szCompareText = g_oTextCompare.combineTextSelections(oCompareSectionGroup.g_oTextSelections);\r\n\r\n\t\t// If we are performing a case insensitive match, replace any text with lower case.\r\n\t\tif (g_oTextCompare.g_iCaseSensitivity == g_oTextCompare.eCaseSensitivityLevels.Off) {\r\n\t\t\tszApprovalText = szApprovalText.toLowerCase();\r\n\t\t\tszCompareText = szCompareText.toLowerCase();\r\n\t\t}\r\n\r\n\t\t// Calculate the text comparisons to the correct level.\r\n\t\tvar oTextComparisons = g_oTextCompare.calculateTextComparison(szCompareText, szApprovalText);\r\n\r\n\t\t// Convert the text comparisons to text modifications.\r\n\t\tvar oTextModifications = g_oTextCompare.convertTextComparisonsToModifications(oTextComparisons);\r\n\r\n\t\t// Remove any text equivalents from the modifications.\r\n\t\tg_oTextCompare_Equivalents.removeTextEquivalentsFromModifications(oTextModifications);\r\n\r\n\t\t// Convert the text modifications to text differences.\r\n\t\tvar oTextDifferences = g_oTextCompare.convertTextModificationsToDifferences(oTextModifications);\r\n\r\n\t\t// Update the approval group.\r\n\t\toApprovalSectionGroup.g_oTextModifications = oTextModifications;\r\n\t\toApprovalSectionGroup.g_oTextDifferences = oTextDifferences;\r\n\r\n\t\t// Update the compare group.\r\n\t\toCompareSectionGroup.g_oTextModifications = oTextModifications;\r\n\t\toCompareSectionGroup.g_oTextDifferences = oTextDifferences;\r\n\r\n\t\t// Update the list statuses.\r\n\t\tg_oTextCompare.updateListStatuses(oApprovalSectionGroup, false);\r\n\t\tg_oTextCompare.updateListStatuses(oCompareSectionGroup, true);\r\n\r\n\t\t// If we are calculating the bold italic differences.\r\n\t\tif (g_oTextCompare.g_iBoldItalicDetection == g_oTextCompare.eBoldItalicDetectionLevels.On) {\r\n\t\t\tg_oTextCompare.calculateBoldItalicDifferences(oApprovalSectionGroup.g_oTextSelections, oCompareSectionGroup.g_oTextSelections, oApprovalSectionGroup.g_oTextDifferences);\r\n\t\t}\r\n\r\n\t\t// Generate the formatted differences text.\r\n\t\tg_oTextCompare.generateFormattedDifferenceText(oApprovalSectionGroup, oCompareSectionGroup, oApprovalSectionGroup.g_oTextDifferences);\r\n\t};\r\n\r\n\t/**\r\n\t * Resets the word list statuses.\r\n\t * @param {object} oSelectionGroup - The text selection group.\r\n\t */\r\n\tTextCompare.prototype.resetListStatuses = function (oSelectionGroup) {\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oSelectionGroup.g_oTextSelections.length; i++) {\r\n\r\n\t\t\t// Loop through each of the words in the selection.\r\n\t\t\tfor (var j = 0; j < oSelectionGroup.g_oTextSelections[i].g_oSelectionWords.length; j++) {\r\n\r\n\t\t\t\t// Update the status of the word.\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].status = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].difference = -1;\r\n\r\n\t\t\t\t// Update the marker of the word.\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].marker = g_oTextCompare.eMarkerTypes.NoMarker;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].markerDifference = -1;\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the characters in the selection.\r\n\t\t\tfor (var j = 0; j < oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters.length; j++) {\r\n\r\n\t\t\t\t// Update the status of the word.\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].status = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].difference = -1;\r\n\r\n\t\t\t\t// Update the marker of the word.\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].marker = g_oTextCompare.eMarkerTypes.NoMarker;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].markerDifference = -1;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the list statuses.\r\n\t * @param {object} oSelectionGroup - The selection group.\r\n\t * @param {bool} bCompare - If this on the compare document.\r\n\t */\r\n\tTextCompare.prototype.updateListStatuses = function (oSelectionGroup, bCompare) {\r\n\r\n\t\t// If our accuracy is at a word level.\r\n\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\t\t\tg_oTextCompare.updateWordListStatuses(oSelectionGroup, bCompare);\r\n\t\t}\r\n\t\t// If our accuracy is at a character level.\r\n\t\telse {\r\n\t\t\tg_oTextCompare.updateCharacterListStatuses(oSelectionGroup, bCompare);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the word list statuses.\r\n\t * @param {object} oSelectionGroup - The selection group.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.updateWordListStatuses = function (oSelectionGroup, bCompare) {\r\n\r\n\t\t// Keep track of the difference we are on.\r\n\t\tvar iDifference = 1;\r\n\r\n\t\t// Get a list of all words and their modifications.\r\n\t\tvar oModificationWords = [];\r\n\r\n\t\t// Keep track of any words that need to show markers.\r\n\t\tvar oMarkerWords = [];\r\n\r\n\t\t// Loop through each of the text modifications.\r\n\t\tfor (var i = 0; i < oSelectionGroup.g_oTextModifications.length; i++) {\r\n\r\n\t\t\t// Ensure this modification is not specifically mapped to the other canvas.\r\n\t\t\tif ((!bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceMapping == g_oTextCompare.g_eDifferenceMapping.CompareOnly) ||\r\n\t\t\t\t(bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceMapping == g_oTextCompare.g_eDifferenceMapping.ApprovalOnly)) {\r\n\r\n\t\t\t\t// Skip this modification.\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Ensure this modification is relevant for the compare setting.\r\n\t\t\tif ((!bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Deletion) ||\r\n\t\t\t\t(bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Addition)) {\r\n\r\n\t\t\t\t// If this non-compare addition is not part of a substitution.\r\n\t\t\t\tif (bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Addition && (i == 0 || i > 0 && oSelectionGroup.g_oTextModifications[i - 1].g_eDifferenceType != g_oTextCompare.eDifferenceTypes.Deletion)) {\r\n\r\n\t\t\t\t\t// Set that the previous and next words needs to be markers.\r\n\t\t\t\t\toMarkerWords.push({\r\n\t\t\t\t\t\tstartWord: oModificationWords.length - 1,\r\n\t\t\t\t\t\tendWord: oModificationWords.length,\r\n\t\t\t\t\t\tdifference: iDifference\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t// We need to increment the difference as we skip as this canvas has no text for the difference.\r\n\t\t\t\t\tiDifference++;\r\n\t\t\t\t}\r\n\t\t\t\t// If this compare deletion is not part of a substitution.\r\n\t\t\t\telse if (!bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Deletion && (i + 1 == oSelectionGroup.g_oTextModifications.length || oSelectionGroup.g_oTextModifications[i + 1].g_eDifferenceType != g_oTextCompare.eDifferenceTypes.Addition)) {\r\n\r\n\t\t\t\t\t// Set that the previous and next words needs to be markers.\r\n\t\t\t\t\toMarkerWords.push({\r\n\t\t\t\t\t\tstartWord: oModificationWords.length - 1,\r\n\t\t\t\t\t\tendWord: oModificationWords.length,\r\n\t\t\t\t\t\tdifference: iDifference\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t// We need to increment the difference as we skip as this canvas has no text for the difference.\r\n\t\t\t\t\tiDifference++;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Skip this modification.\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Split the modification into its individual words.\r\n\t\t\tvar oSplitWords = oSelectionGroup.g_oTextModifications[i].g_szModificationText.split(' ');\r\n\r\n\t\t\t// Loop through each of the split words.\r\n\t\t\tfor (var j = 0; j < oSplitWords.length; j++) {\r\n\r\n\t\t\t\t// Ensure this split word has content.\r\n\t\t\t\tif (oSplitWords[j] == \"\") {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Add the split word and its modification to the list.\r\n\t\t\t\toModificationWords.push({\r\n\t\t\t\t\tcontent: oSplitWords[j],\r\n\t\t\t\t\tstatus: oSelectionGroup.g_oTextModifications[i].g_eDifferenceType,\r\n\t\t\t\t\tdifference: oSelectionGroup.g_oTextModifications[i].g_eDifferenceType != g_oTextCompare.eDifferenceTypes.NoDifference ? iDifference : -1,\r\n\t\t\t\t\tmarker: g_oTextCompare.eMarkerTypes.NoMarker,\r\n\t\t\t\t\tmarkerDifference: -1,\r\n\t\t\t\t\tequivalentDifference: (oSelectionGroup.g_oTextModifications[i].g_eDifferenceMapping == g_oTextCompare.g_eDifferenceMapping.ApprovalOnly || oSelectionGroup.g_oTextModifications[i].g_eDifferenceMapping == g_oTextCompare.g_eDifferenceMapping.CompareOnly)\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Increment the difference count if this is a valid difference.\r\n\t\t\tif (oSelectionGroup.g_oTextModifications[i].g_eDifferenceType != g_oTextCompare.eDifferenceTypes.NoDifference) {\r\n\t\t\t\tiDifference++;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Loop through each of the markers.\r\n\t\tfor (var i = 0; i < oMarkerWords.length; i++) {\r\n\r\n\t\t\t// If both words exist, or only the first word exists.\r\n\t\t\tif ((oModificationWords[oMarkerWords[i].startWord] != undefined && oModificationWords[oMarkerWords[i].endWord] != undefined) ||\r\n\t\t\t\t(oModificationWords[oMarkerWords[i].startWord] != undefined && oModificationWords[oMarkerWords[i].endWord] == undefined)) {\r\n\r\n\t\t\t\t// Set that the start word has a marker after.\r\n\t\t\t\toModificationWords[oMarkerWords[i].startWord].marker = g_oTextCompare.eMarkerTypes.MarkerAfter;\r\n\t\t\t\toModificationWords[oMarkerWords[i].startWord].markerDifference = oMarkerWords[i].difference;\r\n\t\t\t}\r\n\t\t\t// If only the end word exists.\r\n\t\t\telse if (oModificationWords[oMarkerWords[i].startWord] == undefined && oModificationWords[oMarkerWords[i].endWord] != undefined) {\r\n\r\n\t\t\t\t// Set that the end word has a marker before.\r\n\t\t\t\toModificationWords[oMarkerWords[i].endWord].marker = g_oTextCompare.eMarkerTypes.MarkerBefore;\r\n\t\t\t\toModificationWords[oMarkerWords[i].endWord].markerDifference = oMarkerWords[i].difference;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Keep track of the current modification word.\r\n\t\tvar iModificationWord = 0;\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oSelectionGroup.g_oTextSelections.length; i++) {\r\n\r\n\t\t\t// Loop through each of the words in the selection.\r\n\t\t\tfor (var j = 0; j < oSelectionGroup.g_oTextSelections[i].g_oSelectionWords.length; j++) {\r\n\r\n\t\t\t\t// If this is a blank word, skip.\r\n\t\t\t\tif (oSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].content == \"\") {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Update the status, difference and marker of the word.\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].status = oModificationWords[iModificationWord].status;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].difference = oModificationWords[iModificationWord].difference;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].marker = oModificationWords[iModificationWord].marker;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].markerDifference = oModificationWords[iModificationWord].markerDifference;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionWords[j].equivalentDifference = oModificationWords[iModificationWord].equivalentDifference;\r\n\r\n\t\t\t\t// Increment the modification word.\r\n\t\t\t\tiModificationWord++;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Update the character list statuses.\r\n\t * @param {object} oSelectionGroup - The selection group.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.updateCharacterListStatuses = function (oSelectionGroup, bCompare) {\r\n\r\n\t\t// Keep track of the difference we are on.\r\n\t\tvar iDifference = 1;\r\n\r\n\t\t// Get a list of all characters and their modifications.\r\n\t\tvar oModificationCharacters = [];\r\n\r\n\t\t// Keep track of any characters that need to show markers.\r\n\t\tvar oMarkerCharacters = [];\r\n\r\n\t\t// Loop through each of the text modifications.\r\n\t\tfor (var i = 0; i < oSelectionGroup.g_oTextModifications.length; i++) {\r\n\r\n\t\t\t// Ensure this modification is not specifically mapped to the other canvas.\r\n\t\t\tif ((!bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceMapping == g_oTextCompare.g_eDifferenceMapping.CompareOnly) ||\r\n\t\t\t\t(bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceMapping == g_oTextCompare.g_eDifferenceMapping.ApprovalOnly)) {\r\n\r\n\t\t\t\t// Skip this modification.\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Ensure this modification is relevant for the compare setting.\r\n\t\t\tif ((!bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Deletion) ||\r\n\t\t\t\t(bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Addition)) {\r\n\r\n\t\t\t\t// If this non-compare addition is not part of a substitution.\r\n\t\t\t\tif (bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Addition && (i == 0 || i > 0 && oSelectionGroup.g_oTextModifications[i - 1].g_eDifferenceType != g_oTextCompare.eDifferenceTypes.Deletion)) {\r\n\r\n\t\t\t\t\t// Set that the previous and next characters needs to be markers.\r\n\t\t\t\t\toMarkerCharacters.push({\r\n\t\t\t\t\t\tstartCharacter: oModificationCharacters.length - 1,\r\n\t\t\t\t\t\tendCharacter: oModificationCharacters.length,\r\n\t\t\t\t\t\tdifference: iDifference\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t// We need to increment the difference as we skip as this canvas has no text for the difference.\r\n\t\t\t\t\tiDifference++;\r\n\t\t\t\t}\r\n\t\t\t\t// If this compare deletion is not part of a substitution.\r\n\t\t\t\telse if (!bCompare && oSelectionGroup.g_oTextModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Deletion && (i + 1 == oSelectionGroup.g_oTextModifications.length || oSelectionGroup.g_oTextModifications[i + 1].g_eDifferenceType != g_oTextCompare.eDifferenceTypes.Addition)) {\r\n\r\n\t\t\t\t\t// Set that the previous and next characters needs to be markers.\r\n\t\t\t\t\toMarkerCharacters.push({\r\n\t\t\t\t\t\tstartCharacter: oModificationCharacters.length - 1,\r\n\t\t\t\t\t\tendCharacter: oModificationCharacters.length,\r\n\t\t\t\t\t\tdifference: iDifference\r\n\t\t\t\t\t});\r\n\r\n\t\t\t\t\t// We need to increment the difference as we skip as this canvas has no text for the difference.\r\n\t\t\t\t\tiDifference++;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Skip this modification.\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Split the modification into its individual characters.\r\n\t\t\tvar oSplitCharacters = oSelectionGroup.g_oTextModifications[i].g_szModificationText;\r\n\r\n\t\t\t// Loop through each of the split characters.\r\n\t\t\tfor (var j = 0; j < oSplitCharacters.length; j++) {\r\n\r\n\t\t\t\t// Ensure this split character has content.\r\n\t\t\t\tif (oSplitCharacters[j] == \" \") {\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Add the split character and its modification to the list.\r\n\t\t\t\toModificationCharacters.push({\r\n\t\t\t\t\tcontent: oSplitCharacters[j],\r\n\t\t\t\t\tstatus: oSelectionGroup.g_oTextModifications[i].g_eDifferenceType,\r\n\t\t\t\t\tdifference: oSelectionGroup.g_oTextModifications[i].g_eDifferenceType != g_oTextCompare.eDifferenceTypes.NoDifference ? iDifference : -1,\r\n\t\t\t\t\tmarker: g_oTextCompare.eMarkerTypes.NoMarker,\r\n\t\t\t\t\tmarkerDifference: -1,\r\n\t\t\t\t\tequivalentDifference: (oSelectionGroup.g_oTextModifications[i].g_eDifferenceMapping == g_oTextCompare.g_eDifferenceMapping.ApprovalOnly || oSelectionGroup.g_oTextModifications[i].g_eDifferenceMapping == g_oTextCompare.g_eDifferenceMapping.CompareOnly)\r\n\t\t\t\t});\r\n\t\t\t}\r\n\r\n\t\t\t// Increment the difference count if this is a valid difference.\r\n\t\t\tif (oSelectionGroup.g_oTextModifications[i].g_eDifferenceType != g_oTextCompare.eDifferenceTypes.NoDifference) {\r\n\t\t\t\tiDifference++;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Loop through each of the markers.\r\n\t\tfor (var i = 0; i < oMarkerCharacters.length; i++) {\r\n\r\n\t\t\t// If both characters exist, or only the first character exists.\r\n\t\t\tif ((oModificationCharacters[oMarkerCharacters[i].startCharacter] != undefined && oModificationCharacters[oMarkerCharacters[i].endCharacter] != undefined) ||\r\n\t\t\t\t(oModificationCharacters[oMarkerCharacters[i].startCharacter] != undefined && oModificationCharacters[oMarkerCharacters[i].endCharacter] == undefined)) {\r\n\r\n\t\t\t\t// Set that the start character has a marker after.\r\n\t\t\t\toModificationCharacters[oMarkerCharacters[i].startCharacter].marker = g_oTextCompare.eMarkerTypes.MarkerAfter;\r\n\t\t\t\toModificationCharacters[oMarkerCharacters[i].startCharacter].markerDifference = oMarkerCharacters[i].difference;\r\n\t\t\t}\r\n\t\t\t// If only the end character exists.\r\n\t\t\telse if (oModificationCharacters[oMarkerCharacters[i].startCharacter] == undefined && oModificationCharacters[oMarkerCharacters[i].endCharacter] != undefined) {\r\n\r\n\t\t\t\t// Set that the end character has a marker before.\r\n\t\t\t\toModificationCharacters[oMarkerCharacters[i].endCharacter].marker = g_oTextCompare.eMarkerTypes.MarkerBefore;\r\n\t\t\t\toModificationCharacters[oMarkerCharacters[i].endCharacter].markerDifference = oMarkerCharacters[i].difference;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Keep track of the current modification character.\r\n\t\tvar iModificationCharacter = 0;\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oSelectionGroup.g_oTextSelections.length; i++) {\r\n\r\n\t\t\t// Loop through each of the text selection characters.\r\n\t\t\tfor (var j = 0; j < oSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters.length; j++) {\r\n\r\n\t\t\t\t// If we have run out of modification words.\r\n\t\t\t\tif (oModificationCharacters[iModificationCharacter] == undefined) {\r\n\t\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].status = 0;\r\n\t\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].difference = -1;\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Update the status and difference of the word.\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].status = oModificationCharacters[iModificationCharacter].status;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].difference = oModificationCharacters[iModificationCharacter].difference;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].marker = oModificationCharacters[iModificationCharacter].marker;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].markerDifference = oModificationCharacters[iModificationCharacter].markerDifference;\r\n\t\t\t\toSelectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j].equivalentDifference = oModificationCharacters[iModificationCharacter].equivalentDifference;\r\n\r\n\t\t\t\t// Increment the modification word.\r\n\t\t\t\tiModificationCharacter++;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Calculates the text comparison.\r\n\t * @param {string} text1 - The first text.\r\n\t * @param {string} text2 - The second text.\r\n\t */\r\n\tTextCompare.prototype.calculateTextComparison = function (text1, text2) {\r\n\r\n\t\t// Outline the differences to be returned.\r\n\t\tvar oDifferences = [];\r\n\r\n\t\t// If we are calculating differences to a word level.\r\n\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\t\t\toDifferences = g_oTextCompare.calculateTextComparisonWords(text1, text2);\r\n\t\t}\r\n\t\t// If we are calculating differences to a character level.\r\n\t\telse {\r\n\t\t\toDifferences = g_oTextCompare.calculateTextComparisonCharacters(text1, text2);\r\n\t\t}\r\n\r\n\t\t// Return the differences.\r\n\t\treturn oDifferences;\r\n\t};\r\n\r\n\t/**\r\n\t * Calculates the text comparison words.\r\n\t * @param {string} text1 - The first text.\r\n\t * @param {string} text2 - The second text.\r\n\t */\r\n\tTextCompare.prototype.calculateTextComparisonWords = function (text1, text2) {\r\n\r\n\t\t// Initialise the diff match patch.\r\n\t\tvar oDiffMatchPath = new diff_match_patch();\r\n\r\n\t\t// Convert the lines to words and extract the text.\r\n\t\tvar oLinesToWords = oDiffMatchPath.diff_linesToWords_(text1, text2);\r\n\t\tvar oLineText1 = oLinesToWords.chars1;\r\n\t\tvar oLineText2 = oLinesToWords.chars2;\r\n\t\tvar oLineArray = oLinesToWords.lineArray;\r\n\r\n\t\t// Calculate the differences.\r\n\t\tvar oDifferences = oDiffMatchPath.diff_main(oLineText1, oLineText2, false);\r\n\r\n\t\t// Convert the difference characters to lines.\r\n\t\toDiffMatchPath.diff_charsToLines_(oDifferences, oLineArray);\r\n\r\n\t\t// Cleanup semantic.\r\n\t\toDiffMatchPath.diff_cleanupSemantic(oDifferences);\r\n\r\n\t\t// Cleanup blanks.\r\n\t\toDiffMatchPath.diff_cleanupBlankValues(oDifferences);\r\n\r\n\t\t// Return the differences.\r\n\t\treturn oDifferences;\r\n\t};\r\n\r\n\t/**\r\n\t * Calculates the text comparison characters.\r\n\t * @param {string} text1 - The first text.\r\n\t * @param {string} text2 - The second text.\r\n\t */\r\n\tTextCompare.prototype.calculateTextComparisonCharacters = function (text1, text2) {\r\n\r\n\t\t// Initialise the diff match patch.\r\n\t\tvar oDiffMatchPatch = new diff_match_patch();\r\n\r\n\t\t// Calculate the differences.\r\n\t\tvar oDifferences = oDiffMatchPatch.diff_main(text1, text2);\r\n\r\n\t\t// Cleanup semantic.\r\n\t\toDiffMatchPatch.diff_cleanupSemantic(oDifferences);\r\n\r\n\t\t// Cleanup character blanks.\r\n\t\toDiffMatchPatch.diff_cleanupBlankValuesCharacters(oDifferences);\r\n\r\n\t\t// Return the differences.\r\n\t\treturn oDifferences;\r\n\t};\r\n\r\n\t/**\r\n\t * Converts text comparisons to modifications.\r\n\t * @param {object} oComparisons - The comparisons.\r\n\t */\r\n\tTextCompare.prototype.convertTextComparisonsToModifications = function (oComparisons) {\r\n\r\n\t\t// Outline the modifications to be returned.\r\n\t\tvar oModifications = [];\r\n\r\n\t\t// Loop through each of the comparisons and convert these to modifications.\r\n\t\tfor (var i = 0; i < oComparisons.length; i++) {\r\n\t\t\toModifications.push(new g_oTextCompare.textModification(oComparisons[i]));\r\n\t\t}\r\n\r\n\t\t// Return the modifications list.\r\n\t\treturn oModifications;\r\n\t};\r\n\r\n\t/**\r\n\t * Converts text modifications to differences.\r\n\t * @param {object} oModifications - The modifications.\r\n\t */\r\n\tTextCompare.prototype.convertTextModificationsToDifferences = function (oModifications) {\r\n\r\n\t\t// Keep track of the difference order.\r\n\t\tvar iDifferenceOrder = 0;\r\n\r\n\t\t// Outline the differences to be returned.\r\n\t\tvar oDifferences = [];\r\n\r\n\t\t// Loop through each of the modifications.\r\n\t\tfor (var i = 0; i < oModifications.length; i++) {\r\n\r\n\t\t\t// If this is a no difference section, skip.\r\n\t\t\tif (oModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.NoDifference) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Increment the difference number.\r\n\t\t\tg_oTextCompare.g_iNumberOfDifferences++;\r\n\r\n\t\t\t// Increment the difference order.\r\n\t\t\tiDifferenceOrder++;\r\n\r\n\t\t\t// If this is a deletion followed by an addition, this is a substitution.\r\n\t\t\tif (oModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Deletion && (i + 1) < oModifications.length && oModifications[i + 1].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Addition) {\r\n\r\n\t\t\t\t// Add the difference as a substitution.\r\n\t\t\t\toDifferences.push(new g_oTextCompare.textDifference([oModifications[i].g_szModificationText, oModifications[i + 1].g_szModificationText], g_oTextCompare.eDifferenceTypes.Substitution, g_oTextCompare.g_iNumberOfDifferences, iDifferenceOrder));\r\n\r\n\t\t\t\t// Skip the next modification as this is included in the substitution.\r\n\t\t\t\ti++;\r\n\t\t\t}\r\n\t\t\t// If this is a deletion.\r\n\t\t\telse if (oModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Deletion) {\r\n\r\n\t\t\t\t// Add the difference as a deletion.\r\n\t\t\t\toDifferences.push(new g_oTextCompare.textDifference([oModifications[i].g_szModificationText], g_oTextCompare.eDifferenceTypes.Deletion, g_oTextCompare.g_iNumberOfDifferences, iDifferenceOrder));\r\n\t\t\t}\r\n\t\t\t// If this is an addition.\r\n\t\t\telse if (oModifications[i].g_eDifferenceType == g_oTextCompare.eDifferenceTypes.Addition) {\r\n\r\n\t\t\t\t// Add the difference as an addition.\r\n\t\t\t\toDifferences.push(new g_oTextCompare.textDifference([oModifications[i].g_szModificationText], g_oTextCompare.eDifferenceTypes.Addition, g_oTextCompare.g_iNumberOfDifferences, iDifferenceOrder));\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the differences.\r\n\t\treturn oDifferences;\r\n\t};\r\n\r\n\t/**\r\n\t * Combines the text selections.\r\n\t * @param {object} oTextSelections - The text selections.\r\n\t */\r\n\tTextCompare.prototype.combineTextSelections = function (oTextSelections) {\r\n\r\n\t\t// Keep track of the combined text.\r\n\t\tvar szCombinedText = \"\";\r\n\r\n\t\t// Loop through and each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelections.length; i++) {\r\n\r\n\t\t\t// If this is not the first selection text, add a space.\r\n\t\t\tif (i > 0) {\r\n\t\t\t\tszCombinedText += \" \";\r\n\t\t\t}\r\n\r\n\t\t\t// Add the selection text.\r\n\t\t\tszCombinedText += g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word ? oTextSelections[i].g_oSelectionWordsText : oTextSelections[i].g_oSelectionCharactersText;\r\n\t\t}\r\n\r\n\t\t// Return the combined text.\r\n\t\treturn szCombinedText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text selection words.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.getTextSelectionWords = function (oTextData, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the selection words.\r\n\t\tvar oWords = g_oTextTools.getSectionsWords(oTextData, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Sort the words.\r\n\t\toWords = oWords.sort(g_oTextTools.sortWords);\r\n\r\n\t\t// Remove the duplicates.\r\n\t\toWords = g_oTextTools.distinctWords(oWords);\r\n\r\n\t\t// Convert these to selection words.\r\n\t\tvar oSelectionWords = [];\r\n\t\tfor (var i = 0; i < oWords.length; i++) {\r\n\t\t\toSelectionWords.push(new g_oTextCompare.textSelectionWord(oWords[i], oArtworkCanvas, oAnnotationCanvas));\r\n\t\t}\r\n\r\n\t\t// Return the list of selection words.\r\n\t\treturn oSelectionWords;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the text selection characters.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.getTextSelectionCharacters = function (oTextData, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the selection characters.\r\n\t\tvar oCharacters = g_oTextTools.getSectionsCharacters(oTextData, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Sort the characters.\r\n\t\toCharacters = oCharacters.sort(g_oTextTools.sortCharacters);\r\n\r\n\t\t// Remove the duplicates.\r\n\t\toCharacters = g_oTextTools.distinctCharacters(oCharacters);\r\n\r\n\t\t// Convert these to selection characters.\r\n\t\tvar oSelectionCharacters = [];\r\n\t\tfor (var i = 0; i < oCharacters.length; i++) {\r\n\t\t\toSelectionCharacters.push(new g_oTextCompare.textSelectionCharacter(oCharacters[i], oArtworkCanvas, oAnnotationCanvas));\r\n\t\t}\r\n\r\n\t\t// Return the list of selection characters.\r\n\t\treturn oSelectionCharacters;\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the difference status.\r\n\t * @param {int} iDifferenceNumber - The difference number.\r\n\t */\r\n\tTextCompare.prototype.updateDifferenceStatus = function (iDifferenceNumber) {\r\n\r\n\t\t// Get the new value for the difference.\r\n\t\tvar eDifferenceStatus = parseInt($(\"#selDifferenceStatus_\" + iDifferenceNumber).val());\r\n\r\n\t\t// Update the difference status for both canvas.\r\n\t\tg_oTextCompare.updateDifferenceStatusValue(iDifferenceNumber, eDifferenceStatus, false);\r\n\t\tg_oTextCompare.updateDifferenceStatusValue(iDifferenceNumber, eDifferenceStatus, true);\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the step difference status.\r\n\t */\r\n\tTextCompare.prototype.updateStepDifferenceStatus = function () {\r\n\r\n\t\t// Get the new value for the difference.\r\n\t\tvar eDifferenceStatus = parseInt($(\"#selTextDifferenceStatus\").val());\r\n\r\n\t\t// Get the difference number from the step through.\r\n\t\tvar iDifferenceNumber = g_oTextCompare.g_iStepThroughDifference;\r\n\r\n\t\t// Update the difference status for both canvas.\r\n\t\tg_oTextCompare.updateDifferenceStatusValue(iDifferenceNumber, eDifferenceStatus, false);\r\n\t\tg_oTextCompare.updateDifferenceStatusValue(iDifferenceNumber, eDifferenceStatus, true);\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the difference status value.\r\n\t * @param {int} iDifferenceNumber - The difference number.\r\n\t * @param {int} eDifferenceStatus - The difference status.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.updateDifferenceStatusValue = function (iDifferenceNumber, eDifferenceStatus, bCompare) {\r\n\r\n\t\t// Get the text selections.\r\n\t\tvar oTextSelections = g_oTextCompare.getTextSelectionGroup(bCompare);\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelections.length; i++) {\r\n\r\n\t\t\t// Loop through each of the differences.\r\n\t\t\tfor (var j = 0; j < oTextSelections[i].g_oTextDifferences.length; j++) {\r\n\r\n\t\t\t\t// If this is the difference to update.\r\n\t\t\t\tif (oTextSelections[i].g_oTextDifferences[j].g_iDifferenceNumber == iDifferenceNumber) {\r\n\r\n\t\t\t\t\t// Update the status and stop.\r\n\t\t\t\t\toTextSelections[i].g_oTextDifferences[j].g_iDifferenceStatus = eDifferenceStatus;\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Generates the formatted text difference.\r\n\t * @param {object} oApprovalSectionGroup - The approval selection group.\r\n\t * @param {object} oCompareSectionGroup - The compare selection group.\r\n\t * @param {object} oDifferences - The differences.\r\n\t */\r\n\tTextCompare.prototype.generateFormattedDifferenceText = function (oApprovalSectionGroup, oCompareSectionGroup, oDifferences) {\r\n\r\n\t\t// Loop through each of the differences.\r\n\t\tfor (var i = 0; i < oDifferences.length; i++) {\r\n\r\n\t\t\t// Generate the formatted difference text based on the difference type.\r\n\t\t\tswitch (oDifferences[i].g_eDifferenceType) {\r\n\t\t\t\tcase g_oTextCompare.eDifferenceTypes.Addition:\r\n\t\t\t\t\toDifferences[i].g_oFormattedDifferenceText = [g_oTextCompare.getFormattedTextForDifference(oDifferences[i].g_iDifferenceOrder, oApprovalSectionGroup)];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase g_oTextCompare.eDifferenceTypes.Deletion:\r\n\t\t\t\t\toDifferences[i].g_oFormattedDifferenceText = [g_oTextCompare.getFormattedTextForDifference(oDifferences[i].g_iDifferenceOrder, oCompareSectionGroup)];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase g_oTextCompare.eDifferenceTypes.Substitution:\r\n\t\t\t\tcase g_oTextCompare.eDifferenceTypes.WeightSubstitution:\r\n\t\t\t\tcase g_oTextCompare.eDifferenceTypes.StyleSubstitution:\r\n\t\t\t\tcase g_oTextCompare.eDifferenceTypes.WeightStyleSubstitution:\r\n\t\t\t\t\toDifferences[i].g_oFormattedDifferenceText = [g_oTextCompare.getFormattedTextForDifference(oDifferences[i].g_iDifferenceOrder, oCompareSectionGroup), g_oTextCompare.getFormattedTextForDifference(oDifferences[i].g_iDifferenceOrder, oApprovalSectionGroup)];\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// Ensure we have been able to extract the formatted difference text.\r\n\t\t\tif (oDifferences[i].g_oFormattedDifferenceText[0] == \"\") {\r\n\t\t\t\toDifferences[i].g_oFormattedDifferenceText[0] = oDifferences[i].g_oDifferenceText[0];\r\n\t\t\t}\r\n\r\n\t\t\t// Ensure we have been able to extract the formatted substitution text if required.\r\n\t\t\tif (oDifferences[i].g_oFormattedDifferenceText[1] == \"\") {\r\n\t\t\t\toDifferences[i].g_oFormattedDifferenceText[1] = oDifferences[i].g_oDifferenceText[1];\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the formatted text for a difference.\r\n\t * @param {int} iDifference - The difference.\r\n\t * @param {object} oSectionGroup - The selection group.\r\n\t */\r\n\tTextCompare.prototype.getFormattedTextForDifference = function (iDifference, oSectionGroup) {\r\n\r\n\t\t// Get the text for the difference based on the accuracy.\r\n\t\treturn g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word ? g_oTextCompare.getFormattedTextForDifference_Words(iDifference, oSectionGroup) : g_oTextCompare.getFormattedTextForDifference_Characters(iDifference, oSectionGroup);\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the formatted text for a difference at word level.\r\n\t * @param {int} iDifference - The difference.\r\n\t * @param {object} oSectionGroup - The selection group.\r\n\t */\r\n\tTextCompare.prototype.getFormattedTextForDifference_Words = function (iDifference, oSectionGroup) {\r\n\r\n\t\t// Outline the difference text to be returned.\r\n\t\tvar szDifferenceText = \"\";\r\n\r\n\t\t// Loop through each of the words in the selection.\r\n\t\tfor (var i = 0; i < oSectionGroup.g_oTextSelections.length; i++) {\r\n\t\t\tfor (var j = 0; j < oSectionGroup.g_oTextSelections[i].g_oSelectionWords.length; j++) {\r\n\r\n\t\t\t\t// Extract the word.\r\n\t\t\t\tvar oWord = oSectionGroup.g_oTextSelections[i].g_oSelectionWords[j];\r\n\r\n\t\t\t\t// If this word is part of the difference.\r\n\t\t\t\tif (oWord.difference == iDifference) {\r\n\r\n\t\t\t\t\t// Add a space if required.\r\n\t\t\t\t\tif (szDifferenceText.length > 0) {\r\n\t\t\t\t\t\tszDifferenceText += \" \";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Outline the text content to be added.\r\n\t\t\t\t\tvar szWordContent = oWord.content;\r\n\r\n\t\t\t\t\t// If we are not showing case sensitivity.\r\n\t\t\t\t\tif (g_oTextCompare.g_iCaseSensitivity == g_oTextCompare.eCaseSensitivityLevels.Off) {\r\n\t\t\t\t\t\tszWordContent = szWordContent.toLowerCase();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// If we are showing bold italic differences, wrap with the appropriate styling.\r\n\t\t\t\t\tif (g_oTextCompare.g_iBoldItalicDetection == g_oTextCompare.eBoldItalicDetectionLevels.On) {\r\n\t\t\t\t\t\tif (oWord.bold) {\r\n\t\t\t\t\t\t\tszWordContent = \"\" + szWordContent + \"\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (oWord.italic) {\r\n\t\t\t\t\t\t\tszWordContent = \"\" + szWordContent + \"\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the word in the correct styling.\r\n\t\t\t\t\tszDifferenceText += szWordContent;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the difference text.\r\n\t\treturn szDifferenceText;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the formatted text for a difference at character level.\r\n\t * @param {int} iDifference - The difference.\r\n\t * @param {object} oSectionGroup - The selection group.\r\n\t */\r\n\tTextCompare.prototype.getFormattedTextForDifference_Characters = function (iDifference, oSectionGroup) {\r\n\r\n\t\t// Outline the difference text to be returned.\r\n\t\tvar szDifferenceText = \"\";\r\n\r\n\t\t// Keep track of if the previous character was the last in the word.\r\n\t\tvar bPreviousCharacterLastInWord = false;\r\n\r\n\t\t// Loop through each of the characters in the selection.\r\n\t\tfor (var i = 0; i < oSectionGroup.g_oTextSelections.length; i++) {\r\n\t\t\tfor (var j = 0; j < oSectionGroup.g_oTextSelections[i].g_oSelectionCharacters.length; j++) {\r\n\r\n\t\t\t\t// Extract the character.\r\n\t\t\t\tvar oCharacter = oSectionGroup.g_oTextSelections[i].g_oSelectionCharacters[j];\r\n\r\n\t\t\t\t// If this character is part of the difference.\r\n\t\t\t\tif (oCharacter.difference == iDifference) {\r\n\r\n\t\t\t\t\t// Add a space if required.\r\n\t\t\t\t\tif (bPreviousCharacterLastInWord) {\r\n\t\t\t\t\t\tszDifferenceText += \" \";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Outline the text content to be added.\r\n\t\t\t\t\tvar szCharacterContent = oCharacter.content;\r\n\r\n\t\t\t\t\t// If we are not showing case sensitivity.\r\n\t\t\t\t\tif (g_oTextCompare.g_iCaseSensitivity == g_oTextCompare.eCaseSensitivityLevels.Off) {\r\n\t\t\t\t\t\tszCharacterContent = szCharacterContent.toLowerCase();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// If we are showing bold italic differences, wrap with the appropriate styling.\r\n\t\t\t\t\tif (g_oTextCompare.g_iBoldItalicDetection == g_oTextCompare.eBoldItalicDetectionLevels.On) {\r\n\t\t\t\t\t\tif (oCharacter.bold) {\r\n\t\t\t\t\t\t\tszCharacterContent = \"\" + szCharacterContent + \"\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tif (oCharacter.italic) {\r\n\t\t\t\t\t\t\tszCharacterContent = \"\" + szCharacterContent + \"\";\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the character in the correct styling.\r\n\t\t\t\t\tszDifferenceText += szCharacterContent;\r\n\r\n\t\t\t\t\t// Determine if this character is the last in the word.\r\n\t\t\t\t\tbPreviousCharacterLastInWord = oCharacter.lastInWord;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the difference text.\r\n\t\treturn szDifferenceText;\r\n\t};\r\n\r\n\t/**\r\n\t * Calculates the bold and italic differences.\r\n\t * @param {object} oApprovalSelections - The approval selections.\r\n\t * @param {object} oCompareSelections - The compare selections.\r\n\t * @param {object} oDifferences - The differences.\r\n\t */\r\n\tTextCompare.prototype.calculateBoldItalicDifferences = function (oApprovalSelections, oCompareSelections, oDifferences) {\r\n\r\n\t\t// If our accuracy is at a word level.\r\n\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\t\t\tg_oTextCompare.calculateWordBoldItalicDifferences(oApprovalSelections, oCompareSelections, oDifferences);\r\n\t\t}\r\n\t\t// If our accuracy is at a character level.\r\n\t\telse {\r\n\t\t\tg_oTextCompare.calculateCharacterBoldItalicDifferences(oApprovalSelections, oCompareSelections, oDifferences);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Calculates the word bold and italic differences.\r\n\t * @param {object} oApprovalSelections - The approval selections.\r\n\t * @param {object} oCompareSelections - The compare selections.\r\n\t * @param {object} oDifferences - The differences.\r\n\t */\r\n\tTextCompare.prototype.calculateWordBoldItalicDifferences = function (oApprovalSelections, oCompareSelections, oDifferences) {\r\n\r\n\t\t// Keep track of the styling changes.\r\n\t\tvar oStylingChanges = [];\r\n\r\n\t\t// Get the words with no differences for each selection.\r\n\t\tvar oApprovalNoDifferenceWords = g_oTextCompare.getWordsWithNoDifferences(oApprovalSelections);\r\n\t\tvar oCompareNoDifferenceWords = g_oTextCompare.getWordsWithNoDifferences(oCompareSelections);\r\n\r\n\t\t// Loop through each of the words that have no differences.\r\n\t\tfor (var i = 0; i < oApprovalNoDifferenceWords.length; i++) {\r\n\r\n\t\t\t// Ensure we have words with no differences on both sides.\r\n\t\t\tif (oApprovalNoDifferenceWords[i] == undefined || oCompareNoDifferenceWords[i] == undefined) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// If this word has a difference in styling.\r\n\t\t\tif (oApprovalNoDifferenceWords[i].bold != oCompareNoDifferenceWords[i].bold || oApprovalNoDifferenceWords[i].italic != oCompareNoDifferenceWords[i].italic) {\r\n\r\n\t\t\t\t// Determine the substitution type.\r\n\t\t\t\tvar eSubstitutionType = g_oTextCompare.determineBoldItalicSubstitutionType(oApprovalNoDifferenceWords[i].bold != oCompareNoDifferenceWords[i].bold, oApprovalNoDifferenceWords[i].italic != oCompareNoDifferenceWords[i].italic);\r\n\r\n\t\t\t\t// If this styling change can be grouped with the previous styling change.\r\n\t\t\t\t// - We have at least one previous styling change.\r\n\t\t\t\t// - The substitution type is the same.\r\n\t\t\t\t// - The approval word follows directly after the previous approval word.\r\n\t\t\t\t// - The compare word follows directly after the previous compare word.\r\n\t\t\t\tif (oStylingChanges.length > 0 && oStylingChanges[oStylingChanges.length - 1].type == eSubstitutionType &&\r\n\t\t\t\t\toStylingChanges[oStylingChanges.length - 1].approvalWords[oStylingChanges[oStylingChanges.length - 1].approvalWords.length - 1].order + 1 == oApprovalNoDifferenceWords[i].words[0].order &&\r\n\t\t\t\t\toStylingChanges[oStylingChanges.length - 1].compareWords[oStylingChanges[oStylingChanges.length - 1].compareWords.length - 1].order + 1 == oCompareNoDifferenceWords[i].words[0].order) {\r\n\r\n\t\t\t\t\t// Add the approval words to the previous styling change.\r\n\t\t\t\t\tfor (var j = 0; j < oApprovalNoDifferenceWords[i].words.length; j++) {\r\n\t\t\t\t\t\toStylingChanges[oStylingChanges.length - 1].approvalWords.push(oApprovalNoDifferenceWords[i].words[j]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the compare words to the previous styling change.\r\n\t\t\t\t\tfor (var j = 0; j < oCompareNoDifferenceWords[i].words.length; j++) {\r\n\t\t\t\t\t\toStylingChanges[oStylingChanges.length - 1].compareWords.push(oCompareNoDifferenceWords[i].words[j]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Continue now we have grouped with the previous styling change.\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Create the styling change.\r\n\t\t\t\toStylingChanges.push({\r\n\t\t\t\t\tapprovalWords: oApprovalNoDifferenceWords[i].words,\r\n\t\t\t\t\tcompareWords: oCompareNoDifferenceWords[i].words,\r\n\t\t\t\t\ttype: eSubstitutionType,\r\n\t\t\t\t\tpreviousDifference: oApprovalNoDifferenceWords[i].previousDifference\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Loop through each of the styling changes.\r\n\t\tfor (var i = 0; i < oStylingChanges.length; i++) {\r\n\r\n\t\t\t// Get the difference order and number to be used for the styling difference.\r\n\t\t\t// The order is the previous difference, plus one as we want to be after this difference, plus the number of differences we have already inserted.\r\n\t\t\tvar iDifferenceOrder = oStylingChanges[i].previousDifference + 1 + i;\r\n\t\t\tvar iDifferenceNumber = g_oTextCompare.getDifferenceNumberFromOrder(iDifferenceOrder, oDifferences);\r\n\r\n\t\t\t// Create a gap for the new styling difference.\r\n\t\t\tg_oTextCompare.createGapForDifference(iDifferenceNumber, iDifferenceOrder, oDifferences);\r\n\t\t\tg_oTextCompare.createWordGapForDifference(iDifferenceNumber, iDifferenceOrder, oApprovalSelections);\r\n\t\t\tg_oTextCompare.createWordGapForDifference(iDifferenceNumber, iDifferenceOrder, oCompareSelections);\r\n\r\n\t\t\t// Build the content for the styling change.\r\n\t\t\tvar oApprovalStylingChangeContent = \"\";\r\n\t\t\tvar oCompareStylingChangeContent = \"\";\r\n\r\n\t\t\t// Loop through each of the approval words for the styling change.\r\n\t\t\tfor (var j = 0; j < oStylingChanges[i].approvalWords.length; j++) {\r\n\r\n\t\t\t\t// Extract the approval word.\r\n\t\t\t\tvar oApprovalNoDifferenceWord = oApprovalSelections[oStylingChanges[i].approvalWords[j].selection].g_oSelectionWords[oStylingChanges[i].approvalWords[j].word];\r\n\r\n\t\t\t\t// Add the word content.\r\n\t\t\t\toApprovalStylingChangeContent += oApprovalNoDifferenceWord.content;\r\n\r\n\t\t\t\t// Update the difference and status of the word.\r\n\t\t\t\toApprovalNoDifferenceWord.difference = iDifferenceOrder;\r\n\t\t\t\toApprovalNoDifferenceWord.status = g_oTextCompare.eDifferenceTypes.Addition;\r\n\r\n\t\t\t\t// Add a space if required.\r\n\t\t\t\tif (j + 1 < oStylingChanges[i].approvalWords.length) {\r\n\t\t\t\t\toApprovalStylingChangeContent += \" \";\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the compare words for the styling change.\r\n\t\t\tfor (var j = 0; j < oStylingChanges[i].compareWords.length; j++) {\r\n\r\n\t\t\t\t// Extract the compare word.\r\n\t\t\t\tvar oCompareNoDifferenceWord = oCompareSelections[oStylingChanges[i].compareWords[j].selection].g_oSelectionWords[oStylingChanges[i].compareWords[j].word];\r\n\r\n\t\t\t\t// Add the word content.\r\n\t\t\t\toCompareStylingChangeContent += oCompareNoDifferenceWord.content;\r\n\r\n\t\t\t\t// Update the difference and status of the word.\r\n\t\t\t\toCompareNoDifferenceWord.difference = iDifferenceOrder;\r\n\t\t\t\toCompareNoDifferenceWord.status = g_oTextCompare.eDifferenceTypes.Deletion;\r\n\r\n\t\t\t\t// Add a space if required.\r\n\t\t\t\tif (j + 1 < oStylingChanges[i].compareWords.length) {\r\n\t\t\t\t\toCompareStylingChangeContent += \" \";\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Add the styling difference in the correct spot.\r\n\t\t\toDifferences.splice(iDifferenceOrder - 1, 0, new g_oTextCompare.textDifference([oCompareStylingChangeContent, oApprovalStylingChangeContent], oStylingChanges[i].type, iDifferenceNumber, iDifferenceOrder));\r\n\r\n\t\t\t// Increment the number of differences.\r\n\t\t\tg_oTextCompare.g_iNumberOfDifferences++;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Calculates the character bold and italic differences.\r\n\t * @param {object} oApprovalSelections - The approval selections.\r\n\t * @param {object} oCompareSelections - The compare selections.\r\n\t * @param {object} oDifferences - The differences.\r\n\t */\r\n\tTextCompare.prototype.calculateCharacterBoldItalicDifferences = function (oApprovalSelections, oCompareSelections, oDifferences) {\r\n\r\n\t\t// Keep track of the styling changes.\r\n\t\tvar oStylingChanges = [];\r\n\r\n\t\t// Get the characters with no differences for each selection.\r\n\t\tvar oApprovalNoDifferenceCharacters = g_oTextCompare.getCharactersWithNoDifferences(oApprovalSelections);\r\n\t\tvar oCompareNoDifferenceCharacters = g_oTextCompare.getCharactersWithNoDifferences(oCompareSelections);\r\n\r\n\t\t// Loop through each of the characters that have no differences.\r\n\t\tfor (var i = 0; i < oApprovalNoDifferenceCharacters.length; i++) {\r\n\r\n\t\t\t// Ensure we have characters with no differences on both sides.\r\n\t\t\tif (oApprovalNoDifferenceCharacters[i] == undefined || oCompareNoDifferenceCharacters[i] == undefined) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// If this character has a difference in styling.\r\n\t\t\tif (oApprovalNoDifferenceCharacters[i].bold != oCompareNoDifferenceCharacters[i].bold || oApprovalNoDifferenceCharacters[i].italic != oCompareNoDifferenceCharacters[i].italic) {\r\n\r\n\t\t\t\t// Determine the substitution type.\r\n\t\t\t\tvar eSubstitutionType = g_oTextCompare.determineBoldItalicSubstitutionType(oApprovalNoDifferenceCharacters[i].bold != oCompareNoDifferenceCharacters[i].bold, oApprovalNoDifferenceCharacters[i].italic != oCompareNoDifferenceCharacters[i].italic);\r\n\r\n\t\t\t\t// If this styling change can be grouped with the previous styling change.\r\n\t\t\t\t// - We have at least one previous styling change.\r\n\t\t\t\t// - The substitution type is the same.\r\n\t\t\t\t// - The approval character follows directly after the previous approval character.\r\n\t\t\t\t// - The compare character follows directly after the previous compare character.\r\n\t\t\t\tif (oStylingChanges.length > 0 && oStylingChanges[oStylingChanges.length - 1].type == eSubstitutionType &&\r\n\t\t\t\t\toStylingChanges[oStylingChanges.length - 1].approvalCharacters[oStylingChanges[oStylingChanges.length - 1].approvalCharacters.length - 1].order + 1 == oApprovalNoDifferenceCharacters[i].characters[0].order &&\r\n\t\t\t\t\toStylingChanges[oStylingChanges.length - 1].compareCharacters[oStylingChanges[oStylingChanges.length - 1].compareCharacters.length - 1].order + 1 == oCompareNoDifferenceCharacters[i].characters[0].order) {\r\n\r\n\t\t\t\t\t// Add the approval characters to the previous styling change.\r\n\t\t\t\t\tfor (var j = 0; j < oApprovalNoDifferenceCharacters[i].characters.length; j++) {\r\n\t\t\t\t\t\toStylingChanges[oStylingChanges.length - 1].approvalCharacters.push(oApprovalNoDifferenceCharacters[i].characters[j]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the compare characters to the previous styling change.\r\n\t\t\t\t\tfor (var j = 0; j < oCompareNoDifferenceCharacters[i].characters.length; j++) {\r\n\t\t\t\t\t\toStylingChanges[oStylingChanges.length - 1].compareCharacters.push(oCompareNoDifferenceCharacters[i].characters[j]);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Continue now we have grouped with the previous styling change.\r\n\t\t\t\t\tcontinue;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Create the styling change.\r\n\t\t\t\toStylingChanges.push({\r\n\t\t\t\t\tapprovalCharacters: oApprovalNoDifferenceCharacters[i].characters,\r\n\t\t\t\t\tcompareCharacters: oCompareNoDifferenceCharacters[i].characters,\r\n\t\t\t\t\ttype: eSubstitutionType,\r\n\t\t\t\t\tpreviousDifference: oApprovalNoDifferenceCharacters[i].previousDifference\r\n\t\t\t\t});\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Loop through each of the styling changes.\r\n\t\tfor (var i = 0; i < oStylingChanges.length; i++) {\r\n\r\n\t\t\t// Get the difference order and number to be used for the styling difference.\r\n\t\t\t// The order is the previous difference, plus one as we want to be after this difference, plus the number of differences we have already inserted.\r\n\t\t\tvar iDifferenceOrder = oStylingChanges[i].previousDifference + 1 + i;\r\n\t\t\tvar iDifferenceNumber = g_oTextCompare.getDifferenceNumberFromOrder(iDifferenceOrder, oDifferences);\r\n\r\n\t\t\t// Create a gap for the new styling difference.\r\n\t\t\tg_oTextCompare.createGapForDifference(iDifferenceNumber, iDifferenceOrder, oDifferences);\r\n\t\t\tg_oTextCompare.createCharacterGapForDifference(iDifferenceNumber, iDifferenceOrder, oApprovalSelections);\r\n\t\t\tg_oTextCompare.createCharacterGapForDifference(iDifferenceNumber, iDifferenceOrder, oCompareSelections);\r\n\r\n\t\t\t// Build the content for the styling change.\r\n\t\t\tvar oApprovalStylingChangeContent = \"\";\r\n\t\t\tvar oCompareStylingChangeContent = \"\";\r\n\r\n\t\t\t// Loop through each of the approval characters for the styling change.\r\n\t\t\tfor (var j = 0; j < oStylingChanges[i].approvalCharacters.length; j++) {\r\n\r\n\t\t\t\t// Extract the approval character.\r\n\t\t\t\tvar oApprovalNoDifferenceCharacter = oApprovalSelections[oStylingChanges[i].approvalCharacters[j].selection].g_oSelectionCharacters[oStylingChanges[i].approvalCharacters[j].character];\r\n\r\n\t\t\t\t// Add the character content.\r\n\t\t\t\toApprovalStylingChangeContent += oApprovalNoDifferenceCharacter.content;\r\n\r\n\t\t\t\t// Update the difference and status of the character.\r\n\t\t\t\toApprovalNoDifferenceCharacter.difference = iDifferenceOrder;\r\n\t\t\t\toApprovalNoDifferenceCharacter.status = g_oTextCompare.eDifferenceTypes.Addition;\r\n\r\n\t\t\t\t// Add a space if required.\r\n\t\t\t\tif (oStylingChanges[i].approvalCharacters[j].lastCharacterInWord && j + 1 < oStylingChanges[i].approvalCharacters.length) {\r\n\t\t\t\t\toApprovalStylingChangeContent += \" \";\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the compare characters for the styling change.\r\n\t\t\tfor (var j = 0; j < oStylingChanges[i].compareCharacters.length; j++) {\r\n\r\n\t\t\t\t// Extract the compare character.\r\n\t\t\t\tvar oCompareNoDifferenceCharacter = oCompareSelections[oStylingChanges[i].compareCharacters[j].selection].g_oSelectionCharacters[oStylingChanges[i].compareCharacters[j].character];\r\n\r\n\t\t\t\t// Add the character content.\r\n\t\t\t\toCompareStylingChangeContent += oCompareNoDifferenceCharacter.content;\r\n\r\n\t\t\t\t// Update the difference and status of the character.\r\n\t\t\t\toCompareNoDifferenceCharacter.difference = iDifferenceOrder;\r\n\t\t\t\toCompareNoDifferenceCharacter.status = g_oTextCompare.eDifferenceTypes.Deletion;\r\n\r\n\t\t\t\t// Add a space if required.\r\n\t\t\t\tif (oStylingChanges[i].compareCharacters[j].lastCharacterInWord && j + 1 < oStylingChanges[i].compareCharacters.length) {\r\n\t\t\t\t\toCompareStylingChangeContent += \" \";\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Add the styling difference in the correct spot.\r\n\t\t\toDifferences.splice(iDifferenceOrder - 1, 0, new g_oTextCompare.textDifference([oCompareStylingChangeContent, oApprovalStylingChangeContent], oStylingChanges[i].type, iDifferenceNumber, iDifferenceOrder));\r\n\r\n\t\t\t// Increment the number of differences.\r\n\t\t\tg_oTextCompare.g_iNumberOfDifferences++;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Gets a list of words with no differences.\r\n\t * @param {object} oSelectionGroups - The selections.\r\n\t */\r\n\tTextCompare.prototype.getWordsWithNoDifferences = function (oSelectionGroups) {\r\n\r\n\t\t// Outline the no difference text to be returned.\r\n\t\tvar oNoDifferenceWords = [];\r\n\r\n\t\t// Keep track of the word we are on and the previous difference.\r\n\t\tvar iCurrentWord = 0;\r\n\t\tvar iPreviousDifference = 0;\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oSelectionGroups.length; i++) {\r\n\r\n\t\t\t// Loop through each of the words in the selection.\r\n\t\t\tfor (var j = 0; j < oSelectionGroups[i].g_oSelectionWords.length; j++) {\r\n\r\n\t\t\t\t// If this word has a difference, set the previous difference number and order.\r\n\t\t\t\tiPreviousDifference = Math.max(oSelectionGroups[i].g_oSelectionWords[j].difference, oSelectionGroups[i].g_oSelectionWords[j].markerDifference, iPreviousDifference);\r\n\r\n\t\t\t\t// If this word has no differences, add it to the list.\r\n\t\t\t\tif (oSelectionGroups[i].g_oSelectionWords[j].difference == -1) {\r\n\r\n\t\t\t\t\t// If this is an equivalent word and should be grouped with the previous equivalent word:\r\n\t\t\t\t\t// - This word is part of an equivalent.\r\n\t\t\t\t\t// - The previous no difference word is part of an equivalent.\r\n\t\t\t\t\t// - This word is directly after the previous character.\r\n\t\t\t\t\tif (oSelectionGroups[i].g_oSelectionWords[j].equivalentDifference && oNoDifferenceWords.length > 0 && oNoDifferenceWords[oNoDifferenceWords.length - 1].equivalentDifference && iCurrentWord == oNoDifferenceWords[oNoDifferenceWords.length - 1].words[oNoDifferenceWords[oNoDifferenceWords.length - 1].words.length - 1].order + 1) {\r\n\r\n\t\t\t\t\t\t// Combine this equivalent word with the previous equivalent word.\r\n\t\t\t\t\t\toNoDifferenceWords[oNoDifferenceWords.length - 1].words.push({\r\n\t\t\t\t\t\t\tselection: i,\r\n\t\t\t\t\t\t\tword: j,\r\n\t\t\t\t\t\t\torder: iCurrentWord,\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t// Update the bold italic flags.\r\n\t\t\t\t\t\toNoDifferenceWords[oNoDifferenceWords.length - 1].bold = (oNoDifferenceWords[oNoDifferenceWords.length - 1].bold || oSelectionGroups[i].g_oSelectionWords[j].bold);\r\n\t\t\t\t\t\toNoDifferenceWords[oNoDifferenceWords.length - 1].italic = (oNoDifferenceWords[oNoDifferenceWords.length - 1].italic || oSelectionGroups[i].g_oSelectionWords[j].italic);\r\n\r\n\t\t\t\t\t\t// Increment the current word tracker and continue.\r\n\t\t\t\t\t\tiCurrentWord++;\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the word to the list.\r\n\t\t\t\t\toNoDifferenceWords.push({\r\n\t\t\t\t\t\twords: [{\r\n\t\t\t\t\t\t\tselection: i,\r\n\t\t\t\t\t\t\tword: j,\r\n\t\t\t\t\t\t\torder: iCurrentWord\r\n\t\t\t\t\t\t}],\r\n\t\t\t\t\t\tpreviousDifference: iPreviousDifference,\r\n\t\t\t\t\t\tequivalentDifference: oSelectionGroups[i].g_oSelectionWords[j].equivalentDifference,\r\n\t\t\t\t\t\tbold: oSelectionGroups[i].g_oSelectionWords[j].bold,\r\n\t\t\t\t\t\titalic: oSelectionGroups[i].g_oSelectionWords[j].italic\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Increment the current word tracker.\r\n\t\t\t\tiCurrentWord++;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the words with no differences.\r\n\t\treturn oNoDifferenceWords;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets a list of characters with no differences.\r\n\t * @param {object} oSelectionGroups - The selections.\r\n\t */\r\n\tTextCompare.prototype.getCharactersWithNoDifferences = function (oSelectionGroups) {\r\n\r\n\t\t// Outline the no difference text to be returned.\r\n\t\tvar oNoDifferenceCharacters = [];\r\n\r\n\t\t// Keep track of the character we are on and the previous difference.\r\n\t\tvar iCurrentCharacter = 0;\r\n\t\tvar iPreviousDifference = 0;\r\n\t\tvar bLastCharacterInWord = false;\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oSelectionGroups.length; i++) {\r\n\r\n\t\t\t// Loop through each of the characters in the selection.\r\n\t\t\tfor (var j = 0; j < oSelectionGroups[i].g_oSelectionCharacters.length; j++) {\r\n\r\n\t\t\t\t// If this character has a difference, set the previous difference number and order.\r\n\t\t\t\tiPreviousDifference = Math.max(oSelectionGroups[i].g_oSelectionCharacters[j].difference, oSelectionGroups[i].g_oSelectionCharacters[j].markerDifference, iPreviousDifference);\r\n\r\n\t\t\t\t// If this character has a difference, set the previous difference number and order.\r\n\t\t\t\tiPreviousDifference = Math.max(oSelectionGroups[i].g_oSelectionCharacters[j].difference, oSelectionGroups[i].g_oSelectionCharacters[j].markerDifference, iPreviousDifference);\r\n\r\n\t\t\t\t// Check if this is the last character in the word.\r\n\t\t\t\tbLastCharacterInWord = oSelectionGroups[i].g_oSelectionCharacters[j].lastInWord;\r\n\r\n\t\t\t\t// If this character has no differences, add it to the list.\r\n\t\t\t\tif (oSelectionGroups[i].g_oSelectionCharacters[j].difference == -1) {\r\n\r\n\t\t\t\t\t// If this is an equivalent character and should be grouped with the previous equivalent character:\r\n\t\t\t\t\t// - This character is part of an equivalent.\r\n\t\t\t\t\t// - The previous no difference character is part of an equivalent.\r\n\t\t\t\t\t// - This character is directly after the previous character.\r\n\t\t\t\t\tif (oSelectionGroups[i].g_oSelectionCharacters[j].equivalentDifference && oNoDifferenceCharacters.length > 0 && oNoDifferenceCharacters[oNoDifferenceCharacters.length - 1].equivalentDifference && iCurrentCharacter == oNoDifferenceCharacters[oNoDifferenceCharacters.length - 1].characters[oNoDifferenceCharacters[oNoDifferenceCharacters.length - 1].characters.length - 1].order + 1) {\r\n\r\n\t\t\t\t\t\t// Combine this equivalent character with the previous equivalent character.\r\n\t\t\t\t\t\toNoDifferenceCharacters[oNoDifferenceCharacters.length - 1].characters.push({\r\n\t\t\t\t\t\t\tselection: i,\r\n\t\t\t\t\t\t\tcharacter: j,\r\n\t\t\t\t\t\t\torder: iCurrentCharacter,\r\n\t\t\t\t\t\t\tlastCharacterInWord: bLastCharacterInWord\r\n\t\t\t\t\t\t});\r\n\r\n\t\t\t\t\t\t// Update the bold italic flags.\r\n\t\t\t\t\t\toNoDifferenceCharacters[oNoDifferenceCharacters.length - 1].bold = (oNoDifferenceCharacters[oNoDifferenceCharacters.length - 1].bold || oSelectionGroups[i].g_oSelectionCharacters[j].bold);\r\n\t\t\t\t\t\toNoDifferenceCharacters[oNoDifferenceCharacters.length - 1].italic = (oNoDifferenceCharacters[oNoDifferenceCharacters.length - 1].italic || oSelectionGroups[i].g_oSelectionCharacters[j].italic);\r\n\r\n\t\t\t\t\t\t// Increment the current character tracker and continue.\r\n\t\t\t\t\t\tiCurrentCharacter++;\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the character to the list.\r\n\t\t\t\t\toNoDifferenceCharacters.push({\r\n\t\t\t\t\t\tcharacters: [{\r\n\t\t\t\t\t\t\tselection: i,\r\n\t\t\t\t\t\t\tcharacter: j,\r\n\t\t\t\t\t\t\torder: iCurrentCharacter,\r\n\t\t\t\t\t\t\tlastCharacterInWord: bLastCharacterInWord\r\n\t\t\t\t\t\t}],\r\n\t\t\t\t\t\tpreviousDifference: iPreviousDifference,\r\n\t\t\t\t\t\tequivalentDifference: oSelectionGroups[i].g_oSelectionCharacters[j].equivalentDifference,\r\n\t\t\t\t\t\tbold: oSelectionGroups[i].g_oSelectionCharacters[j].bold,\r\n\t\t\t\t\t\titalic: oSelectionGroups[i].g_oSelectionCharacters[j].italic\r\n\t\t\t\t\t});\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// Increment the current character tracker.\r\n\t\t\t\tiCurrentCharacter++;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the characters with no differences.\r\n\t\treturn oNoDifferenceCharacters;\r\n\t};\r\n\r\n\t/**\r\n\t * Gets the difference number from an order.\r\n\t * @param {int} iDifferenceOrder - The difference order.\r\n\t * @param {object} oDifferences - The differences.\r\n\t */\r\n\tTextCompare.prototype.getDifferenceNumberFromOrder = function (iDifferenceOrder, oDifferences) {\r\n\t\treturn iDifferenceOrder - 1 > oDifferences.length - 1 ? g_oTextCompare.g_iNumberOfDifferences + 1 : oDifferences[iDifferenceOrder - 1].g_iDifferenceNumber;\r\n\t};\r\n\r\n\t/**\r\n\t * Creates a gap for a difference.\r\n\t * @param {int} iDifferenceNumber - The difference number.\r\n\t * @param {int} iDifferenceOrder - The difference order.\r\n\t * @param {object} oDifferences - The differences.\r\n\t */\r\n\tTextCompare.prototype.createGapForDifference = function (iDifferenceNumber, iDifferenceOrder, oDifferences) {\r\n\r\n\t\t// Create a gap in the difference order and number.\r\n\t\tfor (var i = 0; i < oDifferences.length; i++) {\r\n\t\t\tif (oDifferences[i].g_iDifferenceNumber >= iDifferenceNumber) {\r\n\t\t\t\toDifferences[i].g_iDifferenceNumber++;\r\n\t\t\t\toDifferences[i].g_iDifferenceOrder++;\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Creates a word gap for a difference.\r\n\t * @param {int} iDifferenceNumber - The difference number.\r\n\t * @param {int} iDifferenceOrder - The difference order.\r\n\t * @param {object} oSelections - The selections.\r\n\t */\r\n\tTextCompare.prototype.createWordGapForDifference = function (iDifferenceNumber, iDifferenceOrder, oSelections) {\r\n\r\n\t\t// Create a gap in the words differences.\r\n\t\tfor (var i = 0; i < oSelections.length; i++) {\r\n\t\t\tfor (var j = 0; j < oSelections[i].g_oSelectionWords.length; j++) {\r\n\t\t\t\tif (oSelections[i].g_oSelectionWords[j].difference >= iDifferenceOrder) {\r\n\t\t\t\t\toSelections[i].g_oSelectionWords[j].difference++\r\n\t\t\t\t}\r\n\t\t\t\tif (oSelections[i].g_oSelectionWords[j].markerDifference >= iDifferenceOrder) {\r\n\t\t\t\t\toSelections[i].g_oSelectionWords[j].markerDifference++\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Creates a character gap for a difference.\r\n\t * @param {int} iDifferenceNumber - The difference number.\r\n\t * @param {int} iDifferenceOrder - The difference order.\r\n\t * @param {object} oSelections - The selections.\r\n\t */\r\n\tTextCompare.prototype.createCharacterGapForDifference = function (iDifferenceNumber, iDifferenceOrder, oSelections) {\r\n\r\n\t\t// Create a gap in the characters differences.\r\n\t\tfor (var i = 0; i < oSelections.length; i++) {\r\n\t\t\tfor (var j = 0; j < oSelections[i].g_oSelectionCharacters.length; j++) {\r\n\t\t\t\tif (oSelections[i].g_oSelectionCharacters[j].difference >= iDifferenceOrder) {\r\n\t\t\t\t\toSelections[i].g_oSelectionCharacters[j].difference++\r\n\t\t\t\t}\r\n\t\t\t\tif (oSelections[i].g_oSelectionCharacters[j].markerDifference >= iDifferenceOrder) {\r\n\t\t\t\t\toSelections[i].g_oSelectionCharacters[j].markerDifference++\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Begins stepping through differences.\r\n\t */\r\n\tTextCompare.prototype.beginStepThroughDifferences = function () {\r\n\r\n\t\t// Check we have calculated differences.\r\n\t\tif (!g_oTextCompare.g_bDifferencesCalculated) {\r\n\t\t\tg_oGreenlightMessages.displayWarningBubble(g_oTextCompare.c_szTextCompareDifferencesNotCalculated);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Step through to the first difference.\r\n\t\tg_oTextCompare.stepThroughToDifference(1);\r\n\t};\r\n\r\n\t/**\r\n\t * Steps to the next difference.\r\n\t */\r\n\tTextCompare.prototype.nextStepThroughDifferences = function () {\r\n\r\n\t\t// If we are not in step through mode, start this.\r\n\t\tif (g_oTextCompare.g_iStepThroughDifference == null) {\r\n\t\t\tg_oTextCompare.beginStepThroughDifferences();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Step through to the next difference.\r\n\t\tg_oTextCompare.stepThroughToDifference(g_oTextCompare.g_iStepThroughDifference + 1 > g_oTextCompare.g_iNumberOfDifferences ? 1 : g_oTextCompare.g_iStepThroughDifference + 1);\r\n\t};\r\n\r\n\t/**\r\n\t * Steps to the previous difference.\r\n\t */\r\n\tTextCompare.prototype.previousStepThroughDifferences = function () {\r\n\r\n\t\t// If we are not in step through mode, start this.\r\n\t\tif (g_oTextCompare.g_iStepThroughDifference == null) {\r\n\t\t\tg_oTextCompare.beginStepThroughDifferences();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Step through to the previous difference.\r\n\t\tg_oTextCompare.stepThroughToDifference(g_oTextCompare.g_iStepThroughDifference - 1 == 0 ? g_oTextCompare.g_iNumberOfDifferences : g_oTextCompare.g_iStepThroughDifference - 1);\r\n\t};\r\n\r\n\t/**\r\n\t * Steps through to a difference.\r\n\t * @param {int} iDifference - The difference.\r\n\t */\r\n\tTextCompare.prototype.stepThroughToDifference = function (iDifference) {\r\n\r\n\t\t// If the review screen is open, close this.\r\n\t\tif (g_oTextCompare.g_bTextCompareDivShown) {\r\n\t\t\tg_oTextCompare.toggleTextCompareDiv();\r\n\t\t}\r\n\r\n\t\t// Step through to the difference.\r\n\t\tg_oTextCompare.g_iStepThroughDifference = iDifference;\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\r\n\t\t// Pan to the difference.\r\n\t\tg_oTextCompare.panToDifference(g_oTextCompare.g_iStepThroughDifference);\r\n\t};\r\n\r\n\t/**\r\n\t * Ends stepping through differences.\r\n\t */\r\n\tTextCompare.prototype.endStepThroughDifferences = function () {\r\n\r\n\t\t// Stop stepping through differences.\r\n\t\tg_oTextCompare.g_iStepThroughDifference = null;\r\n\r\n\t\t// Render the text compare annotations.\r\n\t\tg_oTextCompare.renderTextCompareAnnotations();\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the differences bar.\r\n\t */\r\n\tTextCompare.prototype.updateDifferencesBar = function () {\r\n\r\n\t\t// If we are not stepping through differences.\r\n\t\tif (g_oTextCompare.g_iStepThroughDifference == null) {\r\n\r\n\t\t\t// If we have differences.\r\n\t\t\tif (g_oTextCompare.g_iNumberOfDifferences > 0) {\r\n\r\n\t\t\t\t// Set the differences bar back to its default state.\r\n\t\t\t\t$(\"#divTextDifferencesTitle\").html(g_oTextCompare.c_szTextCompareDifferencesAll);\r\n\t\t\t\t$(\"#divTextDifferencesContent\").html(g_oTextCompare.c_szTextCompareStepThroughIndividual);\r\n\t\t\t}\r\n\t\t\t// If we have no differences.\r\n\t\t\telse {\r\n\r\n\t\t\t\t// Set the differences bar back to its default state.\r\n\t\t\t\t$(\"#divTextDifferencesTitle\").html(g_oTextCompare.c_szTextCompareNoDifferencesText);\r\n\t\t\t\t$(\"#divTextDifferencesContent\").html(g_oTextCompare.c_szTextCompareNoDifferencesText);\r\n\t\t\t}\r\n\r\n\t\t\t// Update the bar details.\r\n\t\t\t$(\"#selTextDifferenceStatus\").val(g_oTextCompare.eDifferenceStatuses.Initial);\r\n\t\t\t$(\"#selTextDifferenceStatus\").prop(\"disabled\", \"true\");\r\n\t\t\t$(\"#divTextDifferenceCounter\").html(\"\");\r\n\t\t\t$(\"#divTextDifferenceCounter\").hide();\r\n\t\t\t$(\"#divTextDifferenceAnnotate\").hide();\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get the text selections.\r\n\t\tvar oTextSelections = g_oTextCompare.getTextSelectionGroup(false);\r\n\r\n\t\t// Loop through each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelections.length; i++) {\r\n\r\n\t\t\t// Ensure this text selection has differences.\r\n\t\t\tif (oTextSelections[i].g_oTextDifferences == null) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Loop through each of the differences on the text selection.\r\n\t\t\tfor (var j = 0; j < oTextSelections[i].g_oTextDifferences.length; j++) {\r\n\r\n\t\t\t\t// If this is the matching difference.\r\n\t\t\t\tif (oTextSelections[i].g_oTextDifferences[j].g_iDifferenceNumber == g_oTextCompare.g_iStepThroughDifference) {\r\n\r\n\t\t\t\t\t// Extract the difference.\r\n\t\t\t\t\tvar oDifference = oTextSelections[i].g_oTextDifferences[j];\r\n\r\n\t\t\t\t\t// Update the bar with the difference details.\r\n\t\t\t\t\t$(\"#divTextDifferencesTitle\").html(g_oTextCompare.c_szTextCompareGroupText + \" \" + oTextSelections[i].g_iGroupOrder + \" \" + g_oTextCompare.c_szTextCompareDifferenceText + \" \" + oDifference.g_iDifferenceOrder);\r\n\t\t\t\t\t$(\"#selTextDifferenceStatus\").val(oDifference.g_iDifferenceStatus);\r\n\t\t\t\t\t$(\"#selTextDifferenceStatus\").prop(\"disabled\", \"\");\r\n\t\t\t\t\t$(\"#divTextDifferenceCounter\").html(\"(\" + g_oTextCompare.g_iStepThroughDifference + \"/\" + g_oTextCompare.g_iNumberOfDifferences + \")\");\r\n\t\t\t\t\t$(\"#divTextDifferenceCounter\").show();\r\n\r\n\t\t\t\t\t// If we can add difference annotations, show the annotate icon.\r\n\t\t\t\t\tif (g_oTextCompare.g_bDifferenceAnnotations && !oTextSelections[i].g_oTextDifferences[j].g_bAnnotationCreated) {\r\n\t\t\t\t\t\t$(\"#divTextDifferenceAnnotate\").show();\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// If we cannot add difference annotations, hide the annotate icon.\r\n\t\t\t\t\telse {\r\n\t\t\t\t\t\t$(\"#divTextDifferenceAnnotate\").hide();\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// Add the difference text.\r\n\t\t\t\t\tvar szHTML = g_oTextCompare.getDifferenceText(oDifference.g_eDifferenceType) + \": \";\r\n\t\t\t\t\tif (g_oTextCompare.differenceTypeIsSubstitution(oDifference.g_eDifferenceType)) {\r\n\t\t\t\t\t\tszHTML += g_oTextCompare.c_szTextCompareCompareDocument + \": \";\r\n\t\t\t\t\t}\r\n\t\t\t\t\tszHTML += oDifference.g_oFormattedDifferenceText[0];\r\n\t\t\t\t\tif (g_oTextCompare.differenceTypeIsSubstitution(oDifference.g_eDifferenceType)) {\r\n\t\t\t\t\t\tszHTML += \", \" + g_oTextCompare.c_szTextCompareApprovalDocument + \": \";\r\n\t\t\t\t\t\tszHTML += oDifference.g_oFormattedDifferenceText[1];\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$(\"#divTextDifferencesContent\").html(szHTML);\r\n\r\n\t\t\t\t\t// Return.\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Shows the differences summary.\r\n\t */\r\n\tTextCompare.prototype.showDifferencesSummary = function () {\r\n\r\n\t\t// Move the differences summary.\r\n\t\tg_oTextCompare.moveDifferencesSummary(event);\r\n\r\n\t\t// Show the differences summary.\r\n\t\t$(\"#divTextComparisonSummary\").show();\r\n\t};\r\n\r\n\t/**\r\n\t * Moves the differences summary.\r\n\t */\r\n\tTextCompare.prototype.moveDifferencesSummary = function () {\r\n\r\n\t\t// Determine the position of the summary.\r\n\t\tvar iPositionTop = $(\".textCompareSummaryIcon\").position().top + 26;\r\n\t\tvar iPositionLeft = $(\".textCompareSummaryIcon\").position().left;\r\n\r\n\t\t// Set the position of the summary.\r\n\t\t$(\"#divTextComparisonSummary\").css(\"top\", iPositionTop + \"px\");\r\n\t\t$(\"#divTextComparisonSummary\").css(\"left\", iPositionLeft + \"px\");\r\n\t};\r\n\r\n\t/**\r\n\t * Hides the differences summary.\r\n\t */\r\n\tTextCompare.prototype.hideDifferencesSummary = function () {\r\n\r\n\t\t// Hide the differences summary.\r\n\t\t$(\"#divTextComparisonSummary\").hide();\r\n\t};\r\n\r\n\t/**\r\n\t * Updates the differences summary.\r\n\t */\r\n\tTextCompare.prototype.updateDifferencesSummary = function () {\r\n\r\n\t\t// Get the number of each type of difference.\r\n\t\tvar iTotalDifferences = g_oTextCompare.countDifferences(null, null, null);\r\n\t\tvar iAdditionDifferences = g_oTextCompare.countDifferences(null, g_oTextCompare.eDifferenceTypes.Addition, null);\r\n\t\tvar iDeletionDifferences = g_oTextCompare.countDifferences(null, g_oTextCompare.eDifferenceTypes.Deletion, null);\r\n\t\tvar iSubstitutionDifferences = g_oTextCompare.countDifferences(null, g_oTextCompare.eDifferenceTypes.Substitution, null);\r\n\t\tiSubstitutionDifferences += g_oTextCompare.countDifferences(null, g_oTextCompare.eDifferenceTypes.WeightSubstitution, null);\r\n\t\tiSubstitutionDifferences += g_oTextCompare.countDifferences(null, g_oTextCompare.eDifferenceTypes.StyleSubstitution, null);\r\n\t\tiSubstitutionDifferences += g_oTextCompare.countDifferences(null, g_oTextCompare.eDifferenceTypes.WeightStyleSubstitution, null);\r\n\r\n\t\t// Get the number of each status type.\r\n\t\tvar iInitialDifferences = g_oTextCompare.countDifferences(null, null, g_oTextCompare.eDifferenceStatuses.Initial);\r\n\t\tvar iIgnoredDifferences = g_oTextCompare.countDifferences(null, null, g_oTextCompare.eDifferenceStatuses.Ignore);\r\n\t\tvar iAcceptedDifferences = g_oTextCompare.countDifferences(null, null, g_oTextCompare.eDifferenceStatuses.Accept);\r\n\t\tvar iRejectedDifferences = g_oTextCompare.countDifferences(null, null, g_oTextCompare.eDifferenceStatuses.Reject);\r\n\r\n\t\t// Build up the HTML for the summary.\r\n\t\tvar szHTML = '';\r\n\r\n\t\t// Open the summary div.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the row for the total differences.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + iTotalDifferences + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + (iTotalDifferences == 1 ? g_oTextCompare.c_szTextCompareDifferenceLocated : g_oTextCompare.c_szTextCompareDifferencesLocated) + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the row for the addition differences.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + iAdditionDifferences + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + (iAdditionDifferences == 1 ? g_oTextCompare.c_szTextCompareDifferenceTypeAddition : g_oTextCompare.c_szTextCompareDifferenceTypeAdditions) + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the row for the deletion differences.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + iDeletionDifferences + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + (iDeletionDifferences == 1 ? g_oTextCompare.c_szTextCompareDifferenceTypeDeletion : g_oTextCompare.c_szTextCompareDifferenceTypeDeletions) + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the row for the substitution differences.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + iSubstitutionDifferences + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + (iSubstitutionDifferences == 1 ? g_oTextCompare.c_szTextCompareDifferenceTypeSubstitution : g_oTextCompare.c_szTextCompareDifferenceTypeSubstitutions) + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Close the summary div.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the summary status div.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Add the statuses.\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + iInitialDifferences + ' ' + g_oTextCompare.c_szTextCompareDifferenceStatusInitial + '
';\r\n\t\tszHTML += '
' + iIgnoredDifferences + ' ' + g_oTextCompare.c_szTextCompareDifferenceStatusIgnored + '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
';\r\n\t\tszHTML += '
' + iAcceptedDifferences + ' ' + g_oTextCompare.c_szTextCompareDifferenceStatusAccepted + '
';\r\n\t\tszHTML += '
' + iRejectedDifferences + ' ' + g_oTextCompare.c_szTextCompareDifferenceStatusRejected + '
';\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Close the summary status div.\r\n\t\tszHTML += '
';\r\n\r\n\t\t// Apply the HTML.\r\n\t\t$(\"#divTextComparisonSummary\").html(szHTML);\r\n\t};\r\n\r\n\t/**\r\n\t * Pans to a difference.\r\n\t * @param {int} iDifference - The difference.\r\n\t */\r\n\tTextCompare.prototype.panToDifference = function (iDifference) {\r\n\r\n\t\t// Sync the zoom level for both canvas to the highest zoom level.\r\n\t\tif (g_oViewer.g_oArtworkViewer.g_iZoomLevel > g_oCompare.g_oCompareViewer.g_iZoomLevel) {\r\n\t\t\tg_oCompare.g_oCompareViewer.synchroniseZoomPanProperties(g_oViewer.g_oArtworkViewer);\r\n\t\t\tg_oCompare.g_oCompareViewer.g_oCanvasZoom.startZoomAnimate();\r\n\t\t}\r\n\t\telse if (g_oCompare.g_oCompareViewer.g_iZoomLevel > g_oViewer.g_oArtworkViewer.g_iZoomLevel) {\r\n\t\t\tg_oViewer.g_oArtworkViewer.synchroniseZoomPanProperties(g_oCompare.g_oCompareViewer);\r\n\t\t\tg_oViewer.g_oArtworkViewer.g_oCanvasZoom.startZoomAnimate();\r\n\t\t}\r\n\r\n\t\t// Get the pages for the difference on both canvas.\r\n\t\tvar iApprovalDifferencePage = g_oTextCompare.getPageForDifference(iDifference, false);\r\n\t\tvar iCompareDifferencePage = g_oTextCompare.getPageForDifference(iDifference, true);\r\n\r\n\t\t// If we did not find a page for either canvas, assume we are on the correct page.\r\n\t\tiApprovalDifferencePage = iApprovalDifferencePage == -1 ? g_oViewer.g_oArtworkViewer.g_iCurrentPage : iApprovalDifferencePage;\r\n\t\tiCompareDifferencePage = iCompareDifferencePage == -1 ? g_oCompare.g_oCompareViewer.g_iCurrentPage : iCompareDifferencePage;\r\n\r\n\t\t// If we are on the wrong page on either canvas.\r\n\t\tif (iApprovalDifferencePage != g_oViewer.g_oArtworkViewer.g_iCurrentPage || iCompareDifferencePage != g_oCompare.g_oCompareViewer.g_iCurrentPage) {\r\n\r\n\t\t\t// Change to the correct approval page.\r\n\t\t\tg_oViewer.g_oArtworkViewer.g_iCurrentPage = iApprovalDifferencePage;\r\n\t\t\tg_oViewer.g_oArtworkViewer.changeCurrentPage();\r\n\r\n\t\t\t// Change to the correct compare page.\r\n\t\t\tg_oCompare.g_oCompareViewer.g_iCurrentPage = iCompareDifferencePage;\r\n\t\t\tg_oCompare.g_oCompareViewer.changeCurrentPage();\r\n\r\n\t\t\t// Publish that the pages have changed.\r\n\t\t\tEventService.publish(\"changeCurrentPage\", g_oViewer.g_oArtworkViewer, g_oCompare.g_oCompareViewer);\r\n\t\t}\r\n\t\t// If we are on the correct pages.\r\n\t\telse {\r\n\r\n\t\t\t// Pan to the difference on both canvas.\r\n\t\t\tg_oTextCompare.panToDifferenceCanvas(iDifference, false);\r\n\t\t\tg_oTextCompare.panToDifferenceCanvas(iDifference, true);\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * \r\n\t * @param {any} iDifference\r\n\t * @param {any} bCompare\r\n\t */\r\n\tTextCompare.prototype.getPageForDifference = function (iDifference, bCompare) {\r\n\r\n\t\t// Get the text selection groups for this canvas.\r\n\t\tvar oTextSelectionsGroups = g_oTextCompare.getTextSelectionGroup(bCompare);\r\n\r\n\t\t// Get the text selection and difference.\r\n\t\tvar oDifference = null;\r\n\t\tvar oTextSelectionGroup = null;\r\n\r\n\t\t// Check through each of the text selections.\r\n\t\tfor (var i = 0; i < oTextSelectionsGroups.length; i++) {\r\n\r\n\t\t\t// Ensure this group has text differences.\r\n\t\t\tif (oTextSelectionsGroups[i].g_oTextDifferences == null) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// Check through each of the text selections.\r\n\t\t\tfor (var j = 0; j < oTextSelectionsGroups[i].g_oTextDifferences.length; j++) {\r\n\r\n\t\t\t\t// If this is the difference we are looking for.\r\n\t\t\t\tif (oTextSelectionsGroups[i].g_oTextDifferences[j].g_iDifferenceNumber == iDifference) {\r\n\r\n\t\t\t\t\t// Set the difference and text selection group.\r\n\t\t\t\t\toDifference = oTextSelectionsGroups[i].g_oTextDifferences[j];\r\n\t\t\t\t\toTextSelectionGroup = oTextSelectionsGroups[i];\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// Stop if we have found the difference.\r\n\t\t\tif (oDifference != null) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Ensure we have found both the difference and text selection group.\r\n\t\tif (oDifference == null || oTextSelectionGroup == null) {\r\n\t\t\treturn -1;\r\n\t\t}\r\n\r\n\t\t// Check through each of the text selection.\r\n\t\tfor (var j = 0; j < oTextSelectionGroup.g_oTextSelections.length; j++) {\r\n\r\n\t\t\t// If we are at a word level difference.\r\n\t\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\r\n\t\t\t\t// Check through each of the words.\r\n\t\t\t\tfor (var k = 0; k < oTextSelectionGroup.g_oTextSelections[j].g_oSelectionWords.length; k++) {\r\n\r\n\t\t\t\t\t// If this word is part of the difference, return the difference page.\r\n\t\t\t\t\t// If this word is part of the difference as a marker, return the difference page.\r\n\t\t\t\t\tif (oTextSelectionGroup.g_oTextSelections[j].g_oSelectionWords[k].difference == oDifference.g_iDifferenceOrder ||\r\n\t\t\t\t\t\toTextSelectionGroup.g_oTextSelections[j].g_oSelectionWords[k].markerDifference == oDifference.g_iDifferenceOrder) {\r\n\t\t\t\t\t\treturn oTextSelectionGroup.g_oTextSelections[j].g_oSelectionWords[k].page;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t// If we are at a character level difference.\r\n\t\t\telse {\r\n\r\n\t\t\t\t// Check through each of the characters.\r\n\t\t\t\tfor (var k = 0; k < oTextSelectionGroup.g_oTextSelections[j].g_oSelectionCharacters.length; k++) {\r\n\r\n\t\t\t\t\t// If this character is part of the difference, return the difference page.\r\n\t\t\t\t\t// If this character is part of the difference as a marker, return the difference page.\r\n\t\t\t\t\tif (oTextSelectionGroup.g_oTextSelections[j].g_oSelectionCharacters[k].difference == oDifference.g_iDifferenceOrder ||\r\n\t\t\t\t\t\toTextSelectionGroup.g_oTextSelections[j].g_oSelectionCharacters[k].markerDifference == oDifference.g_iDifferenceOrder) {\r\n\t\t\t\t\t\treturn oTextSelectionGroup.g_oTextSelections[j].g_oSelectionCharacters[k].page;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return that we did not find a difference page.\r\n\t\treturn -1;\r\n\t};\r\n\r\n\t/**\r\n\t * Pans to a difference on canvas.\r\n\t * @param {int} iDifference - The difference.\r\n\t * @param {boolean} bCompare - If this is the compare canvas.\r\n\t */\r\n\tTextCompare.prototype.panToDifferenceCanvas = function (iDifference, bCompare) {\r\n\r\n\t\t// Get the canvas we are going to pan on.\r\n\t\tvar oArtworkCanvas = !bCompare ? g_oViewer.g_oArtworkViewer : g_oCompare.g_oCompareViewer;\r\n\t\tvar oAnnotationCanvas = !bCompare ? g_oViewer.g_oAnnotationViewer : g_oCompare.g_oCompareAnnotationViewer;\r\n\r\n\t\t// Ensure we are zoomed.\r\n\t\tif (oArtworkCanvas.g_iZoomLevel == 1) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Get the text selection groups for this canvas.\r\n\t\tvar oTextSelectionsGroups = g_oTextCompare.getTextSelectionGroup(bCompare);\r\n\r\n\t\t// Get the difference and text selections.\r\n\t\tvar oDifference = null;\r\n\t\tvar oTextSelections = null;\r\n\t\tfor (var i = 0; i < oTextSelectionsGroups.length; i++) {\r\n\t\t\t// Ensure this text selection has differences.\r\n\t\t\tif (oTextSelectionsGroups[i].g_oTextDifferences == null) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tfor (var j = 0; j < oTextSelectionsGroups[i].g_oTextDifferences.length; j++) {\r\n\t\t\t\tif (oTextSelectionsGroups[i].g_oTextDifferences[j].g_iDifferenceNumber == iDifference) {\r\n\t\t\t\t\toDifference = oTextSelectionsGroups[i].g_oTextDifferences[j];\r\n\t\t\t\t\toTextSelections = oTextSelectionsGroups[i].g_oTextSelections;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (oDifference != null) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Outline the bounds to pan to.\r\n\t\tvar oPanBounds = null;\r\n\r\n\t\t// If we have calculated differences to the word level.\r\n\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\r\n\t\t\t// Keep track of a list of words that are part of this difference.\r\n\t\t\tvar oDifferenceWords = g_oTextCompare.getWordsForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t\t// If we have no words, get the markers for this difference.\r\n\t\t\tif (oDifferenceWords.length == 0) {\r\n\t\t\t\toDifferenceWords = g_oTextCompare.getWordMarkersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\t\t\t}\r\n\r\n\t\t\t// Ensure we have words to pan to.\r\n\t\t\tif (oDifferenceWords.length > 0) {\r\n\r\n\t\t\t\t// Get the bounds of the word list for this difference.\r\n\t\t\t\toPanBounds = g_oTextTools.getWordListBounds(oDifferenceWords, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t}\r\n\t\t}\r\n\t\t// If we have calculated differences to the character level.\r\n\t\telse {\r\n\r\n\t\t\t// Keep track of a list of characters that are part of this difference.\r\n\t\t\tvar oDifferenceCharacters = g_oTextCompare.getCharactersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t\t// If we have no characters, get the markers for this difference.\r\n\t\t\tif (oDifferenceCharacters.length == 0) {\r\n\t\t\t\toDifferenceCharacters = g_oTextCompare.getCharacterMarkersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\t\t\t}\r\n\r\n\t\t\t// Ensure we have characters to pan to.\r\n\t\t\tif (oDifferenceCharacters.length > 0) {\r\n\r\n\t\t\t\t// Get the bounds of the character list for this difference.\r\n\t\t\t\toPanBounds = g_oTextTools.getCharacterListBounds(oDifferenceCharacters, oArtworkCanvas, oAnnotationCanvas);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Ensure we have bounds to pan to.\r\n\t\tif (oPanBounds == null) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Calculate the mid point.\r\n\t\tvar oBoundsMidPoint = [oPanBounds.x1 + ((oPanBounds.x2 - oPanBounds.x1) / 2), oPanBounds.y1 + ((oPanBounds.y2 - oPanBounds.y1) / 2)];\r\n\r\n\t\t// Determine the max canvas width and height.\r\n\t\tvar maxCanvasWidth = Math.max(g_oViewer.g_oArtworkViewer.g_iScaledImageWidth, g_oCompare.g_oCompareViewer.g_iScaledImageWidth);\r\n\t\tvar maxCanvasHeight = Math.max(g_oViewer.g_oArtworkViewer.g_iScaledImageHeight, g_oCompare.g_oCompareViewer.g_iScaledImageHeight);\r\n\r\n\t\t// Determine the drag offset.\r\n\t\toArtworkCanvas.g_iTempDragOffset_x = (oBoundsMidPoint[0] * oArtworkCanvas.g_iScaledImageWidth) - (maxCanvasWidth / 2);\r\n\t\toArtworkCanvas.g_iTempDragOffset_y = (oBoundsMidPoint[1] * oArtworkCanvas.g_iScaledImageHeight) - (maxCanvasHeight / 2);\r\n\r\n\t\t// Determine the drag difference.\r\n\t\toArtworkCanvas.g_iDragXDiff = (oArtworkCanvas.g_iDragOffset_x - oArtworkCanvas.g_iTempDragOffset_x) / oArtworkCanvas.g_iAnimateFrames;\r\n\t\toArtworkCanvas.g_iDragYDiff = (oArtworkCanvas.g_iDragOffset_y - oArtworkCanvas.g_iTempDragOffset_y) / oArtworkCanvas.g_iAnimateFrames;\r\n\r\n\t\t// Perform the pan.\r\n\t\toArtworkCanvas.g_oCanvasZoom.startZoomAnimate();\r\n\t};\r\n\r\n\t/**\r\n\t * Creates a step difference annotation.\r\n\t */\r\n\tTextCompare.prototype.createStepDifferenceAnnotation = function () {\r\n\r\n\t\t// Get the current difference from the step through.\r\n\t\tvar iDifference = g_oTextCompare.g_iStepThroughDifference;\r\n\r\n\t\t// Create the difference annotation for this difference.\r\n\t\tg_oTextCompare.createDifferenceAnnotationEdit(iDifference);\r\n\t};\r\n\r\n\t/**\r\n\t * Creates a difference annotation edit area.\r\n\t * @param {int} iDifference - The difference number.\r\n\t */\r\n\tTextCompare.prototype.createDifferenceAnnotationEdit = function (iDifference) {\r\n\r\n\t\t// Create the difference annotation.\r\n\t\tvar oDifferenceAnnotation = g_oTextCompare.createDifferenceAnnotation(iDifference);\r\n\r\n\t\t// Ensure we have a difference annotation.\r\n\t\tif (oDifferenceAnnotation == null) {\r\n\t\t\tg_oGreenlightMessages.displayErrorBubble(\"Failed to create the difference annotation\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Hide the annotate button.\r\n\t\t$(\"#divTextDifferenceAnnotate\").hide();\r\n\r\n\t\t// Remove the content from the text difference to make room for the annotation edit area.\r\n\t\t$(\"#divTextDifferencesContent\").html(\"\");\r\n\r\n\t\t// Create the text area input.\r\n\t\toDifferenceAnnotation.createAnnotationTextArea(\"divTextDifferencesContent\", oDifferenceAnnotation.g_iAuthor, oDifferenceAnnotation.g_szAuthorEmail, oDifferenceAnnotation.g_szAuthorEmail, eFieldTypes.DifferenceHeader, false, oDifferenceAnnotation.g_szTextContent, $(\"#divTextDifferencesContent\")[0], Date.now(), null, g_oViewer.g_oArtworkViewer, g_oViewer.g_oAnnotationViewer, null, null);\r\n\r\n\t\t// Add the create and cancel buttons to the text area input.\r\n\t\t$(\"#divTextDifferencesContent\").append(\r\n\t\t\t'
' +\r\n\t\t\t'
' + g_oTextCompare.c_szTextCompareCancelAnnotation + '
' +\r\n\t\t\t'
' + g_oTextCompare.c_szTextCompareCreateAnnotation + '
' +\r\n\t\t\t'
'\r\n\t\t);\r\n\t};\r\n\r\n\t/**\r\n\t * Saves the difference annotation.\r\n\t */\r\n\tTextCompare.prototype.saveDifferenceAnnotation = function () {\r\n\r\n\t\t// Get the difference number.\r\n\t\tvar iDifference = g_oTextCompare.g_iStepThroughDifference;\r\n\r\n\t\t// Create the difference annotation.\r\n\t\tvar oDifferenceAnnotation = g_oTextCompare.createDifferenceAnnotation(iDifference);\r\n\r\n\t\t// Ensure we have a difference annotation.\r\n\t\tif (oDifferenceAnnotation == null) {\r\n\t\t\tg_oGreenlightMessages.displayErrorBubble(\"Failed to create the difference annotation\");\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// Update the difference text with that of the editor.\r\n\t\toDifferenceAnnotation.g_szTextContent = $(\".jqte_editor\").html();\r\n\r\n\t\t// Save the difference annotation.\r\n\t\toDifferenceAnnotation.AnnotationSave();\r\n\r\n\t\t// Get the text selection groups for this canvas.\r\n\t\tvar oTextSelectionsGroups = g_oTextCompare.getTextSelectionGroup(false);\r\n\r\n\t\t// Set that this difference has had an annotation created.\r\n\t\tfor (var i = 0; i < oTextSelectionsGroups.length; i++) {\r\n\t\t\t// Ensure this text selection has differences.\r\n\t\t\tif (oTextSelectionsGroups[i].g_oTextDifferences == null) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tfor (var j = 0; j < oTextSelectionsGroups[i].g_oTextDifferences.length; j++) {\r\n\t\t\t\tif (oTextSelectionsGroups[i].g_oTextDifferences[j].g_iDifferenceNumber == iDifference) {\r\n\t\t\t\t\toTextSelectionsGroups[i].g_oTextDifferences[j].g_bAnnotationCreated = true;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Update the differences bar.\r\n\t\tg_oTextCompare.updateDifferencesBar();\r\n\t};\r\n\r\n\t/**\r\n\t * Cancels the difference annotation.\r\n\t */\r\n\tTextCompare.prototype.cancelDifferenceAnnotation = function () {\r\n\r\n\t\t// Update the differences bar.\r\n\t\tg_oTextCompare.updateDifferencesBar();\r\n\t};\r\n\r\n\t/**\r\n\t * Creates a difference annotation.\r\n\t * @param {int} iDifference - The difference number.\r\n\t */\r\n\tTextCompare.prototype.createDifferenceAnnotation = function (iDifference) {\r\n\r\n\t\t// Get the canvas we are going to add annotations to.\r\n\t\tvar oArtworkCanvas = g_oViewer.g_oArtworkViewer;\r\n\t\tvar oAnnotationCanvas = g_oViewer.g_oAnnotationViewer;\r\n\r\n\t\t// Get the text selection groups for this canvas.\r\n\t\tvar oTextSelectionsGroups = g_oTextCompare.getTextSelectionGroup(false);\r\n\r\n\t\t// Get the difference and text selections.\r\n\t\tvar oDifference = null;\r\n\t\tvar oTextSelections = null;\r\n\t\tfor (var i = 0; i < oTextSelectionsGroups.length; i++) {\r\n\t\t\t// Ensure this text selection has differences.\r\n\t\t\tif (oTextSelectionsGroups[i].g_oTextDifferences == null) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\t\t\tfor (var j = 0; j < oTextSelectionsGroups[i].g_oTextDifferences.length; j++) {\r\n\t\t\t\tif (oTextSelectionsGroups[i].g_oTextDifferences[j].g_iDifferenceNumber == iDifference) {\r\n\t\t\t\t\toDifference = oTextSelectionsGroups[i].g_oTextDifferences[j];\r\n\t\t\t\t\toTextSelections = oTextSelectionsGroups[i].g_oTextSelections;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tif (oDifference != null) {\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Keep track of the annotation text.\r\n\t\tvar oAnnotationText = [];\r\n\r\n\t\t// If we have calculated differences to a word level.\r\n\t\tif (g_oTextCompare.g_iAccuracy == g_oTextCompare.eAccuracyLevels.Word) {\r\n\r\n\t\t\t// Get the words for the text difference.\r\n\t\t\tvar oDifferenceWords = g_oTextCompare.getWordsForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t\t// If we have no words, get the markers for this difference.\r\n\t\t\tif (oDifferenceWords.length == 0) {\r\n\t\t\t\toDifferenceWords = g_oTextCompare.getWordMarkersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\t\t\t}\r\n\r\n\t\t\t// Convert difference words to annotation text.\r\n\t\t\toAnnotationText = g_oTextCompare.convertWordsToAnnotationText(oDifferenceWords);\r\n\t\t}\r\n\t\t// If we have calculated differences to a character level.\r\n\t\telse {\t\t\t\r\n\t\t\t// Get the characters for the text difference.\r\n\t\t\tvar oDifferenceCharacters = g_oTextCompare.getCharactersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\r\n\t\t\t// If we have no characters, get the markers for this difference.\r\n\t\t\tif (oDifferenceCharacters.length == 0) {\r\n\t\t\t\toDifferenceCharacters = g_oTextCompare.getCharacterMarkersForTextDifference(oTextSelections, oDifference.g_iDifferenceOrder, oArtworkCanvas.g_iCurrentPage);\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\t// Convert difference characters to annotation text.\r\n\t\t\toAnnotationText = g_oTextCompare.convertCharactersToAnnotationText(oDifferenceCharacters);\r\n\t\t}\r\n\r\n\t\t// Ensure we have text.\r\n\t\tif (oAnnotationText.length == 0) {\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t// Create the text annotation.\r\n\t\tvar oTextAnnotation = g_oTextTools.generateTextAnnotation(oAnnotationText, eAnnotationTypes.TextHighlight, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Update the colour of the annotation based on the difference status.\r\n\t\toTextAnnotation.g_szColour = g_oAnnotations.getHexColour(g_oTextCompare.getAnnotationColourFromDifferenceStatus(oDifference.g_iDifferenceStatus));\r\n\r\n\t\t// Update the text of the annotation based on the difference.\r\n\t\toTextAnnotation.g_szTextContent = '
' + g_oTextCompare.getDifferenceText(oDifference.g_eDifferenceType) + '
';\r\n\t\tif (g_oTextCompare.differenceTypeIsSubstitution(oDifference.g_eDifferenceType)) {\r\n\t\t\toTextAnnotation.g_szTextContent += '
' + g_oTextCompare.c_szTextCompareCompareDocument + ':
';\r\n\t\t}\r\n\t\toTextAnnotation.g_szTextContent += '
' + oDifference.g_oFormattedDifferenceText[0] + '
';\r\n\t\tif (g_oTextCompare.differenceTypeIsSubstitution(oDifference.g_eDifferenceType)) {\r\n\t\t\toTextAnnotation.g_szTextContent += '
' + g_oTextCompare.c_szTextCompareApprovalDocument + ':
';\r\n\t\t\toTextAnnotation.g_szTextContent += '
' + oDifference.g_oFormattedDifferenceText[1] + '
';\r\n\t\t}\r\n\r\n\t\t// Return the difference annotation.\r\n\t\treturn oTextAnnotation;\r\n\t};\r\n\r\n\t/**\r\n\t * Converts the difference words to annotation text.\r\n\t * @param {object} oDifferenceWords - The difference words.\r\n\t */\r\n\tTextCompare.prototype.convertWordsToAnnotationText = function (oDifferenceWords) {\r\n\t\t\r\n\t\t// Outline the annotation text to be returned.\r\n\t\tvar oAnnotationText = [];\r\n\r\n\t\t// Loop through each of the difference words.\r\n\t\tfor (var i = 0; i < oDifferenceWords.length; i++) {\r\n\r\n\t\t\t// Add the difference word as an annotation text.\r\n\t\t\toAnnotationText.push({\r\n\t\t\t\tstartingText: {\r\n\t\t\t\t\tparagraph: oDifferenceWords[i].paragraph,\r\n\t\t\t\t\tline: oDifferenceWords[i].line,\r\n\t\t\t\t\tword: oDifferenceWords[i].word\r\n\t\t\t\t},\r\n\t\t\t\tendingText: {\r\n\t\t\t\t\tparagraph: oDifferenceWords[i].paragraph,\r\n\t\t\t\t\tline: oDifferenceWords[i].line,\r\n\t\t\t\t\tword: oDifferenceWords[i].word\r\n\t\t\t\t},\r\n\t\t\t\tleftToRight: true\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// Merge the sections words to create the annotation text.\r\n\t\toAnnotationText = g_oTextTools.mergeSections_Words(oAnnotationText, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Return the annotation text.\r\n\t\treturn oAnnotationText;\r\n\t};\r\n\r\n\t/**\r\n\t * Converts the difference characters to annotation text.\r\n\t * @param {object} oDifferenceCharacters - The difference characters.\r\n\t */\r\n\tTextCompare.prototype.convertCharactersToAnnotationText = function (oDifferenceCharacters) {\r\n\r\n\t\t// Outline the annotation text to be returned.\r\n\t\tvar oAnnotationText = [];\r\n\r\n\t\t// Loop through each of the difference characters.\r\n\t\tfor (var i = 0; i < oDifferenceCharacters.length; i++) {\r\n\r\n\t\t\t// Add the difference character as an annotation text.\r\n\t\t\toAnnotationText.push({\r\n\t\t\t\tstartingText: {\r\n\t\t\t\t\tparagraph: oDifferenceCharacters[i].paragraph,\r\n\t\t\t\t\tline: oDifferenceCharacters[i].line,\r\n\t\t\t\t\tword: oDifferenceCharacters[i].word,\r\n\t\t\t\t\tcharacter: oDifferenceCharacters[i].character\r\n\t\t\t\t},\r\n\t\t\t\tendingText: {\r\n\t\t\t\t\tparagraph: oDifferenceCharacters[i].paragraph,\r\n\t\t\t\t\tline: oDifferenceCharacters[i].line,\r\n\t\t\t\t\tword: oDifferenceCharacters[i].word,\r\n\t\t\t\t\tcharacter: oDifferenceCharacters[i].character\r\n\t\t\t\t},\r\n\t\t\t\tleftToRight: true\r\n\t\t\t});\r\n\t\t}\r\n\r\n\t\t// Merge the sections characters to create the annotation text.\r\n\t\toAnnotationText = g_oTextTools.mergeSections_Characters(oAnnotationText, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Return the annotation text.\r\n\t\treturn oAnnotationText;\r\n\t};\r\n\r\n\t/**\r\n\t * Checks if a difference type is a substitution.\r\n\t * @param {int} eDifferenceType - The difference type to be checked.\r\n\t */\r\n\tTextCompare.prototype.differenceTypeIsSubstitution = function (iDifferenceType) {\r\n\t\treturn iDifferenceType == g_oTextCompare.eDifferenceTypes.Substitution || iDifferenceType == g_oTextCompare.eDifferenceTypes.WeightSubstitution ||\r\n\t\t\tiDifferenceType == g_oTextCompare.eDifferenceTypes.StyleSubstitution || iDifferenceType == g_oTextCompare.eDifferenceTypes.WeightStyleSubstitution;\r\n\t};\r\n\r\n\t/**\r\n\t * Determines the bold italic substitution type.\r\n\t * @param {any} bHasBoldDifference - The bold difference.\r\n\t * @param {any} bHasItalicDifference - The italic difference.\r\n\t */\r\n\tTextCompare.prototype.determineBoldItalicSubstitutionType = function (bHasBoldDifference, bHasItalicDifference) {\r\n\t\tvar iDifferenceType = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\r\n\t\t// Determine the difference type.\r\n\t\tif (bHasBoldDifference && bHasItalicDifference) {\r\n\t\t\tiDifferenceType = g_oTextCompare.eDifferenceTypes.WeightStyleSubstitution;\r\n\t\t}\r\n\t\telse if (bHasBoldDifference) {\r\n\t\t\tiDifferenceType = g_oTextCompare.eDifferenceTypes.WeightSubstitution;\r\n\t\t}\r\n\t\telse if (bHasItalicDifference) {\r\n\t\t\tiDifferenceType = g_oTextCompare.eDifferenceTypes.StyleSubstitution;\r\n\t\t}\r\n\r\n\t\treturn iDifferenceType;\r\n\t};\r\n\r\n\t/**\r\n\t * Populates text data.\r\n\t * @param {any} oTextData - The text data to be populated.\r\n\t * @param {any} oArtworkCanvas - The artwork canvas.\r\n\t * @param {any} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.populateTextData = function (oTextData, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// Get the text data for the document page.\r\n\t\tvar oFullTextData = g_oTextData.getTextData(oArtworkCanvas.g_oDoc.documentId, oArtworkCanvas.g_iCurrentPage).textData;\r\n\r\n\t\t// Add any missing character data.\r\n\t\tfor (var i = 0; i < oTextData.length; i++) {\r\n\r\n\t\t\t// Populate the starting text character if required.\r\n\t\t\tif (oTextData[i].startingText.character == undefined) {\r\n\r\n\t\t\t\t// Extract the word.\r\n\t\t\t\tvar oWord = oFullTextData.Paragraphs[oTextData[i].startingText.paragraph].Lines[oTextData[i].startingText.line].Words[oTextData[i].startingText.word];\r\n\r\n\t\t\t\t// Set the starting text to the first / last character.\r\n\t\t\t\toTextData[i].startingText.character = oTextData[i].leftToRight ? oWord.Characters[0].Order : oWord.Characters[oWord.Characters.length - 1].Order;\r\n\t\t\t}\r\n\r\n\t\t\t// Populate the ending text character if required.\r\n\t\t\tif (oTextData[i].endingText.character == undefined) {\r\n\r\n\t\t\t\t// Extract the word.\r\n\t\t\t\tvar oWord = oFullTextData.Paragraphs[oTextData[i].endingText.paragraph].Lines[oTextData[i].endingText.line].Words[oTextData[i].endingText.word];\r\n\r\n\t\t\t\t// Set the ending text to the last / first character.\r\n\t\t\t\toTextData[i].endingText.character = oTextData[i].leftToRight ? oWord.Characters[oWord.Characters.length - 1].Order : oWord.Characters[0].Order;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Return the result.\r\n\t\treturn oTextData;\r\n\t};\r\n\r\n\t/**\r\n\t * Constructor for a text selection groups object.\r\n\t * @param {object} oTextSelectionGroups - The text selection groups.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t */\r\n\tTextCompare.prototype.textSelectionGroups = function (oTextSelectionGroups, oArtworkCanvas) {\r\n\r\n\t\t// Ensure we have a document to store selections for.\r\n\t\tif (oArtworkCanvas.g_oDoc != null) {\r\n\r\n\t\t\t// The id of the canvas the text selection is stored for.\r\n\t\t\tthis.g_szCanvasId = oArtworkCanvas.g_szCanvasId;\r\n\r\n\t\t\t// The id of the document.\r\n\t\t\tthis.g_iDocumentId = oArtworkCanvas.g_oDoc.documentId;\r\n\r\n\t\t\t// The list of text selection groups.\r\n\t\t\tthis.g_oTextSelectionGroups = oTextSelectionGroups;\r\n\t\t}\r\n\t};\r\n\r\n\t/**\r\n\t * Constructor for a text selection group object.\r\n\t * @param {int} iGroupOrder - The group order.\r\n\t */\r\n\tTextCompare.prototype.textSelectionGroup = function (iGroupOrder) {\r\n\r\n\t\t// The order of this group.\r\n\t\tthis.g_iGroupOrder = iGroupOrder;\r\n\r\n\t\t// The text selection for this group.\r\n\t\tthis.g_oTextSelections = [];\r\n\r\n\t\t// The text modifications for this group.\r\n\t\tthis.g_oTextModifications = [];\r\n\r\n\t\t// The text differences for this group.\r\n\t\tthis.g_oTextDifferences = [];\r\n\t};\r\n\r\n\t/**\r\n\t * Constructor for a text selection object.\r\n\t * @param {object} oTextData - The text data.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.textSelection = function (oTextData, oArtworkCanvas, oAnnotationCanvas) {\r\n\r\n\t\t// The text data for the selection.\r\n\t\tthis.g_oTextData = g_oTextCompare.populateTextData(oTextData, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// The page the selection is on.\r\n\t\tthis.g_iPage = oArtworkCanvas.g_iCurrentPage;\r\n\r\n\t\t// Get the selection words.\r\n\t\tthis.g_oSelectionWords = g_oTextCompare.getTextSelectionWords(oTextData, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// The selection words bounds.\r\n\t\tthis.g_oSelectionWordsBounds = g_oTextTools.getWordListBounds(this.g_oSelectionWords, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Get the selection words text.\r\n\t\tthis.g_oSelectionWordsText = g_oTextTools.getWordListText(this.g_oSelectionWords, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Get the selection characters.\r\n\t\tthis.g_oSelectionCharacters = g_oTextCompare.getTextSelectionCharacters(oTextData, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// The selection characters bounds.\r\n\t\tthis.g_oSelectionCharacterBounds = g_oTextTools.getCharacterListBounds(this.g_oSelectionCharacters, oArtworkCanvas, oAnnotationCanvas);\r\n\r\n\t\t// Get the selection characters text.\r\n\t\tthis.g_oSelectionCharactersText = g_oTextTools.getCharacterListText(this.g_oSelectionCharacters, oArtworkCanvas, oAnnotationCanvas);\r\n\t};\r\n\r\n\t/**\r\n\t * Constructor for a text selection word object.\r\n\t * @param {object} oWord - The word.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.textSelectionWord = function (oWord, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\tthis.paragraph = oWord.paragraph;\r\n\t\tthis.line = oWord.line;\r\n\t\tthis.word = oWord.word;\r\n\t\tthis.page = oArtworkCanvas.g_iCurrentPage;\r\n\t\tthis.bold = g_oTextTools.getWordBoldSetting(oWord, oArtworkCanvas, oAnnotationCanvas);\r\n\t\tthis.italic = g_oTextTools.getWordItalicSetting(oWord, oArtworkCanvas, oAnnotationCanvas);\r\n\t\tthis.content = g_oTextTools.getWordText(oWord, oArtworkCanvas, oAnnotationCanvas);\r\n\t\tthis.status = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\t\tthis.difference = -1;\r\n\t\tthis.marker = g_oTextCompare.eMarkerTypes.NoMarker;\r\n\t\tthis.markerDifference = -1;\r\n\t\tthis.equivalentDifference = false;\r\n\t};\r\n\r\n\t/**\r\n\t * Constructor for a text selection character object.\r\n\t * @param {object} oCharacter - The character.\r\n\t * @param {object} oArtworkCanvas - The artwork canvas.\r\n\t * @param {object} oAnnotationCanvas - The annotation canvas.\r\n\t */\r\n\tTextCompare.prototype.textSelectionCharacter = function (oCharacter, oArtworkCanvas, oAnnotationCanvas) {\r\n\t\tthis.paragraph = oCharacter.paragraph;\r\n\t\tthis.line = oCharacter.line;\r\n\t\tthis.word = oCharacter.word;\r\n\t\tthis.character = oCharacter.character;\r\n\t\tthis.page = oArtworkCanvas.g_iCurrentPage;\r\n\t\tthis.lastInWord = g_oTextTools.getCharacterLastInWord(oCharacter, oArtworkCanvas, oAnnotationCanvas);\r\n\t\tthis.bold = g_oTextTools.getCharacterBoldSetting(oCharacter, oArtworkCanvas, oAnnotationCanvas);\r\n\t\tthis.italic = g_oTextTools.getCharacterItalicSetting(oCharacter, oArtworkCanvas, oAnnotationCanvas);\r\n\t\tthis.content = g_oTextTools.getCharacterText(oCharacter, oArtworkCanvas, oAnnotationCanvas);\r\n\t\tthis.status = g_oTextCompare.eDifferenceTypes.NoDifference;\r\n\t\tthis.difference = -1;\r\n\t\tthis.marker = g_oTextCompare.eMarkerTypes.NoMarker;\r\n\t\tthis.markerDifference = -1;\r\n\t\tthis.equivalentDifference = false;\r\n\t};\r\n\r\n\t/**\r\n\t * Constructor for a text modification object.\r\n\t * @param {object} oComparison - The comparison.\r\n\t */\r\n\tTextCompare.prototype.textModification = function (oComparison) {\r\n\r\n\t\t// The modification text.\r\n\t\tthis.g_szModificationText = oComparison[1];\r\n\r\n\t\t// The difference type.\r\n\t\tthis.g_eDifferenceType = oComparison[0];\r\n\r\n\t\t// The difference mapping.\r\n\t\tthis.g_eDifferenceMapping = g_oTextCompare.g_eDifferenceMapping.Both;\r\n\t};\r\n\r\n\t/**\r\n\t * Constructor for a text difference object.\r\n\t * @param {object} oDifferenceTextList - The difference text list.\r\n\t * @param {enum} eDifferenceType - The difference type.\r\n\t * @param {int} iDifferenceNumber - The difference number.\r\n\t * @param {int} iDifferenceOrder - The difference order.\r\n\t */\r\n\tTextCompare.prototype.textDifference = function (oDifferenceTextList, eDifferenceType, iDifferenceNumber, iDifferenceOrder) {\r\n\r\n\t\t// The text to be used for the difference.\r\n\t\tthis.g_oDifferenceText = oDifferenceTextList;\r\n\r\n\t\t// The formatted difference text.\r\n\t\tthis.g_oFormattedDifferenceText = [];\r\n\r\n\t\t// The difference type.\r\n\t\tthis.g_eDifferenceType = eDifferenceType;\r\n\r\n\t\t// The number for this difference.\r\n\t\tthis.g_iDifferenceNumber = iDifferenceNumber;\r\n\r\n\t\t// The order for this difference.\r\n\t\tthis.g_iDifferenceOrder = iDifferenceOrder;\r\n\r\n\t\t// The status of the difference.\r\n\t\tthis.g_iDifferenceStatus = g_oTextCompare.eDifferenceStatuses.Initial;\r\n\r\n\t\t// The annotation for the difference.\r\n\t\tthis.g_bAnnotationCreated = false;\r\n\t};\r\n\r\n\t// Add the Text Compare UI object to the window.\r\n\twindow.TextCompare = TextCompare;\r\n}());"]}