Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrbrooks2010-07-23 21:54:28 +0000
committerrbrooks2010-07-23 21:54:28 +0000
commite6b2837faf351beaf748103de9ceed8a72191531 (patch)
tree7b6219bd3f483e024e02cbf31524aad1be5f2f52
parentefb0fc5976eeee18b3a0be5ff11068b2eb261661 (diff)
downloadorg.eclipse.osee-e6b2837faf351beaf748103de9ceed8a72191531.tar.gz
org.eclipse.osee-e6b2837faf351beaf748103de9ceed8a72191531.tar.xz
org.eclipse.osee-e6b2837faf351beaf748103de9ceed8a72191531.zip
[Bug 316039] OSEE Artifact Import - Word outline parser does not work with certain xml documents in wordml
-rw-r--r--plugins/org.eclipse.osee.ats.config.demo/support/SAW-SubsystemRequirements.xml2
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core.test/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/JdkCoreTestSuite.java11
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/JdkCoreRuleTestSuite.java23
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/WordMLNewLineMakerRuleTest.java93
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/sample_icd_formatted.xml44
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/JdkCoreTextTestSuite.java23
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/UtfReadingRuleTest.java107
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/utf8_input.xml1
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/Rule.java335
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/HushHtmlScriptErrors.java79
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/WordMLNewLineMaker.java203
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/AHTML.java972
-rw-r--r--plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/Lib.java3326
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Fast_Suite.java25
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Suite.java31
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/MockResolutionGui.java38
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/OutlineResolutionAndNumberTest.java75
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/ParsersSuite.java25
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordMLExtractorDelegateTableOfContentsTest.java75
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordMlResolutionGuiTest.java119
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordOutlineTest.java213
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/numberEmbeddedInTheContent.xml2
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineNameNumberAndContent.xml2
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineNameWithNumber.xml1
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineResolutionCausingInput_no_toc_formatted.xml255
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/tableOfContentsHyperlinkTest.xml73
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/OutlineResolution.java107
-rw-r--r--plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/WordOutlineExtractorDelegate.java477
-rw-r--r--plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml6
-rw-r--r--plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/handler/UIOutlineResolutionHandler.java58
32 files changed, 4317 insertions, 2486 deletions
diff --git a/plugins/org.eclipse.osee.ats.config.demo/support/SAW-SubsystemRequirements.xml b/plugins/org.eclipse.osee.ats.config.demo/support/SAW-SubsystemRequirements.xml
index 324be4301d2..1d8bca3a5bb 100644
--- a/plugins/org.eclipse.osee.ats.config.demo/support/SAW-SubsystemRequirements.xml
+++ b/plugins/org.eclipse.osee.ats.config.demo/support/SAW-SubsystemRequirements.xml
@@ -1,3 +1,3 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<?mso-application progid="Word.Document"?>
-<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:wsp="http://schemas.microsoft.com/office/word/2003/wordml/sp2" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve"><w:ignoreElements w:val="http://schemas.microsoft.com/office/word/2003/wordml/sp2"/><o:DocumentProperties><o:Author>Ryan D. Brooks</o:Author><o:LastAuthor>Ryan D. Brooks</o:LastAuthor><o:Revision>3</o:Revision><o:TotalTime>4</o:TotalTime><o:Created>2007-11-08T00:23:00Z</o:Created><o:LastSaved>2007-11-08T00:57:00Z</o:LastSaved><o:Pages>6</o:Pages><o:Words>1398</o:Words><o:Characters>7969</o:Characters><o:Company>The Boeing Company</o:Company><o:Lines>66</o:Lines><o:Paragraphs>18</o:Paragraphs><o:CharactersWithSpaces>9349</o:CharactersWithSpaces><o:Version>11.8134</o:Version></o:DocumentProperties><w:fonts><w:defaultFonts w:ascii="Times New Roman" w:fareast="Times New Roman" w:h-ansi="Times New Roman" w:cs="Times New Roman"/><w:font w:name="Wingdings"><w:panose-1 w:val="05000000000000000000"/><w:charset w:val="02"/><w:family w:val="Auto"/><w:pitch w:val="variable"/><w:sig w:usb-0="00000000" w:usb-1="10000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="80000000" w:csb-1="00000000"/></w:font><w:font w:name="APODLF+TimesNewRoman"><w:altName w:val="Times New Roman"/><w:panose-1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="default"/><w:sig w:usb-0="00000003" w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="00000001" w:csb-1="00000000"/></w:font><w:font w:name="APOBEE+TimesNewRoman,Bold"><w:altName w:val="Times New Roman"/><w:panose-1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="default"/><w:sig w:usb-0="00000003" w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="00000001" w:csb-1="00000000"/></w:font><w:font w:name="APODLD+TimesNewRoman,Italic"><w:altName w:val="Times New Roman"/><w:panose-1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="default"/><w:sig w:usb-0="00000003" w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="00000001" w:csb-1="00000000"/></w:font></w:fonts><w:lists><w:listDef w:listDefId="0"><w:lsid w:val="051F140B"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="56CC694C"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="1"><w:lsid w:val="27052676"/><w:plt w:val="Multilevel"/><w:tmpl w:val="53543520"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:pStyle w:val="Heading1"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1. "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="461" w:hanging="461"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1"><w:start w:val="1"/><w:pStyle w:val="Heading2"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="734" w:hanging="734"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2"><w:start w:val="1"/><w:pStyle w:val="Heading3"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="1066" w:hanging="1066"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3"><w:start w:val="1"/><w:pStyle w:val="Heading4"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="1397" w:hanging="1397"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4"><w:start w:val="1"/><w:pStyle w:val="Heading5"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="1742" w:hanging="1742"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5"><w:start w:val="1"/><w:pStyle w:val="Heading6"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2074" w:hanging="2074"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6"><w:start w:val="1"/><w:pStyle w:val="Heading7"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2405" w:hanging="2405"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7"><w:start w:val="1"/><w:pStyle w:val="Heading8"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2736" w:hanging="2736"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8"><w:start w:val="1"/><w:pStyle w:val="Heading9"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8.%9 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="3082" w:hanging="3082"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="2"><w:lsid w:val="28F27417"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="DE367966"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="3"><w:lsid w:val="6A186F94"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="BACCBC98"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="4"><w:lsid w:val="74E71559"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="36E2C870"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="5"><w:lsid w:val="797F5C7B"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="5CF487D8"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:list w:ilfo="1"><w:ilst w:val="1"/></w:list><w:list w:ilfo="2"><w:ilst w:val="2"/></w:list><w:list w:ilfo="3"><w:ilst w:val="5"/></w:list><w:list w:ilfo="4"><w:ilst w:val="0"/></w:list><w:list w:ilfo="5"><w:ilst w:val="4"/></w:list><w:list w:ilfo="6"><w:ilst w:val="3"/></w:list></w:lists><w:styles><w:versionOfBuiltInStylenames w:val="4"/><w:latentStyles w:defLockedState="off" w:latentStyleCount="156"/><w:style w:type="paragraph" w:default="on" w:styleId="Normal"><w:name w:val="Normal"/><w:rsid w:val="00E1538C"/><w:rPr><wx:font wx:val="Times New Roman"/><w:sz w:val="24"/><w:sz-cs w:val="24"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/><wx:uiName wx:val="Heading 1"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading1"/><w:keepNext/><w:listPr><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="0"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial" w:cs="Arial"/><wx:font wx:val="Arial"/><w:b/><w:b-cs/><w:kern w:val="32"/><w:sz w:val="32"/><w:sz-cs w:val="32"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading2"><w:name w:val="heading 2"/><wx:uiName wx:val="Heading 2"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading2"/><w:keepNext/><w:listPr><w:ilvl w:val="1"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="1"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial" w:cs="Arial"/><wx:font wx:val="Arial"/><w:b/><w:b-cs/><w:i/><w:i-cs/><w:sz w:val="28"/><w:sz-cs w:val="28"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading3"><w:name w:val="heading 3"/><wx:uiName wx:val="Heading 3"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading3"/><w:keepNext/><w:listPr><w:ilvl w:val="2"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="2"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial" w:cs="Arial"/><wx:font wx:val="Arial"/><w:b/><w:b-cs/><w:sz w:val="26"/><w:sz-cs w:val="26"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading4"><w:name w:val="heading 4"/><wx:uiName wx:val="Heading 4"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading4"/><w:keepNext/><w:listPr><w:ilvl w:val="3"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="3"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:b-cs/><w:sz w:val="28"/><w:sz-cs w:val="28"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading5"><w:name w:val="heading 5"/><wx:uiName wx:val="Heading 5"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading5"/><w:listPr><w:ilvl w:val="4"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="4"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:b-cs/><w:i/><w:i-cs/><w:sz w:val="26"/><w:sz-cs w:val="26"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading6"><w:name w:val="heading 6"/><wx:uiName wx:val="Heading 6"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading6"/><w:listPr><w:ilvl w:val="5"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="5"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:b-cs/><w:sz w:val="22"/><w:sz-cs w:val="22"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading7"><w:name w:val="heading 7"/><wx:uiName wx:val="Heading 7"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading7"/><w:listPr><w:ilvl w:val="6"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="6"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading8"><w:name w:val="heading 8"/><wx:uiName wx:val="Heading 8"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading8"/><w:listPr><w:ilvl w:val="7"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="7"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:i/><w:i-cs/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading9"><w:name w:val="heading 9"/><wx:uiName wx:val="Heading 9"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading9"/><w:listPr><w:ilvl w:val="8"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="8"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial" w:cs="Arial"/><wx:font wx:val="Arial"/><w:sz w:val="22"/><w:sz-cs w:val="22"/></w:rPr></w:style><w:style w:type="character" w:default="on" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:semiHidden/></w:style><w:style w:type="table" w:default="on" w:styleId="TableNormal"><w:name w:val="Normal Table"/><wx:uiName wx:val="Table Normal"/><w:semiHidden/><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="list" w:default="on" w:styleId="NoList"><w:name w:val="No List"/><w:semiHidden/></w:style><w:style w:type="paragraph" w:styleId="Default"><w:name w:val="Default"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Default"/><w:widowControl w:val="off"/><w:autoSpaceDE w:val="off"/><w:autoSpaceDN w:val="off"/><w:adjustRightInd w:val="off"/></w:pPr><w:rPr><w:rFonts w:ascii="APOBEE+TimesNewRoman,Bold" w:h-ansi="APOBEE+TimesNewRoman,Bold" w:cs="APOBEE+TimesNewRoman,Bold"/><wx:font wx:val="APOBEE+TimesNewRoman,Bold"/><w:color w:val="000000"/><w:sz w:val="24"/><w:sz-cs w:val="24"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style></w:styles><w:docPr><w:view w:val="normal"/><w:zoom w:percent="100"/><w:displayBackgroundShape/><w:doNotEmbedSystemFonts/><w:proofState w:spelling="clean" w:grammar="clean"/><w:attachedTemplate w:val=""/><w:defaultTabStop w:val="720"/><w:punctuationKerning/><w:characterSpacingControl w:val="DontCompress"/><w:optimizeForBrowser/><w:validateAgainstSchema/><w:saveInvalidXML w:val="off"/><w:ignoreMixedContent w:val="off"/><w:alwaysShowPlaceholderText w:val="off"/><w:compat><w:breakWrappedTables/><w:snapToGridInCell/><w:wrapTextWithPunct/><w:useAsianBreakRules/><w:dontGrowAutofit/></w:compat><wsp:rsids><wsp:rsidRoot wsp:val="0085555F"/><wsp:rsid wsp:val="00032983"/><wsp:rsid wsp:val="00057F8D"/><wsp:rsid wsp:val="00074DC0"/><wsp:rsid wsp:val="000B3338"/><wsp:rsid wsp:val="000C033F"/><wsp:rsid wsp:val="000C1E6F"/><wsp:rsid wsp:val="000C2E64"/><wsp:rsid wsp:val="000D7B67"/><wsp:rsid wsp:val="00121DE1"/><wsp:rsid wsp:val="00140AA7"/><wsp:rsid wsp:val="001A5C18"/><wsp:rsid wsp:val="001C0EA3"/><wsp:rsid wsp:val="001F44D7"/><wsp:rsid wsp:val="002417BF"/><wsp:rsid wsp:val="00246911"/><wsp:rsid wsp:val="0026273B"/><wsp:rsid wsp:val="0026750B"/><wsp:rsid wsp:val="002A4BDF"/><wsp:rsid wsp:val="002E251C"/><wsp:rsid wsp:val="00322364"/><wsp:rsid wsp:val="00333DE9"/><wsp:rsid wsp:val="00345668"/><wsp:rsid wsp:val="00381AD0"/><wsp:rsid wsp:val="00385A5D"/><wsp:rsid wsp:val="003A0B4B"/><wsp:rsid wsp:val="003E0161"/><wsp:rsid wsp:val="00402D48"/><wsp:rsid wsp:val="00416C9D"/><wsp:rsid wsp:val="00420233"/><wsp:rsid wsp:val="0061272D"/><wsp:rsid wsp:val="006141BE"/><wsp:rsid wsp:val="00633862"/><wsp:rsid wsp:val="0066564A"/><wsp:rsid wsp:val="00676F12"/><wsp:rsid wsp:val="00747618"/><wsp:rsid wsp:val="00763A67"/><wsp:rsid wsp:val="00784E1D"/><wsp:rsid wsp:val="00791E6A"/><wsp:rsid wsp:val="007A69F5"/><wsp:rsid wsp:val="007E6A54"/><wsp:rsid wsp:val="007F3A83"/><wsp:rsid wsp:val="0081123D"/><wsp:rsid wsp:val="00820625"/><wsp:rsid wsp:val="008376DC"/><wsp:rsid wsp:val="00850AC3"/><wsp:rsid wsp:val="0085555F"/><wsp:rsid wsp:val="00872E7A"/><wsp:rsid wsp:val="00872F8E"/><wsp:rsid wsp:val="008A35E9"/><wsp:rsid wsp:val="00932EF4"/><wsp:rsid wsp:val="00A4305E"/><wsp:rsid wsp:val="00A51DE8"/><wsp:rsid wsp:val="00A540B8"/><wsp:rsid wsp:val="00A569AD"/><wsp:rsid wsp:val="00AB1386"/><wsp:rsid wsp:val="00AD7FD0"/><wsp:rsid wsp:val="00AF2E8E"/><wsp:rsid wsp:val="00B21FF0"/><wsp:rsid wsp:val="00B327AE"/><wsp:rsid wsp:val="00B62463"/><wsp:rsid wsp:val="00B91691"/><wsp:rsid wsp:val="00B93554"/><wsp:rsid wsp:val="00BF020D"/><wsp:rsid wsp:val="00C04D90"/><wsp:rsid wsp:val="00C25C84"/><wsp:rsid wsp:val="00C54B54"/><wsp:rsid wsp:val="00CC1964"/><wsp:rsid wsp:val="00CD088E"/><wsp:rsid wsp:val="00CE3D5F"/><wsp:rsid wsp:val="00D17844"/><wsp:rsid wsp:val="00D2292E"/><wsp:rsid wsp:val="00D30EC1"/><wsp:rsid wsp:val="00D35D56"/><wsp:rsid wsp:val="00D72411"/><wsp:rsid wsp:val="00DB754D"/><wsp:rsid wsp:val="00DC28CF"/><wsp:rsid wsp:val="00E034A8"/><wsp:rsid wsp:val="00E1538C"/><wsp:rsid wsp:val="00E8683A"/><wsp:rsid wsp:val="00EA00A4"/><wsp:rsid wsp:val="00EB184C"/><wsp:rsid wsp:val="00EB1B08"/><wsp:rsid wsp:val="00EE2795"/><wsp:rsid wsp:val="00EF3917"/><wsp:rsid wsp:val="00F4296D"/><wsp:rsid wsp:val="00F53898"/><wsp:rsid wsp:val="00F549F0"/><wsp:rsid wsp:val="00F7158B"/><wsp:rsid wsp:val="00FC1791"/><wsp:rsid wsp:val="00FD5B6E"/><wsp:rsid wsp:val="00FE71C8"/><wsp:rsid wsp:val="00FF16F2"/></wsp:rsids></w:docPr><w:body><wx:sect><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="001A5C18" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading1"/><w:listPr><wx:t wx:val="1. "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Subsystem</w:t></w:r><w:r wsp:rsidR="00E1538C"><w:t> </w:t></w:r><w:r wsp:rsidR="00E1538C" wsp:rsidRPr="00174D8A"><w:t>Requirements </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00174D8A"><w:t>Robot API</w:t></w:r></w:p><w:p wsp:rsidR="001A5C18" wsp:rsidRPr="001A5C18" wsp:rsidRDefault="001A5C18" wsp:rsidP="001A5C18"><w:r><w:t>The </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>robot Application Programming Interface with provide</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> the software interface to all robots attached to the system.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Video processing</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Video C</w:t></w:r><w:r wsp:rsidRPr="00A04D4C"><w:t>apture</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>The system shall include hardware to capture video images from a number of sources, including stereo cameras and ultrasound. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00A04D4C"><w:t>3D surface reconstruction</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>The software shall include a method for 3D surface reconstruction from</w:t></w:r><w:r><w:t> stereo video images (see 4.3).</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>V</w:t></w:r><w:r wsp:rsidRPr="00A04D4C"><w:t>olumetric </w:t></w:r><w:r><w:t>I</w:t></w:r><w:r wsp:rsidRPr="00A04D4C"><w:t>mages</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>In addition to video, the software shall accept inputs from other sources, such as prior volumetric images and models. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Video Files</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>The software should work with recorded data (e.g., video files). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Frame Synchronization</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>The software shall have a method for synchronizing the video frames to other data, such as robot feedback (see 4.7.7). One possibility is to utilize an image format that enables additional information to be stored as meta-data. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Other device interfaces </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.3.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00A04D4C"><w:t>Input Devices</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall provide interfaces to various user input devices, such as foot pedals, switches, and buttons (including those on the </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>daVinci</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> master console). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.3.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>S</w:t></w:r><w:r wsp:rsidRPr="00A04D4C"><w:t>ensors</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall provide an interface to sensors that can measure forces and torques, including full 6-dof force/torque data. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.3.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00A04D4C"><w:t>Additional Device Integration</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The architecture shall be extensible, allowing the integration of other devices not yet specified. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration and registration</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.4.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall support calibration of the following: </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Ultrasound probe</w:t></w:r></w:p><w:proofErr w:type="gramStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>Position/orientation of the 2D image plane with respect to a 3D reference frame on the probe.</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Camera calibration (intrinsic)</w:t></w:r></w:p><w:proofErr w:type="gramStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The determination of camera parameters such as focal length, resolution, optical center, and lens distortion.</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Stereo camera calibration (extrinsic)</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:rPr><w:rFonts w:ascii="APODLD+TimesNewRoman,Italic" w:h-ansi="APODLD+TimesNewRoman,Italic" w:cs="APODLD+TimesNewRoman,Italic"/><wx:font wx:val="APODLD+TimesNewRoman,Italic"/></w:rPr><w:t>T</w:t></w:r><w:r><w:t>he transformation between two camera systems (or one camera moved between two positions). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Robot kinematics</w:t></w:r></w:p><w:proofErr w:type="gramStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:rPr><w:rFonts w:ascii="APODLD+TimesNewRoman,Italic" w:h-ansi="APODLD+TimesNewRoman,Italic" w:cs="APODLD+TimesNewRoman,Italic"/><wx:font wx:val="APODLD+TimesNewRoman,Italic"/></w:rPr><w:t>T</w:t></w:r><w:r><w:t>he transformation between a frame on the final link of the robot and a frame on the base of the robot.</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Tool tip</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:rPr><w:rFonts w:ascii="APODLD+TimesNewRoman,Italic" w:h-ansi="APODLD+TimesNewRoman,Italic" w:cs="APODLD+TimesNewRoman,Italic"/><wx:font wx:val="APODLD+TimesNewRoman,Italic"/></w:rPr><w:t>T</w:t></w:r><w:r><w:t>he transformation between a frame on the tip of a (rigid) tool and a frame defined elsewhere on the tool. This calibration may not require a full transformation; for example, a translation vector is sufficient if only the tip position is required. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.4.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration Methods</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall support each calibration listed under “</w:t></w:r><w:r wsp:rsidRPr="007704C0"><w:t>Calibration</w:t></w:r><w:r><w:t>” by providing the following: </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.2.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Data Collection</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>system may</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> (optionally) provide functions for collecting calibration data. Otherwise, this can be provided by external software. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.2.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration Parameters</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>system may</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> (optionally) provide functions to compute the calibration parameters. Otherwise, this can be done by external software (e.g., </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:t>Matlab</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:t> program). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.2.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration Results</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall have a method for using the results of the calibration (e.g., by reading the results from a file). </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.4.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Registration</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.3.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Coordinate Systems Registration</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall provide routines to register the following coordinate systems (i.e., find the transformation from one coordinate system to another coordinate system): </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>stereo video image </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>ultrasound image </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>preoperative image (e.g., CT) or model (e.g., segmented volume) </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>robot </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>external measurement device (e.g., </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:t>Optotrak</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:t>) </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>Registration between any two of these coordinate systems shall either be computed directly or obtained by composition of two or more known registrations. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.4.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Coordinate Computation Methods</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall provide implementations of the following coordinate computation methods (for calibration and/or registration): </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Pivot Calibration</w:t></w:r></w:p><w:proofErr w:type="gramStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>A “pivot calibration” method, where the transformation is computed from data obtained by pivoting a tool about a fixed position.</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Paired-point Rigid Registration</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>Paired-point rigid registration, using a method such as the one proposed in Reference 2.2.1 or in Reference 2.2.2 (enhanced in Reference 2.2.3). </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading5"/><w:listPr><wx:t wx:val="1.4.4.2.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>External Measurement</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>This method may be used to register the robot to the external measurement device. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading5"/><w:listPr><wx:t wx:val="1.4.4.2.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Preoperative Image</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>This method may be used to register the preoperative image or model to the robot or external measurement device. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Iterative methods for registering sets of points/surfaces</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>An example is the Iterative Closest Point (ICP) algorithm proposed in Reference </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>2.2.5. This method may be used to register prior models to the anatomy without requiring </w:t></w:r><w:proofErr w:type="spellStart"/><w:proofErr w:type="gramStart"/><w:r><w:t>fiducials</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:t> .</w:t></w:r><w:proofErr w:type="gramEnd"/></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Matrix Equation</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>Solving the matrix equation AX = XB, where </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>A and</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> B are known and X is unknown. This method may be used for ultrasound calibration (see Reference 2.2.4). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Deformable (non-rigid) registration </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>This method may be used for video overlay on organs. </w:t></w:r></w:p></wx:sub-section></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Tool tracking</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.5.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Tool Positions/Orientations</w:t></w:r><w:r wsp:rsidRPr="007704C0"><w:t> </w:t></w:r><w:r><w:t>Estimation</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall be able to estimate tool positions/orientations using a combination of stereo video images and joint encoder feedback. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.5.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Position Prediction</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall be able to predict the position and shape of tools in the 3D frames (i.e., to provide input to the video rendering). </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.6 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>User Interface (Visualization) </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Supported Hardware</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall contain hardware to display the captured stereo images</w:t></w:r><w:r><w:rPr><w:color w:val="auto"/></w:rPr><w:t>. </w:t></w:r><w:r><w:rPr><w:color w:val="auto"/></w:rPr><w:tab wx:wTab="525" wx:tlc="none" wx:cTlc="8"/></w:r><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>At a minimum, the following hardware shall be supported: </w:t></w:r></w:p><w:proofErr w:type="spellStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="3"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>daVinci</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> master console display </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="3"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Head-mounted display </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Windowing System</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall include a windowing system to: </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="4"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Manage the display of multiple windows. </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="4"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Render visual objects, including menus, buttons, toolbars, and images (see 4.6.3), in the 3D viewing space. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Image Rendering</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall be capable of rendering the following images: </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="5"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>2D images </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="5"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>3D volume models </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="5"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>3D surface models </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="5"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>2D image projected onto a 3D plane (e.g., laparoscopic ultrasound) </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Image Fusion</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall be capable of performing image fusion, i.e., the ability to combine multiple images with different blending/overlay parameters. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Object Manipulation</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall support the manipulation of virtual objects in the surgeon’s field of view, where the virtual objects may be 2D or 3D images or models, or widgets such as “in volume” menus and virtual push-buttons, and similar functions. The manipulation functions shall be designed to accept position/orientation inputs from a generic user input device. One embodiment shall include the </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>daVinci</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> master </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>telemanipulators</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> and associated surgeon console controls. The manipulation functions shall include controls for manipulating the virtual objects (e.g., repositioning, rotating, scaling) and for turning them on and off. </w:t></w:r></w:p><w:proofErr w:type="spellStart"/></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.7 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Telesurgery</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r wsp:rsidRPr="007704C0"><w:t> application framework </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall integrate all functions listed above. </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Event Loop</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall contain an event loop to handle events from the subsystem components.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Video Data Pipeline</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall include a real-time data pipeline that can be used by video processing subsystem (4.2). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>CISST</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall include the CISST Interactive Research Environment (IRE), which is a Python-based shell for interactive development.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Plug-in Modules</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall allow users to dynamically load “plug-in” modules for research purposes.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Modular Architecture</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall have a modular architecture, allowing it to be implemented on different physical architectures (i.e., different boxes), within the performance (bandwidth and latency) limitations of the interconnections. Supported physical architectures shall include any of the following: </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="6"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Ultrasound acquisition on a separate computer. </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="6"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Robot control on a separate computer (e.g., </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>daVinci</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> embedded controller or external JHU controller). </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="6"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Collaborative robots controlled by different computers. </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="6"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>All functions specified in this requirement on a single PC. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.6 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Data Logging</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall include a flexible data logging mechanism to allow the recording of relevant state information, including video. This can, for example, be used for research in gesture recognition.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.7 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Time Synchronization</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The data logging shall support time synchronization, either by ensuring that all data are captured at the same time or by associating a system-wide “timestamp” with each data item. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.8 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>System Recovery</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall provide a method to save an occasional “snapshot” of the state for recovery from system restart (e.g., due to power failure, computer crash, etc.). </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.8 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Volume viewer</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.1 "/><wx:font wx:val="Times New Roman"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/></w:rPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Functions</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall be implemented using the functions specified in Section 4.6.5. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Volume Data Sets</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall provide functions for selecting and loading volume data sets from a menu of choices. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Scaling</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall provide functions for scaling the data set from </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>voxels</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> to physical coordinates and placing it at a specified position within the stereoscopic visualization coordinate system (i.e., in camera coordinates). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Fused Visualizations</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall provide functions for turning visualization on and off and providing “fused” visualizations by video blending (see Section 4.6.4). </w:t></w:r></w:p><w:proofErr w:type="spellStart"/></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Haptic</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r wsp:rsidRPr="00FD64F9"><w:t> Interaction</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall provide functions to enable </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>haptic</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> interaction with volumetric data (Phase 2) </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.6 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Motion Compensation</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall update the visualization to compensate for camera motion, so that the volumetric data set appears to be fixed to the tissue (Phase 2). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.7 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Third-party Integration</w:t></w:r></w:p><w:p wsp:rsidR="00820625" wsp:rsidRPr="001A5C18" wsp:rsidRDefault="00E1538C" wsp:rsidP="001A5C18"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:t>The interface between the input device(s) and volume viewer shall be as generic as possible to facilitate integration of third-party volume viewer software.</w:t></w:r></w:p><w:sectPr wsp:rsidR="00820625" wsp:rsidRPr="001A5C18" wsp:rsidSect="00E1538C"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1080" w:right="1080" w:bottom="1080" w:left="1080" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/><w:docGrid w:line-pitch="360"/></w:sectPr></wx:sub-section></wx:sub-section></wx:sub-section></wx:sect></w:body></w:wordDocument> \ No newline at end of file
+<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:wsp="http://schemas.microsoft.com/office/word/2003/wordml/sp2" w:macrosPresent="no" w:embeddedObjPresent="no" w:ocxPresent="no" xml:space="preserve"><w:ignoreElements w:val="http://schemas.microsoft.com/office/word/2003/wordml/sp2"/><o:DocumentProperties><o:Author>Ryan D. Brooks</o:Author><o:LastAuthor>Ryan D. Brooks</o:LastAuthor><o:Revision>3</o:Revision><o:TotalTime>4</o:TotalTime><o:Created>2007-11-08T00:23:00Z</o:Created><o:LastSaved>2007-11-08T00:57:00Z</o:LastSaved><o:Pages>6</o:Pages><o:Words>1398</o:Words><o:Characters>7969</o:Characters><o:Company>The Boeing Company</o:Company><o:Lines>66</o:Lines><o:Paragraphs>18</o:Paragraphs><o:CharactersWithSpaces>9349</o:CharactersWithSpaces><o:Version>11.8134</o:Version></o:DocumentProperties><w:fonts><w:defaultFonts w:ascii="Times New Roman" w:fareast="Times New Roman" w:h-ansi="Times New Roman" w:cs="Times New Roman"/><w:font w:name="Wingdings"><w:panose-1 w:val="05000000000000000000"/><w:charset w:val="02"/><w:family w:val="Auto"/><w:pitch w:val="variable"/><w:sig w:usb-0="00000000" w:usb-1="10000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="80000000" w:csb-1="00000000"/></w:font><w:font w:name="APODLF+TimesNewRoman"><w:altName w:val="Times New Roman"/><w:panose-1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="default"/><w:sig w:usb-0="00000003" w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="00000001" w:csb-1="00000000"/></w:font><w:font w:name="APOBEE+TimesNewRoman,Bold"><w:altName w:val="Times New Roman"/><w:panose-1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="default"/><w:sig w:usb-0="00000003" w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="00000001" w:csb-1="00000000"/></w:font><w:font w:name="APODLD+TimesNewRoman,Italic"><w:altName w:val="Times New Roman"/><w:panose-1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="default"/><w:sig w:usb-0="00000003" w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="00000001" w:csb-1="00000000"/></w:font></w:fonts><w:lists><w:listDef w:listDefId="0"><w:lsid w:val="051F140B"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="56CC694C"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="1"><w:lsid w:val="27052676"/><w:plt w:val="Multilevel"/><w:tmpl w:val="53543520"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:pStyle w:val="Heading1"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1. "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="461" w:hanging="461"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1"><w:start w:val="1"/><w:pStyle w:val="Heading2"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="734" w:hanging="734"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2"><w:start w:val="1"/><w:pStyle w:val="Heading3"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="1066" w:hanging="1066"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3"><w:start w:val="1"/><w:pStyle w:val="Heading4"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="1397" w:hanging="1397"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4"><w:start w:val="1"/><w:pStyle w:val="Heading5"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="1742" w:hanging="1742"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5"><w:start w:val="1"/><w:pStyle w:val="Heading6"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2074" w:hanging="2074"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6"><w:start w:val="1"/><w:pStyle w:val="Heading7"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2405" w:hanging="2405"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7"><w:start w:val="1"/><w:pStyle w:val="Heading8"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="2736" w:hanging="2736"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8"><w:start w:val="1"/><w:pStyle w:val="Heading9"/><w:suff w:val="Nothing"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8.%9 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="3082" w:hanging="3082"/></w:pPr><w:rPr><w:rFonts w:cs="Times New Roman" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="2"><w:lsid w:val="28F27417"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="DE367966"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="3"><w:lsid w:val="6A186F94"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="BACCBC98"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="4"><w:lsid w:val="74E71559"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="36E2C870"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="5"><w:lsid w:val="797F5C7B"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="5CF487D8"/><w:lvl w:ilvl="0" w:tplc="04090005"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:list w:ilfo="1"><w:ilst w:val="1"/></w:list><w:list w:ilfo="2"><w:ilst w:val="2"/></w:list><w:list w:ilfo="3"><w:ilst w:val="5"/></w:list><w:list w:ilfo="4"><w:ilst w:val="0"/></w:list><w:list w:ilfo="5"><w:ilst w:val="4"/></w:list><w:list w:ilfo="6"><w:ilst w:val="3"/></w:list></w:lists><w:styles><w:versionOfBuiltInStylenames w:val="4"/><w:latentStyles w:defLockedState="off" w:latentStyleCount="156"/><w:style w:type="paragraph" w:default="on" w:styleId="Normal"><w:name w:val="Normal"/><w:rsid w:val="00E1538C"/><w:rPr><wx:font wx:val="Times New Roman"/><w:sz w:val="24"/><w:sz-cs w:val="24"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/><wx:uiName wx:val="Heading 1"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading1"/><w:keepNext/><w:listPr><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="0"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial" w:cs="Arial"/><wx:font wx:val="Arial"/><w:b/><w:b-cs/><w:kern w:val="32"/><w:sz w:val="32"/><w:sz-cs w:val="32"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading2"><w:name w:val="heading 2"/><wx:uiName wx:val="Heading 2"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading2"/><w:keepNext/><w:listPr><w:ilvl w:val="1"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="1"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial" w:cs="Arial"/><wx:font wx:val="Arial"/><w:b/><w:b-cs/><w:i/><w:i-cs/><w:sz w:val="28"/><w:sz-cs w:val="28"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading3"><w:name w:val="heading 3"/><wx:uiName wx:val="Heading 3"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading3"/><w:keepNext/><w:listPr><w:ilvl w:val="2"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="2"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial" w:cs="Arial"/><wx:font wx:val="Arial"/><w:b/><w:b-cs/><w:sz w:val="26"/><w:sz-cs w:val="26"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading4"><w:name w:val="heading 4"/><wx:uiName wx:val="Heading 4"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading4"/><w:keepNext/><w:listPr><w:ilvl w:val="3"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="3"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:b-cs/><w:sz w:val="28"/><w:sz-cs w:val="28"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading5"><w:name w:val="heading 5"/><wx:uiName wx:val="Heading 5"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading5"/><w:listPr><w:ilvl w:val="4"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="4"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:b-cs/><w:i/><w:i-cs/><w:sz w:val="26"/><w:sz-cs w:val="26"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading6"><w:name w:val="heading 6"/><wx:uiName wx:val="Heading 6"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading6"/><w:listPr><w:ilvl w:val="5"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="5"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:b-cs/><w:sz w:val="22"/><w:sz-cs w:val="22"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading7"><w:name w:val="heading 7"/><wx:uiName wx:val="Heading 7"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading7"/><w:listPr><w:ilvl w:val="6"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="6"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading8"><w:name w:val="heading 8"/><wx:uiName wx:val="Heading 8"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading8"/><w:listPr><w:ilvl w:val="7"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="7"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:i/><w:i-cs/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading9"><w:name w:val="heading 9"/><wx:uiName wx:val="Heading 9"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Heading9"/><w:listPr><w:ilvl w:val="8"/><w:ilfo w:val="1"/></w:listPr><w:spacing w:before="240" w:after="60"/><w:outlineLvl w:val="8"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial" w:cs="Arial"/><wx:font wx:val="Arial"/><w:sz w:val="22"/><w:sz-cs w:val="22"/></w:rPr></w:style><w:style w:type="character" w:default="on" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:semiHidden/></w:style><w:style w:type="table" w:default="on" w:styleId="TableNormal"><w:name w:val="Normal Table"/><wx:uiName wx:val="Table Normal"/><w:semiHidden/><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="list" w:default="on" w:styleId="NoList"><w:name w:val="No List"/><w:semiHidden/></w:style><w:style w:type="paragraph" w:styleId="Default"><w:name w:val="Default"/><w:rsid w:val="00E1538C"/><w:pPr><w:pStyle w:val="Default"/><w:widowControl w:val="off"/><w:autoSpaceDE w:val="off"/><w:autoSpaceDN w:val="off"/><w:adjustRightInd w:val="off"/></w:pPr><w:rPr><w:rFonts w:ascii="APOBEE+TimesNewRoman,Bold" w:h-ansi="APOBEE+TimesNewRoman,Bold" w:cs="APOBEE+TimesNewRoman,Bold"/><wx:font wx:val="APOBEE+TimesNewRoman,Bold"/><w:color w:val="000000"/><w:sz w:val="24"/><w:sz-cs w:val="24"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style></w:styles><w:docPr><w:view w:val="normal"/><w:zoom w:percent="100"/><w:displayBackgroundShape/><w:doNotEmbedSystemFonts/><w:proofState w:spelling="clean" w:grammar="clean"/><w:attachedTemplate w:val=""/><w:defaultTabStop w:val="720"/><w:punctuationKerning/><w:characterSpacingControl w:val="DontCompress"/><w:optimizeForBrowser/><w:validateAgainstSchema/><w:saveInvalidXML w:val="off"/><w:ignoreMixedContent w:val="off"/><w:alwaysShowPlaceholderText w:val="off"/><w:compat><w:breakWrappedTables/><w:snapToGridInCell/><w:wrapTextWithPunct/><w:useAsianBreakRules/><w:dontGrowAutofit/></w:compat><wsp:rsids><wsp:rsidRoot wsp:val="0085555F"/><wsp:rsid wsp:val="00032983"/><wsp:rsid wsp:val="00057F8D"/><wsp:rsid wsp:val="00074DC0"/><wsp:rsid wsp:val="000B3338"/><wsp:rsid wsp:val="000C033F"/><wsp:rsid wsp:val="000C1E6F"/><wsp:rsid wsp:val="000C2E64"/><wsp:rsid wsp:val="000D7B67"/><wsp:rsid wsp:val="00121DE1"/><wsp:rsid wsp:val="00140AA7"/><wsp:rsid wsp:val="001A5C18"/><wsp:rsid wsp:val="001C0EA3"/><wsp:rsid wsp:val="001F44D7"/><wsp:rsid wsp:val="002417BF"/><wsp:rsid wsp:val="00246911"/><wsp:rsid wsp:val="0026273B"/><wsp:rsid wsp:val="0026750B"/><wsp:rsid wsp:val="002A4BDF"/><wsp:rsid wsp:val="002E251C"/><wsp:rsid wsp:val="00322364"/><wsp:rsid wsp:val="00333DE9"/><wsp:rsid wsp:val="00345668"/><wsp:rsid wsp:val="00381AD0"/><wsp:rsid wsp:val="00385A5D"/><wsp:rsid wsp:val="003A0B4B"/><wsp:rsid wsp:val="003E0161"/><wsp:rsid wsp:val="00402D48"/><wsp:rsid wsp:val="00416C9D"/><wsp:rsid wsp:val="00420233"/><wsp:rsid wsp:val="0061272D"/><wsp:rsid wsp:val="006141BE"/><wsp:rsid wsp:val="00633862"/><wsp:rsid wsp:val="0066564A"/><wsp:rsid wsp:val="00676F12"/><wsp:rsid wsp:val="00747618"/><wsp:rsid wsp:val="00763A67"/><wsp:rsid wsp:val="00784E1D"/><wsp:rsid wsp:val="00791E6A"/><wsp:rsid wsp:val="007A69F5"/><wsp:rsid wsp:val="007E6A54"/><wsp:rsid wsp:val="007F3A83"/><wsp:rsid wsp:val="0081123D"/><wsp:rsid wsp:val="00820625"/><wsp:rsid wsp:val="008376DC"/><wsp:rsid wsp:val="00850AC3"/><wsp:rsid wsp:val="0085555F"/><wsp:rsid wsp:val="00872E7A"/><wsp:rsid wsp:val="00872F8E"/><wsp:rsid wsp:val="008A35E9"/><wsp:rsid wsp:val="00932EF4"/><wsp:rsid wsp:val="00A4305E"/><wsp:rsid wsp:val="00A51DE8"/><wsp:rsid wsp:val="00A540B8"/><wsp:rsid wsp:val="00A569AD"/><wsp:rsid wsp:val="00AB1386"/><wsp:rsid wsp:val="00AD7FD0"/><wsp:rsid wsp:val="00AF2E8E"/><wsp:rsid wsp:val="00B21FF0"/><wsp:rsid wsp:val="00B327AE"/><wsp:rsid wsp:val="00B62463"/><wsp:rsid wsp:val="00B91691"/><wsp:rsid wsp:val="00B93554"/><wsp:rsid wsp:val="00BF020D"/><wsp:rsid wsp:val="00C04D90"/><wsp:rsid wsp:val="00C25C84"/><wsp:rsid wsp:val="00C54B54"/><wsp:rsid wsp:val="00CC1964"/><wsp:rsid wsp:val="00CD088E"/><wsp:rsid wsp:val="00CE3D5F"/><wsp:rsid wsp:val="00D17844"/><wsp:rsid wsp:val="00D2292E"/><wsp:rsid wsp:val="00D30EC1"/><wsp:rsid wsp:val="00D35D56"/><wsp:rsid wsp:val="00D72411"/><wsp:rsid wsp:val="00DB754D"/><wsp:rsid wsp:val="00DC28CF"/><wsp:rsid wsp:val="00E034A8"/><wsp:rsid wsp:val="00E1538C"/><wsp:rsid wsp:val="00E8683A"/><wsp:rsid wsp:val="00EA00A4"/><wsp:rsid wsp:val="00EB184C"/><wsp:rsid wsp:val="00EB1B08"/><wsp:rsid wsp:val="00EE2795"/><wsp:rsid wsp:val="00EF3917"/><wsp:rsid wsp:val="00F4296D"/><wsp:rsid wsp:val="00F53898"/><wsp:rsid wsp:val="00F549F0"/><wsp:rsid wsp:val="00F7158B"/><wsp:rsid wsp:val="00FC1791"/><wsp:rsid wsp:val="00FD5B6E"/><wsp:rsid wsp:val="00FE71C8"/><wsp:rsid wsp:val="00FF16F2"/></wsp:rsids></w:docPr><w:body><wx:sect><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="001A5C18" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading1"/><w:listPr><wx:t wx:val="1. "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Subsystem</w:t></w:r><w:r wsp:rsidR="00E1538C"><w:t> </w:t></w:r><w:r wsp:rsidR="00E1538C" wsp:rsidRPr="00174D8A"><w:t>Requirements </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00174D8A"><w:t>Robot API</w:t></w:r></w:p><w:p wsp:rsidR="001A5C18" wsp:rsidRPr="001A5C18" wsp:rsidRDefault="001A5C18" wsp:rsidP="001A5C18"><w:r><w:t>The </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>robot Application Programming Interface with provide</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> the software interface to all robots attached to the system.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Video processing</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Video C</w:t></w:r><w:r wsp:rsidRPr="00A04D4C"><w:t>apture</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>The system shall include hardware to capture video images from a number of sources, including stereo cameras and ultrasound. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00A04D4C"><w:t>3D surface reconstruction</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>The software shall include a method for 3D surface reconstruction from</w:t></w:r><w:r><w:t> stereo video images (see 4.3).</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>V</w:t></w:r><w:r wsp:rsidRPr="00A04D4C"><w:t>olumetric </w:t></w:r><w:r><w:t>I</w:t></w:r><w:r wsp:rsidRPr="00A04D4C"><w:t>mages</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>In addition to video, the software shall accept inputs from other sources, such as prior volumetric images and models. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Video Files</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>The software should work with recorded data (e.g., video files). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.2.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Frame Synchronization</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r wsp:rsidRPr="00A04D4C"><w:t>The software shall have a method for synchronizing the video frames to other data, such as robot feedback (see 4.7.7). One possibility is to utilize an image format that enables additional information to be stored as meta-data. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Other device interfaces </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.3.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00A04D4C"><w:t>Input Devices</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall provide interfaces to various user input devices, such as foot pedals, switches, and buttons (including those on the </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>daVinci</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> master console). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.3.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>S</w:t></w:r><w:r wsp:rsidRPr="00A04D4C"><w:t>ensors</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall provide an interface to sensors that can measure forces and torques, including full 6-dof force/torque data. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00A04D4C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.3.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00A04D4C"><w:t>Additional Device Integration</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The architecture shall be extensible, allowing the integration of other devices not yet specified. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration and registration</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.4.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall support calibration of the following: </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Ultrasound probe</w:t></w:r></w:p><w:proofErr w:type="gramStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>Position/orientation of the 2D image plane with respect to a 3D reference frame on the probe.</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Camera calibration (intrinsic)</w:t></w:r></w:p><w:proofErr w:type="gramStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The determination of camera parameters such as focal length, resolution, optical center, and lens distortion.</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Stereo camera calibration (extrinsic)</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:rPr><w:rFonts w:ascii="APODLD+TimesNewRoman,Italic" w:h-ansi="APODLD+TimesNewRoman,Italic" w:cs="APODLD+TimesNewRoman,Italic"/><wx:font wx:val="APODLD+TimesNewRoman,Italic"/></w:rPr><w:t>T</w:t></w:r><w:r><w:t>he transformation between two camera systems (or one camera moved between two positions). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Robot kinematics</w:t></w:r></w:p><w:proofErr w:type="gramStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:rPr><w:rFonts w:ascii="APODLD+TimesNewRoman,Italic" w:h-ansi="APODLD+TimesNewRoman,Italic" w:cs="APODLD+TimesNewRoman,Italic"/><wx:font wx:val="APODLD+TimesNewRoman,Italic"/></w:rPr><w:t>T</w:t></w:r><w:r><w:t>he transformation between a frame on the final link of the robot and a frame on the base of the robot.</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.1.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Tool tip</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:rPr><w:rFonts w:ascii="APODLD+TimesNewRoman,Italic" w:h-ansi="APODLD+TimesNewRoman,Italic" w:cs="APODLD+TimesNewRoman,Italic"/><wx:font wx:val="APODLD+TimesNewRoman,Italic"/></w:rPr><w:t>T</w:t></w:r><w:r><w:t>he transformation between a frame on the tip of a (rigid) tool and a frame defined elsewhere on the tool. This calibration may not require a full transformation; for example, a translation vector is sufficient if only the tip position is required. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.4.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration Methods</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall support each calibration listed under “</w:t></w:r><w:r wsp:rsidRPr="007704C0"><w:t>Calibration</w:t></w:r><w:r><w:t>” by providing the following: </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.2.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Data Collection</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>system may</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> (optionally) provide functions for collecting calibration data. Otherwise, this can be provided by external software. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.2.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration Parameters</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>system may</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> (optionally) provide functions to compute the calibration parameters. Otherwise, this can be done by external software (e.g., </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:t>Matlab</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:t> program). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.2.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Calibration Results</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall have a method for using the results of the calibration (e.g., by reading the results from a file). </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.4.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Registration</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.3.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Coordinate Systems Registration</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall provide routines to register the following coordinate systems (i.e., find the transformation from one coordinate system to another coordinate system): </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>stereo video image </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>ultrasound image </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>preoperative image (e.g., CT) or model (e.g., segmented volume) </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>robot </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="2"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr></w:pPr><w:r><w:t>external measurement device (e.g., </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:t>Optotrak</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:t>) </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>Registration between any two of these coordinate systems shall either be computed directly or obtained by composition of two or more known registrations. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.4.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Coordinate Computation Methods</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>The system shall provide implementations of the following coordinate computation methods (for calibration and/or registration): </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Pivot Calibration</w:t></w:r></w:p><w:proofErr w:type="gramStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>A “pivot calibration” method, where the transformation is computed from data obtained by pivoting a tool about a fixed position.</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Paired-point Rigid Registration</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>Paired-point rigid registration, using a method such as the one proposed in Reference 2.2.1 or in Reference 2.2.2 (enhanced in Reference 2.2.3). </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading5"/><w:listPr><wx:t wx:val="1.4.4.2.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>External Measurement</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>This method may be used to register the robot to the external measurement device. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading5"/><w:listPr><wx:t wx:val="1.4.4.2.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Preoperative Image</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>This method may be used to register the preoperative image or model to the robot or external measurement device. </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Iterative methods for registering sets of points/surfaces</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>An example is the Iterative Closest Point (ICP) algorithm proposed in Reference </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>This method may be used to register prior models to the anatomy without requiring </w:t></w:r><w:proofErr w:type="spellStart"/><w:proofErr w:type="gramStart"/><w:r><w:t>fiducials</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:t> .</w:t></w:r><w:proofErr w:type="gramEnd"/></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Matrix Equation</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>Solving the matrix equation AX = XB, where </w:t></w:r><w:proofErr w:type="gramStart"/><w:r><w:t>A and</w:t></w:r><w:proofErr w:type="gramEnd"/><w:r><w:t> B are known and X is unknown. This method may be used for ultrasound calibration (see Reference 2.2.4). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><wx:t wx:val="1.4.4.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Deformable (non-rigid) registration </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:r><w:t>This method may be used for video overlay on organs. </w:t></w:r></w:p></wx:sub-section></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Tool tracking</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.5.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Tool Positions/Orientations</w:t></w:r><w:r wsp:rsidRPr="007704C0"><w:t> </w:t></w:r><w:r><w:t>Estimation</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall be able to estimate tool positions/orientations using a combination of stereo video images and joint encoder feedback. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="007704C0" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.5.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Position Prediction</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall be able to predict the position and shape of tools in the 3D frames (i.e., to provide input to the video rendering). </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.6 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>User Interface (Visualization) </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Supported Hardware</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall contain hardware to display the captured stereo images</w:t></w:r><w:r><w:rPr><w:color w:val="auto"/></w:rPr><w:t>. </w:t></w:r><w:r><w:rPr><w:color w:val="auto"/></w:rPr><w:tab wx:wTab="525" wx:tlc="none" wx:cTlc="8"/></w:r><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>At a minimum, the following hardware shall be supported: </w:t></w:r></w:p><w:proofErr w:type="spellStart"/><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="3"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>daVinci</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> master console display </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="3"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Head-mounted display </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Windowing System</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The software shall include a windowing system to: </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="4"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Manage the display of multiple windows. </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="4"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Render visual objects, including menus, buttons, toolbars, and images (see 4.6.3), in the 3D viewing space. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Image Rendering</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall be capable of rendering the following images: </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="5"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>2D images </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="5"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>3D volume models </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="5"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>3D surface models </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="5"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>2D image projected onto a 3D plane (e.g., laparoscopic ultrasound) </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Image Fusion</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall be capable of performing image fusion, i.e., the ability to combine multiple images with different blending/overlay parameters. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="002F3B05" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.6.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="002F3B05"><w:t>Object Manipulation</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall support the manipulation of virtual objects in the surgeon’s field of view, where the virtual objects may be 2D or 3D images or models, or widgets such as “in volume” menus and virtual push-buttons, and similar functions. The manipulation functions shall be designed to accept position/orientation inputs from a generic user input device. One embodiment shall include the </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>daVinci</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> master </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>telemanipulators</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> and associated surgeon console controls. The manipulation functions shall include controls for manipulating the virtual objects (e.g., repositioning, rotating, scaling) and for turning them on and off. </w:t></w:r></w:p><w:proofErr w:type="spellStart"/></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.7 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="007704C0"><w:t>Telesurgery</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r wsp:rsidRPr="007704C0"><w:t> application framework </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall integrate all functions listed above. </w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Event Loop</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall contain an event loop to handle events from the subsystem components.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Video Data Pipeline</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall include a real-time data pipeline that can be used by video processing subsystem (4.2). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>CISST</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall include the CISST Interactive Research Environment (IRE), which is a Python-based shell for interactive development.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Plug-in Modules</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall allow users to dynamically load “plug-in” modules for research purposes.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Modular Architecture</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall have a modular architecture, allowing it to be implemented on different physical architectures (i.e., different boxes), within the performance (bandwidth and latency) limitations of the interconnections. Supported physical architectures shall include any of the following: </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="6"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Ultrasound acquisition on a separate computer. </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="6"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Robot control on a separate computer (e.g., </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>daVinci</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> embedded controller or external JHU controller). </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="6"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>Collaborative robots controlled by different computers. </w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:listPr><w:ilvl w:val="0"/><w:ilfo w:val="6"/><wx:t wx:val="§" wx:wTabBefore="360" wx:wTabAfter="255"/><wx:font wx:val="Wingdings"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>All functions specified in this requirement on a single PC. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.6 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Data Logging</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The application framework shall include a flexible data logging mechanism to allow the recording of relevant state information, including video. This can, for example, be used for research in gesture recognition.</w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.7 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>Time Synchronization</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The data logging shall support time synchronization, either by ensuring that all data are captured at the same time or by associating a system-wide “timestamp” with each data item. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00E16903" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.7.8 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00E16903"><w:t>System Recovery</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The system shall provide a method to save an occasional “snapshot” of the state for recovery from system restart (e.g., due to power failure, computer crash, etc.). </w:t></w:r></w:p></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.8 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Volume viewer</w:t></w:r></w:p><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.1 "/><wx:font wx:val="Times New Roman"/></w:listPr><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/></w:rPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Functions</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall be implemented using the functions specified in Section 4.6.5. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.2 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Volume Data Sets</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall provide functions for selecting and loading volume data sets from a menu of choices. </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.3 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Scaling</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall provide functions for scaling the data set from </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>voxels</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> to physical coordinates and placing it at a specified position within the stereoscopic visualization coordinate system (i.e., in camera coordinates). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.4 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Fused Visualizations</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall provide functions for turning visualization on and off and providing “fused” visualizations by video blending (see Section 4.6.4). </w:t></w:r></w:p><w:proofErr w:type="spellStart"/></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.5 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Haptic</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r wsp:rsidRPr="00FD64F9"><w:t> Interaction</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall provide functions to enable </w:t></w:r><w:proofErr w:type="spellStart"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>haptic</w:t></w:r><w:proofErr w:type="spellEnd"/><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t> interaction with volumetric data (Phase 2) </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.6 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Motion Compensation</w:t></w:r></w:p><w:p wsp:rsidR="00E1538C" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr><w:t>The volume viewer shall update the visualization to compensate for camera motion, so that the volumetric data set appears to be fixed to the tissue (Phase 2). </w:t></w:r></w:p></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00E1538C" wsp:rsidRPr="00FD64F9" wsp:rsidRDefault="00E1538C" wsp:rsidP="00E1538C"><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><wx:t wx:val="1.8.7 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r wsp:rsidRPr="00FD64F9"><w:t>Third-party Integration</w:t></w:r></w:p><w:p wsp:rsidR="00820625" wsp:rsidRPr="001A5C18" wsp:rsidRDefault="00E1538C" wsp:rsidP="001A5C18"><w:pPr><w:pStyle w:val="Default"/><w:rPr><w:rFonts w:ascii="APODLF+TimesNewRoman" w:h-ansi="APODLF+TimesNewRoman" w:cs="APODLF+TimesNewRoman"/><wx:font wx:val="APODLF+TimesNewRoman"/><w:color w:val="auto"/></w:rPr></w:pPr><w:r><w:t>The interface between the input device(s) and volume viewer shall be as generic as possible to facilitate integration of third-party volume viewer software.</w:t></w:r></w:p><w:sectPr wsp:rsidR="00820625" wsp:rsidRPr="001A5C18" wsp:rsidSect="00E1538C"><w:pgSz w:w="12240" w:h="15840"/><w:pgMar w:top="1080" w:right="1080" w:bottom="1080" w:left="1080" w:header="720" w:footer="720" w:gutter="0"/><w:cols w:space="720"/><w:docGrid w:line-pitch="360"/></w:sectPr></wx:sub-section></wx:sub-section></wx:sub-section></wx:sect></w:body></w:wordDocument> \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.jdk.core.test/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.framework.jdk.core.test/META-INF/MANIFEST.MF
index b1033da99c0..d94284c931a 100644
--- a/plugins/org.eclipse.osee.framework.jdk.core.test/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.osee.framework.jdk.core.test/META-INF/MANIFEST.MF
@@ -9,3 +9,4 @@ Bundle-RequiredExecutionEnvironment: JavaSE-1.6
Export-Package: org.eclipse.osee.framework.jdk.core.test,
org.eclipse.osee.framework.jdk.core.test.type
Require-Bundle: org.junit4;bundle-version="4.5.0"
+Import-Package: org.eclipse.osee.framework.jdk.core.text.rules
diff --git a/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/JdkCoreTestSuite.java b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/JdkCoreTestSuite.java
index bab71b778c9..8fdef57fced 100644
--- a/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/JdkCoreTestSuite.java
+++ b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/JdkCoreTestSuite.java
@@ -10,6 +10,8 @@
*******************************************************************************/
package org.eclipse.osee.framework.jdk.core.test;
+import org.eclipse.osee.framework.jdk.core.test.rules.JdkCoreRuleTestSuite;
+import org.eclipse.osee.framework.jdk.core.test.text.JdkCoreTextTestSuite;
import org.eclipse.osee.framework.jdk.core.test.type.JdkCoreTypeTestSuite;
import org.eclipse.osee.framework.jdk.core.test.util.JdkCoreUtilTestSuite;
import org.junit.runner.RunWith;
@@ -18,10 +20,13 @@ import org.junit.runners.Suite;
/**
* @author Roberto E. Escobar
*/
+
@RunWith(Suite.class)
-@Suite.SuiteClasses( { //
- JdkCoreTypeTestSuite.class, //
- JdkCoreUtilTestSuite.class, //
+@Suite.SuiteClasses({
+ JdkCoreTypeTestSuite.class,
+ JdkCoreUtilTestSuite.class,
+ JdkCoreTextTestSuite.class,
+ JdkCoreRuleTestSuite.class,
})
public class JdkCoreTestSuite {
diff --git a/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/JdkCoreRuleTestSuite.java b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/JdkCoreRuleTestSuite.java
new file mode 100644
index 00000000000..72778c06267
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/JdkCoreRuleTestSuite.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.jdk.core.test.rules;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * @author Roberto E. Escobar
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({WordMLNewLineMakerRuleTest.class})
+public class JdkCoreRuleTestSuite {
+
+}
diff --git a/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/WordMLNewLineMakerRuleTest.java b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/WordMLNewLineMakerRuleTest.java
new file mode 100644
index 00000000000..105d856b279
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/WordMLNewLineMakerRuleTest.java
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.jdk.core.test.rules;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.charset.IllegalCharsetNameException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.eclipse.osee.framework.jdk.core.text.change.ChangeSet;
+import org.eclipse.osee.framework.jdk.core.text.rules.WordMLNewLineMaker;
+import org.eclipse.osee.framework.jdk.core.util.Lib;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.junit.Test;
+
+/**
+ * Tests ability of this rule to make new paragraphs, i.e. injecting <w:p> at specific points in the file.
+ *
+ * @link:WordMLNewLineMaker
+ * @author Karol M. Wilk
+ */
+public final class WordMLNewLineMakerRuleTest extends TestCase {
+
+ private final static String INPUT_FILE_NAME = "sample_icd_formatted.xml";
+ private final static String NEW_WP_INJECTION_FINGERPRINT =
+ "<w:p wsp:rsidR=\"01234567\" wsp:rsidRDefault=\"01234567\">";
+
+ private final WordMLNewLineMaker wordNewLineMaker =
+ new WordMLNewLineMaker();
+ private final StringBuilder pathArgument =
+ new StringBuilder();
+ private final Pattern paragraphRegex = Pattern.compile("<w:p[ >].*?</w:p>", Pattern.DOTALL);
+
+ @Test
+ public void testNewLineInserts() {
+ ChangeSet modifiedFile = null;
+ try {
+ modifiedFile = wordNewLineMaker.computeChanges(getResourceData(INPUT_FILE_NAME));
+ } catch (IOException ioex) {
+ System.err.println("Error: " + ioex.getMessage());
+ Assert.fail("Unable to process the file, " +
+ "WordMLNewLineMaker threw an IOException...");
+ } catch (IllegalCharsetNameException illegalName) {
+ System.err.println("Error: " + illegalName.getMessage());
+ Assert.fail("Illegal charset name specified, " +
+ "WordMLNewLineMaker threw an " +
+ "IllegalCharsetNameException...");
+ } catch (UnsupportedCharsetException unsupportedEx) {
+ System.err.println("Error: " + unsupportedEx.getMessage());
+ Assert.fail("Unsupported charset, " +
+ "WordMLNewLineMaker threw an " +
+ "UnsupportedCharsetException...");
+ }
+
+ Assert.assertTrue(modifiedFile.getSourceLength() != 0);
+
+ //Test Does it contain new paragraph injected signature ?
+ String modifiedFileAsString = modifiedFile.toString();
+ Assert.assertTrue(modifiedFileAsString.contains(NEW_WP_INJECTION_FINGERPRINT));
+
+ //Test Does it have 2 <w:p>s instead of 1 ?
+ Matcher wpMatcher = paragraphRegex.matcher(modifiedFileAsString);
+ int count = 0;
+ while (wpMatcher.find()) {
+ count++;
+ }
+ Assert.assertTrue(count == 2);
+
+ }
+
+ private static String getResourceData(String name) throws IOException {
+ InputStream inputStream = null;
+ try {
+ inputStream = WordMLNewLineMakerRuleTest.class.getResourceAsStream(name);
+ String data = Lib.inputStreamToString(inputStream);
+ Assert.assertTrue(Strings.isValid(data));
+ return data;
+ } finally {
+ Lib.close(inputStream);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/sample_icd_formatted.xml b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/sample_icd_formatted.xml
new file mode 100644
index 00000000000..f8c4a66b2e9
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/rules/sample_icd_formatted.xml
@@ -0,0 +1,44 @@
+<w:wordDocument abcded="12345">
+ <w:body>
+ <wx:sub-section>
+ <w:p wsp:rsidR="00000000" wsp:rsidRDefault="00002144">
+ <w:pPr>
+ <w:pStyle w:val="lvl2on"/>
+ <w:spacing w:before="48" w:line="273" w:line-rule="at-least"/>
+ </w:pPr>
+ <w:r>
+ <w:rPr>
+ <w:b/>
+ <w:b-cs/>
+ </w:rPr>
+ <w:t>1.1 </w:t>
+ </w:r>
+ <w:r>
+ <w:rPr>
+ <w:b/>
+ <w:b-cs/>
+ <w:u w:val="single"/>
+ </w:rPr>
+ <w:t>Test </w:t>
+ </w:r>
+ <w:r>
+ <w:rPr>
+ <w:b/>
+ <w:b-cs/>
+ <w:u w:val="single"/>
+ </w:rPr>
+ <w:t>of the new line maker.</w:t>
+ </w:r>
+ <w:r>
+ <w:t>. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc in ante nulla. Sed rhoncus lacinia nunc id vehicula. In eu metus at erat suscipit elementum. Aliquam posuere ante vel tellus tincidunt nec consequat ante ultrices. Proin luctus luctus convallis. Suspendisse potenti.</w:t>
+ </w:r>
+ <w:r>
+ <w:t> Nunc pulvinar arcu id libero ullamcorper in bibendum dolor elementum. Etiam euismod felis a felis pharetra sed eleifend mi interdum. Vivamus nisl elit, porta sed sagittis nec, lacinia quis dolor. Nam rhoncus nisl sed libero varius non aliquam purus faucibus. Curabitur non ante dui, pretium condimentum purus. Aliquam</w:t>
+ </w:r>
+ <w:r>
+ <w:t> congue, diam vel egestas consectetur, magna metus porta turpis, id tincidunt odio felis a justo. Maecenas sagittis pretium diam, at aliquam nisi convallis ut. Maecenas commodo egestas porttitor. In libero mauris, sollicitudin sit amet semper sit amet, posuere vel erat. Vestibulum sed sapien at nisi suscipit volutpat auctor suscipit odio.</w:t>
+ </w:r>
+ </w:p>
+ </wx:sub-section>
+ </w:body>
+</w:wordDocument>
diff --git a/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/JdkCoreTextTestSuite.java b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/JdkCoreTextTestSuite.java
new file mode 100644
index 00000000000..312877fd6c2
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/JdkCoreTextTestSuite.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.jdk.core.test.text;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * @author Karol M. Wilk
+ */
+@RunWith(Suite.class)
+@Suite.SuiteClasses({UtfReadingRuleTest.class})
+public class JdkCoreTextTestSuite {
+
+}
diff --git a/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/UtfReadingRuleTest.java b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/UtfReadingRuleTest.java
new file mode 100644
index 00000000000..730f40eb72a
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/UtfReadingRuleTest.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.jdk.core.test.text;
+
+import java.io.File;
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.UnsupportedCharsetException;
+import java.util.Stack;
+import junit.framework.TestCase;
+import org.eclipse.osee.framework.jdk.core.text.Rule;
+import org.eclipse.osee.framework.jdk.core.text.change.ChangeSet;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Tests ability to read files in charsets, particularly UTF8
+ *
+ * @link:Rule
+ * @link:Lib
+ * @author Karol M. Wilk
+ */
+public final class UtfReadingRuleTest extends TestCase {
+
+ private static class Utf8TestRule extends Rule {
+ private CharSequence lastOutput;
+
+ public Utf8TestRule() {
+ this.lastOutput = null;
+ }
+
+ @Override
+ public ChangeSet computeChanges(final CharSequence seq) {
+ lastOutput = seq;
+ return new ChangeSet(seq);
+ }
+
+ public CharSequence getLastOutput() {
+ return lastOutput;
+ }
+ }
+
+ private static final String FILE_INPUT =
+ "utf8_input.xml";
+
+ private final Utf8TestRule rule = new Utf8TestRule();
+
+ @Test
+ public void testWrongFileName() {
+ try {
+ rule.process(new File("./notexistentFile.txt"));
+ } catch (NullPointerException ex) {
+ Assert.assertTrue(true);
+ } catch (Exception ex) {
+ Assert.fail("unexpected/wrong exception thrown testWrongFileName()");
+ }
+ }
+
+ @Test
+ public void testCharset() {
+ Stack<String> charsetStack = new Stack<String>();
+ charsetStack.add("UnknownCharset");
+ charsetStack.add("UTF-8");
+
+ while (!charsetStack.isEmpty()) {
+ try {
+ File inputFile = new File(
+ UtfReadingRuleTest.class
+ .getResource(FILE_INPUT).toURI());
+ rule.setCharsetString(charsetStack.pop());
+ rule.process(inputFile);
+ } catch (Exception ex) {
+ Assert.assertTrue(
+ "unexpected/wrong exception thrown testCharset(), Exception: " + ex.toString(),
+ ex instanceof UnsupportedCharsetException || ex instanceof UnsupportedEncodingException);
+ }
+ }
+ }
+
+ @Test
+ public void testUtf8ReadData() {
+ String expectedUtf8String = "<w:t>€</w:t>";
+ try {
+ File inputFile = new File(
+ UtfReadingRuleTest.class
+ .getResource(FILE_INPUT).toURI());
+ rule.setCharsetString("UTF8");
+ rule.process(inputFile);
+ } catch (UnsupportedCharsetException ex) {
+ Assert.assertTrue(true);
+ } catch (Exception ex) {
+ Assert.fail("unexpected/wrong exception thrown testCharset()");
+ }
+
+ //trim off extra data
+ String actual =
+ rule.getLastOutput().toString().trim();
+ Assert.assertEquals(expectedUtf8String, actual);
+ }
+}
diff --git a/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/utf8_input.xml b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/utf8_input.xml
new file mode 100644
index 00000000000..e2b766c1876
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.jdk.core.test/src/org/eclipse/osee/framework/jdk/core/test/text/utf8_input.xml
@@ -0,0 +1 @@
+<w:t>€</w:t> \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/Rule.java b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/Rule.java
index a36ff3b0516..62aa2f8693a 100644
--- a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/Rule.java
+++ b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/Rule.java
@@ -27,169 +27,174 @@ import org.eclipse.osee.framework.jdk.core.util.Lib;
* @author Ryan D. Brooks
*/
public abstract class Rule {
- private final String outExtension;
- private String currentOutfileName;
- private File inputFile;
- private String subdirectoryName;
- private Pattern fileNamePattern;
- protected boolean ruleWasApplicable;
- protected Logger logger;
-
- public Rule() {
- this("done");
- }
-
- public Rule(String outExtension) {
- this.outExtension = outExtension;
- this.ruleWasApplicable = false;
- logger = Logger.getLogger(this.getClass().getName());
- logger.setLevel(Level.ALL);
- this.subdirectoryName = null;
- }
-
- public abstract ChangeSet computeChanges(CharSequence seq);
-
- public void process(Collection<File> list) {
- for (File file : list) {
- try {
- process(file);
- } catch (Exception ex) {
- System.out.println(currentOutfileName + ": " + ex.getMessage());
- }
- }
- }
-
- public void process(File file) throws IOException {
- if (file.isDirectory()) {
- List<File> files = Lib.recursivelyListFiles(file, fileNamePattern);
- for (File aFile : files) {
- try {
- process(aFile);
- } catch (Exception ex) {
- System.out.println(currentOutfileName + ": " + ex.getMessage());
- }
- }
- } else {
- inputFile = file;
- process(file, getResultFile(file));
- }
- }
-
- public void process(File inFile, File outFile) throws IOException {
- File subdirectory;
- if (subdirectoryName != null) {
- File parent = outFile.getParentFile();
- subdirectory = new File(parent, subdirectoryName);
- if (!subdirectory.mkdir()) {
- throw new IOException("Could not create directory");
- }
- outFile = new File(subdirectory, outFile.getName());
- }
-
- this.currentOutfileName = outFile.getName();
- if (inFile.exists()) {
- RulesLogHandler handler = null;
- ChangeSet changeSet = null;
- try {
- handler = new RulesLogHandler(new File(Lib.changeExtension(outFile.getPath(), "xml")));
- logger.addHandler(handler);
- ruleWasApplicable = false;
- changeSet = computeChanges(Lib.fileToCharBuffer(inFile));
- } catch (ParserConfigurationException ex) {
- logger.log(Level.SEVERE, ex.toString(), ex);
- } finally {
- if (handler != null) {
- handler.close();
- logger.removeHandler(handler);
- }
- }
- if (ruleWasApplicable) {
- if (subdirectoryName == null) {
- System.out.println("Rule was applied to " + currentOutfileName);
- } else {
- System.out.println("Rule was applied to " + subdirectoryName + currentOutfileName);
- }
-
- if (changeSet != null) {
- changeSet.applyChanges(outFile);
- }
- }
- } else {
- System.out.println("The file " + inFile + " does not exist!");
- }
- }
-
- protected File getResultFile(File file) {
-
- if (outExtension == null) {
- return file;
- }
-
- return new File(Lib.removeExtension(file.getPath()) + "." + outExtension);
- }
-
- public static void main(String[] args) throws Exception {
- if (args.length < 3) {
- System.out.println("Usage: " + Rule.class.getName() + " <ruleClassPath> <ruleClass> <file list>");
- return;
- }
-
- String ruleName = args[1];
- String classPath = args[0];
- try {
- URLClassLoader classLoader = new URLClassLoader(new URL[] {Lib.getUrlFromString(classPath)});
- System.out.println("class path: " + classLoader.getURLs()[0]);
- Object obj = classLoader.loadClass(ruleName).newInstance();
-
- if (obj instanceof org.eclipse.osee.framework.jdk.core.text.Rule) {
- Rule rule = (Rule) obj;
- for (int i = 2; i < args.length; i++) {
- try {
- rule.process(new File(args[i]));
- } catch (Exception ex) {
- System.out.println("Exception in Rule!!! " + rule.currentOutfileName + ": " + ex.getMessage());
- ex.printStackTrace();
- }
- }
- } else {
- throw new IllegalArgumentException(ruleName + " is not of type text.Rule.");
- }
- } catch (InstantiationException ex) {
- System.out.println(ex);
- } catch (IllegalAccessException ex) {
- System.out.println(ex);
- } catch (ClassNotFoundException ex) {
- System.out.println(ex);
- }
- }
-
- public boolean ruleWasApplicable() {
- return ruleWasApplicable;
- }
-
- /**
- * @return Returns the currentFileName.
- */
- public String getCurrentOutfileName() {
- return currentOutfileName;
- }
-
- /**
- * @param ruleWasApplicable The ruleWasApplicable to set.
- */
- public void setRuleWasApplicable(boolean ruleWasApplicable) {
- this.ruleWasApplicable = ruleWasApplicable;
- }
-
- public File getInputFile() {
- return inputFile;
- }
-
- public void setSubdirectoryNameToPlaceResultFilesIn(String subdirectoryName) {
- this.subdirectoryName = subdirectoryName;
- }
-
- public void setFileNamePattern(String fileNamePattern) {
- this.fileNamePattern = Pattern.compile(fileNamePattern);
- }
+ private final String outExtension;
+ private String currentOutfileName;
+ private File inputFile;
+ private String subdirectoryName;
+ private Pattern fileNamePattern;
+ protected boolean ruleWasApplicable;
+ protected Logger logger;
+
+ private String charsetString = "UTF8";
+
+ public Rule() {
+ this("done");
+ }
+
+ public Rule(String outExtension) {
+ this.outExtension = outExtension;
+ this.ruleWasApplicable = false;
+ logger = Logger.getLogger(this.getClass().getName());
+ logger.setLevel(Level.ALL);
+ this.subdirectoryName = null;
+ }
+
+ public abstract ChangeSet computeChanges(CharSequence seq);
+
+ public final void process(Collection<File> list) {
+ for (File file : list) {
+ try {
+ process(file);
+ } catch (Exception ex) {
+ System.out.println(currentOutfileName + ": " + ex.getMessage());
+ }
+ }
+ }
+
+ public final void process(File file) throws IOException {
+ if (file.isDirectory()) {
+ List<File> files = Lib.recursivelyListFiles(file, fileNamePattern);
+ for (File aFile : files) {
+ try {
+ process(aFile);
+ } catch (Exception ex) {
+ System.out.println(currentOutfileName + ": " + ex.getMessage());
+ }
+ }
+ } else {
+ inputFile = file;
+ process(file, getResultFile(file));
+ }
+ }
+
+ public final void process(File inFile, File outFile) throws IOException {
+ File subdirectory;
+ if (subdirectoryName != null) {
+ File parent = outFile.getParentFile();
+ subdirectory = new File(parent, subdirectoryName);
+ if (!subdirectory.mkdir()) {
+ throw new IOException("Could not create directory");
+ }
+ outFile = new File(subdirectory, outFile.getName());
+ }
+
+ this.currentOutfileName = outFile.getName();
+ if (inFile.exists()) {
+ RulesLogHandler handler = null;
+ ChangeSet changeSet = null;
+ try {
+ handler = new RulesLogHandler(new File(Lib.changeExtension(outFile.getPath(), "xml")));
+ logger.addHandler(handler);
+ ruleWasApplicable = false;
+ changeSet = computeChanges(Lib.fileToCharBuffer(inFile, charsetString));
+ } catch (ParserConfigurationException ex) {
+ logger.log(Level.SEVERE, ex.toString(), ex);
+ } finally {
+ if (handler != null) {
+ handler.close();
+ logger.removeHandler(handler);
+ }
+ }
+ if (ruleWasApplicable) {
+ String path = subdirectoryName == null ? "" : subdirectoryName;
+ System.out.println("Rule was applied to " + path + currentOutfileName);
+
+ if (changeSet != null) {
+ changeSet.applyChanges(outFile);
+ }
+ }
+ } else {
+ System.out.println("The file " + inFile + " does not exist!");
+ }
+ }
+
+ protected final File getResultFile(File file) {
+ if (outExtension == null) {
+ return file;
+ }
+ return new File(Lib.removeExtension(file.getPath()) + "." + outExtension);
+ }
+
+ public static void main(String[] args) throws Exception {
+ if (args.length < 3) {
+ System.out.println("Usage: " + Rule.class.getName() + " <ruleClassPath> <ruleClass> <file list>");
+ return;
+ }
+
+ String ruleName = args[1];
+ String classPath = args[0];
+ try {
+ URLClassLoader classLoader = new URLClassLoader(new URL[] {Lib.getUrlFromString(classPath)});
+ System.out.println("class path: " + classLoader.getURLs()[0]);
+ Object obj = classLoader.loadClass(ruleName).newInstance();
+
+ if (obj instanceof org.eclipse.osee.framework.jdk.core.text.Rule) {
+ Rule rule = (Rule) obj;
+ for (int i = 2; i < args.length; i++) {
+ try {
+ rule.process(new File(args[i]));
+ } catch (Exception ex) {
+ System.out.println("Exception in Rule!!! " + rule.currentOutfileName + ": " + ex.getMessage());
+ ex.printStackTrace();
+ }
+ }
+ } else {
+ throw new IllegalArgumentException(ruleName + " is not of type text.Rule.");
+ }
+ } catch (InstantiationException ex) {
+ System.out.println(ex);
+ } catch (IllegalAccessException ex) {
+ System.out.println(ex);
+ } catch (ClassNotFoundException ex) {
+ System.out.println(ex);
+ }
+ }
+
+ public final boolean ruleWasApplicable() {
+ return ruleWasApplicable;
+ }
+
+ /**
+ * @return Returns the currentFileName.
+ */
+ public final String getCurrentOutfileName() {
+ return currentOutfileName;
+ }
+
+ /**
+ * @param ruleWasApplicable The ruleWasApplicable to set.
+ */
+ public final void setRuleWasApplicable(boolean ruleWasApplicable) {
+ this.ruleWasApplicable = ruleWasApplicable;
+ }
+
+ public final File getInputFile() {
+ return inputFile;
+ }
+
+ public final void setSubdirectoryNameToPlaceResultFilesIn(String subdirectoryName) {
+ this.subdirectoryName = subdirectoryName;
+ }
+
+ public final void setFileNamePattern(String fileNamePattern) {
+ this.fileNamePattern = Pattern.compile(fileNamePattern);
+ }
+
+ public final String getCharsetString() {
+ return charsetString;
+ }
+
+ public final void setCharsetString(String charsetString) {
+ this.charsetString = charsetString;
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/HushHtmlScriptErrors.java b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/HushHtmlScriptErrors.java
index ea8741dbc04..bc4161c380c 100644
--- a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/HushHtmlScriptErrors.java
+++ b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/HushHtmlScriptErrors.java
@@ -11,7 +11,6 @@
package org.eclipse.osee.framework.jdk.core.text.rules;
import java.io.File;
-import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.osee.framework.jdk.core.text.Rule;
@@ -26,51 +25,47 @@ import org.eclipse.osee.framework.jdk.core.text.change.ChangeSet;
*/
public class HushHtmlScriptErrors extends Rule {
- // This is the code that must be entered in to the HTML to hush script errors
- private final static String HUSH =
- "\nfunction handleError() {\n" + "return true;\n" + "}\n\n" + "window.onerror = handleError;\n";
+ // This is the code that must be entered in to the HTML to hush script errors
+ private final static String HUSH =
+ "\nfunction handleError() {\n" + "return true;\n" + "}\n\n" + "window.onerror = handleError;\n";
- public HushHtmlScriptErrors() {
- super(null);
- }
+ public HushHtmlScriptErrors() {
+ super(null);
+ setFileNamePattern(".*\\.html");
+ }
- public ChangeSet computeChanges(CharSequence seq) {
- Pattern detectHusherInPlace = Pattern.compile("function handleError");
- Pattern findJavaScriptArea = Pattern.compile("<SCRIPT type=\"text/javascript\">");
- ChangeSet changeSet = new ChangeSet(seq);
+ @Override
+ public ChangeSet computeChanges(CharSequence seq) {
+ Pattern detectHusherInPlace = Pattern.compile("function handleError");
+ Pattern findJavaScriptArea = Pattern.compile("<SCRIPT type=\"text/javascript\">");
+ ChangeSet changeSet = new ChangeSet(seq);
- // Only add in hushing if it is not in place
- Matcher matchHusher = detectHusherInPlace.matcher(seq);
- if (!matchHusher.find()) {
+ // Only add in hushing if it is not in place
+ Matcher matchHusher = detectHusherInPlace.matcher(seq);
+ if (!matchHusher.find()) {
- Matcher matcher = findJavaScriptArea.matcher(seq);
- if (matcher.find()) {
- ruleWasApplicable = true;
+ Matcher matcher = findJavaScriptArea.matcher(seq);
+ if (matcher.find()) {
+ ruleWasApplicable = true;
- changeSet.insertBefore(matcher.end() + 1, HUSH);
- }
- }
+ changeSet.insertBefore(matcher.end() + 1, HUSH);
+ }
+ }
- return changeSet;
- }
+ return changeSet;
+ }
- public static void main(String[] args) {
- HushHtmlScriptErrors hushRule = new HushHtmlScriptErrors();
- for (int i = 0; i < args.length; i++) {
- try {
- System.out.print("File " + (i + 1) + "/" + (args.length) + ":");
- hushRule.process(new File(args[i]));
- } catch (Exception ex) {
- System.out.println("Exception in Rule!!! " + hushRule.getCurrentOutfileName() + ": " + ex.getMessage());
- ex.printStackTrace();
- }
- }
- System.out.println("Finished");
- }
-
- public void process(File inFile, File outFile) throws IOException {
- //Filter files being processed by this to only be of type .html
- if (inFile.getName().endsWith(".html")) super.process(inFile, outFile);
- }
-
-}
+ public static void main(String[] args) {
+ HushHtmlScriptErrors hushRule = new HushHtmlScriptErrors();
+ for (int i = 0; i < args.length; i++) {
+ try {
+ System.out.print("File " + (i + 1) + "/" + (args.length) + ":");
+ hushRule.process(new File(args[i]));
+ } catch (Exception ex) {
+ System.out.println("Exception in Rule!!! " + hushRule.getCurrentOutfileName() + ": " + ex.getMessage());
+ ex.printStackTrace();
+ }
+ }
+ System.out.println("Finished");
+ }
+} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/WordMLNewLineMaker.java b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/WordMLNewLineMaker.java
new file mode 100644
index 00000000000..4e638e56d8e
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/text/rules/WordMLNewLineMaker.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.jdk.core.text.rules;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.eclipse.osee.framework.jdk.core.text.Rule;
+import org.eclipse.osee.framework.jdk.core.text.change.ChangeSet;
+
+/**
+ * @link:WordMLNewLineMakerTest
+ * @author Karol M. Wilk
+ */
+
+//NOTE: Rule implements a main(), so start this by passing path to files as argument
+//TODO: update methods to use ChangeSet rather than current logic
+public final class WordMLNewLineMaker extends Rule {
+
+ private static final String TERMINATING_WP_XML = "\n</w:p>";
+ private static final String DUMMY_PARAGRAPH_BEGINNING =
+ "\n<w:p wsp:rsidR=\"01234567\" wsp:rsidRDefault=\"01234567\">" +
+ "<w:pPr>" + "<w:spacing w:before=\"48\" w:line=\"273\" w:line-rule=\"at-least\"/>" + "</w:pPr>";
+
+ private final Pattern wordDocumentEndRegex = Pattern.compile(".*?</w:wordDocument>", Pattern.DOTALL);
+ private final Pattern bodyRegex = Pattern.compile("<w:body>.*?</w:body>", Pattern.DOTALL);
+ private final Pattern wxSubsectionRegex = Pattern.compile("<wx:sub-section>.*?</wx:sub-section>", Pattern.DOTALL);
+ private final Pattern paragraphRegex = Pattern.compile("<w:p[ >].*?</w:p>", Pattern.DOTALL);
+ private final Pattern wordRunRegex = Pattern.compile("<w:r[ >].*?</w:r>", Pattern.DOTALL);
+ private final Pattern wordTextRegex = Pattern.compile("<w:t>(.*?)</w:t>", Pattern.DOTALL);
+
+ private StringBuilder modifiedText = null;
+
+ @Override
+ public ChangeSet computeChanges(CharSequence entireFile) {
+ modifiedText = new StringBuilder(entireFile.length() * 2);
+ int lastBodySectionMatchEndIndex = -1;
+ boolean foundSomething = false;
+
+ Matcher bodySectionMatcher = bodyRegex.matcher(entireFile);
+
+ if (bodySectionMatcher.find()) {
+ Matcher wxSubSectionMatcher =
+ wxSubsectionRegex.matcher(bodySectionMatcher.group());
+ while (wxSubSectionMatcher.find()) {
+ if (!foundSomething) {
+ //write only at first time
+ writeToBuffer(entireFile.subSequence(0, bodySectionMatcher.start()));
+ writeToBuffer("\n<w:body>");
+ }
+ lastBodySectionMatchEndIndex = bodySectionMatcher.end();
+ processWxSubSection(wxSubSectionMatcher.group());
+ foundSomething = true;
+ }
+
+ if (foundSomething) {
+ writeToBuffer("\n</w:body>");
+ }
+ }
+
+ //data from </w:body> to end of </w:wordDocument>
+ if (foundSomething && lastBodySectionMatchEndIndex != -1) {
+ writeToBuffer(trimWordDocumentEnd(entireFile.subSequence(lastBodySectionMatchEndIndex, entireFile.length())));
+ }
+
+ return decideOnResultAndReturnIt(modifiedText, entireFile);
+ }
+
+ private CharSequence trimWordDocumentEnd(CharSequence endOfWordDocumentChunk) {
+ Matcher endOfWordDocumentMatcher = wordDocumentEndRegex.matcher(endOfWordDocumentChunk);
+ int chopOffAt = -1;
+ if (endOfWordDocumentMatcher.find()) {
+ chopOffAt = endOfWordDocumentMatcher.end();
+ }
+ if (chopOffAt != -1) {
+ return endOfWordDocumentChunk.subSequence(0, chopOffAt);
+ } else {
+ return endOfWordDocumentChunk;
+ }
+ }
+
+ private ChangeSet decideOnResultAndReturnIt(StringBuilder modifiedFile, CharSequence entireFile) {
+ ChangeSet returningChangeSet = null;
+ if (modifiedText.length() > 0) {
+ // modified text becomes the char sequence
+ returningChangeSet = new ChangeSet(modifiedText);
+ setRuleWasApplicable(true);
+ } else {
+ returningChangeSet = new ChangeSet(entireFile);
+ setRuleWasApplicable(false);
+ }
+ return returningChangeSet;
+ }
+
+ private void processWxSubSection(String wxSubSection) {
+ Matcher paragraphMatcher = paragraphRegex.matcher(wxSubSection);
+ boolean writtenPreBodySection = false;
+ int lastParagraphMatchEndIndex = -1;
+ while (paragraphMatcher.find()) {
+
+ String paragraph = paragraphMatcher.group();
+
+ //write anything between section and paragraph
+ if (!writtenPreBodySection) {
+ writeToBuffer(wxSubSection.subSequence(0, paragraphMatcher.start()));
+ writtenPreBodySection = true;
+ }
+ //write anything between last and current <w:p>
+ if (lastParagraphMatchEndIndex != -1) {
+ writeToBuffer(wxSubSection.subSequence(lastParagraphMatchEndIndex, paragraphMatcher.start()));
+ }
+
+ processParagraph(paragraph);
+
+ lastParagraphMatchEndIndex = paragraphMatcher.end();
+ }
+ //write anything after paragraph and before section end...
+ writeToBuffer(wxSubSection.subSequence(lastParagraphMatchEndIndex, wxSubSection.length()));
+ }
+
+ private void processParagraph(String paragraph) {
+ boolean outlineNumberAndNameDetected = false;
+
+ // search for <w:r> containing extra meta data
+ Matcher wordRunMatcher = wordRunRegex.matcher(paragraph);
+ boolean foundSplitArea = false;
+ int indexOfWrPreceedingTheSplit = -1;
+
+ while (wordRunMatcher.find()) {
+
+ String singleWordRun = wordRunMatcher.group();
+
+ boolean boldHint = singleWordRun.contains("<w:b/>");
+ boolean underlineHint = singleWordRun.contains("<w:b-cs/>");
+
+ if (boldHint && underlineHint) {
+ outlineNumberAndNameDetected = true;
+ indexOfWrPreceedingTheSplit = wordRunMatcher.end();
+ }
+
+ if (!boldHint && !underlineHint && outlineNumberAndNameDetected) {
+ foundSplitArea = true;
+ break;
+ }
+ }
+
+ if (indexOfWrPreceedingTheSplit != -1 && foundSplitArea) {
+ //write everything from paragraph.at(0) to paragraph.at(indexOfWrPreceedingTheSplit)...
+ writeToBuffer(paragraph.subSequence(0, indexOfWrPreceedingTheSplit));
+ //terminate wp, start new wp
+ writeToBuffer(TERMINATING_WP_XML);
+ writeToBuffer(DUMMY_PARAGRAPH_BEGINNING);
+ //write remainder of paragraph
+ writeToBuffer(cleanUpWtFromChunk(paragraph.subSequence(indexOfWrPreceedingTheSplit, paragraph.length())));
+ } else {
+ writeToBuffer(paragraph);
+ }
+ }
+
+ /**
+ * Grabs only the first <w:r><w:t> combination and looks for a dot. When found removes the dot
+ *
+ * @param chunk
+ * @return
+ */
+ private StringBuilder cleanUpWtFromChunk(CharSequence chunk) {
+ StringBuilder tempBuffer = new StringBuilder(chunk.length());
+ Matcher wordRunMatcher = wordRunRegex.matcher(chunk);
+ if (wordRunMatcher.find()) {
+ tempBuffer.append(chunk.subSequence(0, wordRunMatcher.start()));
+ Matcher wordTextMatcher = wordTextRegex.matcher(wordRunMatcher.group());
+ if (wordTextMatcher.find()) {
+ String text = wordTextMatcher.group(1);
+ if (text.startsWith(".") && text.trim().length() > 1) {
+ tempBuffer.append("<w:r><w:t>");
+ tempBuffer.append(text.substring(1, text.length()));
+ tempBuffer.append("</w:t></w:r>");
+ } else if (text.trim().length() > 1) {
+ tempBuffer.append("<w:r><w:t>");
+ tempBuffer.append(text);
+ tempBuffer.append("</w:t></w:r>");
+ }
+ tempBuffer.append(chunk.subSequence(wordRunMatcher.end(), chunk.length()));
+ }
+ }
+ return tempBuffer;
+ }
+
+ private void writeToBuffer(CharSequence subSequence) {
+ if (modifiedText != null) {
+ modifiedText.append(subSequence);
+ } else {
+ System.out.println("StringBuilder modifiedText is null! Ignoring write...");
+ }
+ }
+}
diff --git a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/AHTML.java b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/AHTML.java
index f6bf63cb083..ddfb04cf169 100644
--- a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/AHTML.java
+++ b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/AHTML.java
@@ -25,490 +25,492 @@ import java.util.List;
* @author Michael A. Winston
*/
public class AHTML {
- private static final String HTTP_CHARSET_ENCODING =
- "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">";
- private static final String begin = "<table ";
- public final static String LABEL_FONT = "<font color=\"black\" face=\"Arial\" size=\"-1\">";
-
- public static String getHyperlink(String url, String name) {
- return String.format("<a href=\"%s\">%s</a>", url, name);
- }
-
- public static String textToHtml(String text) {
- if (text == null) {
- return "";
- }
- text = text.replaceAll("&", "&amp;");
- text = text.replaceAll(">", "&gt;");
- text = text.replaceAll("<", "&lt;");
- text = text.replaceAll("\"", "&quot;");
- text = text.replaceAll("\\n", "<br/>");
- text = text.replaceAll("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
- text = text.replaceAll("[\\x0B\\f\\r]+", "");
- return text;
- }
-
- public static String htmlToText(String html) {
- if (html == null) {
- return "";
- }
- html = html.replaceAll("&amp;", "&");
- html = html.replaceAll("&gt;", ">");
- html = html.replaceAll("&lt;", "<");
- html = html.replaceAll("&quot;", "\"");
- html = html.replaceAll("&nbsp;", " ");
- return html;
- }
-
- public static String getUrlPageHtml(String urlStr, InetSocketAddress addr) {
- StringBuffer buffer = new StringBuffer();
- try {
- URL url = new URL(urlStr);
- URLConnection connection = url.openConnection(new Proxy(Proxy.Type.HTTP, addr));
- BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
- String line = null;
- while ((line = rd.readLine()) != null) {
- buffer.append(line);
- }
- rd.close();
- return buffer.toString();
- } catch (Exception ex) {
- ex.printStackTrace();
- return simplePage("Exception opening url " + ex.getLocalizedMessage());
- }
- }
-
- public static String titledPage(String title, String text) {
- return simplePage("<head><title>" + title + "</title></head>" + text);
- }
-
- public static String pageEncoding(String html) {
- return HTTP_CHARSET_ENCODING + html;
- }
-
- public static String simplePage(String text) {
- return pageEncoding("<html>" + text + "</html>");
- }
-
- public static String simplePageNoPageEncoding(String text) {
- return "<html>" + text + "</html>";
- }
-
- public static String getLabelStr(String labelFont, String str) {
- return labelFont + "<b>" + textToHtml(str) + "</b></font>";
- }
-
- public static String getLabelValueStr(String labelFont, String label, String value) {
- return getLabelStr(labelFont, label) + value;
- }
-
- public static String getLabelValueStr(String label, String value) {
- return getLabelStr(LABEL_FONT, label + ":") + "&nbsp;&nbsp;" + value;
- }
-
- public static String color(String color, String str) {
- if (color == null) {
- return str;
- } else {
- return "<font color=\"" + color + "\">" + str + "</font>";
- }
- }
-
- public static String boldColor(String color, String str) {
- return "<font color=\"" + color + "\"><b>" + textToHtml(str) + "</b></font>";
- }
-
- public static String bold(String str) {
- return "<b>" + textToHtml(str) + "</b>";
- }
-
- public static String boldColorTags(String color, String str) {
- return "<font color=\"" + color + "\"><b>" + str + "</b></font>";
- }
-
- public static String imageBlock(String description, String filename) {
- String filenames[] = new String[1];
- filenames[0] = filename;
- return imageBlock(description, filenames);
- }
-
- public static String imageBlock(String description, String filenames[]) {
- StringBuilder str = new StringBuilder();
- str.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr><td>");
- if (!description.equals("")) {
- str.append(description);
- str.append(AHTML.newline());
- }
- for (int i = 0; i < filenames.length; i++) {
- str.append("<IMG SRC=\"" + filenames[i] + "\"><br>");
- }
- str.append("</td></tr></table>");
- return str.toString();
- }
-
- public static String urlBlock(String description, String urls[]) {
- StringBuilder str = new StringBuilder();
- str.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">");
- if (!description.equals("")) {
- str.append(description);
- str.append(AHTML.newline());
- }
- for (int i = 0; i < urls.length; i++) {
- str.append("<A HREF=\"" + urls[i] + "\">" + urls[i] + "</A><br>");
- }
- str.append("</td></tr></table>");
- return str.toString();
- }
-
- public static String heading(int heading, String str, String id) {
- return "<h" + heading + (id != null && !id.equals("") ? " id=\"" + id + "\"" : "") + ">" + textToHtml(str) + "</h" + heading + ">";
- }
-
- public static String heading(int heading, String str) {
- return heading(heading, str, null);
- }
-
- public static String padSpace(int num, String str) {
- StringBuilder out = new StringBuilder();
- for (int i = 0; i < num; i++) {
- out.append("&nbsp;");
- }
- out.append(str);
- return out.toString();
- }
-
- public static String addSpace(int num) {
- StringBuilder out = new StringBuilder();
- for (int i = 0; i < num; i++) {
- out.append("&nbsp;");
- }
- return out.toString();
- }
-
- public static String para(String str) {
- return "<p>" + textToHtml(str) + "</p>";
- }
-
- public static String italics(String str) {
- return "<i>" + textToHtml(str) + "</i>";
- }
-
- public static String pre(String str) {
- return "<pre>" + str + "</pre>";
- }
-
- public static String blockQuote(String str) {
- return "<blockquote>" + str + "</blockquote>";
- }
-
- public static String newline() {
- return newline(1);
- }
-
- public static String newline(int num) {
- StringBuilder str = new StringBuilder();
- for (int i = 0; i < num; i++) {
- str.append("<br />");
- }
- return str + "";
- }
-
- public static String name(int num) {
- return nameTarget("" + num);
- }
-
- /**
- * Create target for hyperlink to jump to
- *
- * @param str
- * @return Return name target string
- */
- public static String nameTarget(String str) {
- if (str == null) {
- return "";
- }
- return "<A NAME=\"" + str + "\">";
- }
-
- /**
- * Create &lt;a href> hyperlink to nameTarget
- *
- * @param num
- * @param text
- * @return Return name link string
- */
- public static String nameLink(int num, String text) {
- return nameLink("" + num, text);
- }
-
- /**
- * Create &lt;a href> hyperlink to nameTarget
- *
- * @param name
- * @param text
- * @return Return name link string
- */
- public static String nameLink(String name, String text) {
- return "<A HREF=\"#" + name + "\">" + text + "</A>";
- }
-
- /**
- * Create &lt;a href> hyperlink to nameTarget using name as hyperlink tag and display text
- *
- * @param name
- * @return Return name link string
- */
- public static String nameLink(String name) {
- return "<A HREF=\"#" + name + "\">" + name + "</A>";
- }
-
- public static String simpleTable(String str) {
- return simpleTable(str, 100);
- }
-
- /**
- * Create a table with one row/colum containing str
- *
- * @param str
- * @param width
- * @return return simple table string
- */
- public static String simpleTable(String str, int width) {
- return "<table border=\"0\" cellpadding=\"3\" cellspacing=\"0\" width=\"" + width + "%\">" + "<tr><td>" + str + "</td></tr>" + "</table>";
- }
-
- /**
- * Create a table with one row/colum containing str
- *
- * @param str
- * @param width
- * @param bgcolor
- * @return Return border table string
- */
- public static String borderTable(String str, int width, String bgcolor, String caption) {
- return startBorderTable(width, bgcolor, caption) + str + endBorderTable();
- }
-
- public static String startBorderTable(int width, String bgcolor, String caption) {
- String capStr = "";
- if (!caption.equals("")) {
- capStr = "<caption ALIGN=top>" + caption + "</caption>";
- }
- return "<table border=\"1\" align=\"center\" bgcolor=\"" + bgcolor + "\" cellpadding=\"3\" cellspacing=\"0\" width=\"" + width + "%\">" + capStr + "<tr><td>";
- }
-
- public static String endBorderTable() {
- return "</td></tr></table>";
- }
-
- /**
- * Create a table with one row multi column containing str[]
- *
- * @param str = array of strings for columns
- * @return Return multi-column table string
- */
- public static String multiColumnTable(String[] str) {
- return multiColumnTable(str, 85);
- }
-
- /**
- * Create a table with one row multi column containing str[]
- *
- * @param str - array of strings for columns
- * @param width - percent (1..100) of screen for table
- * @return Return multi-column table string
- */
- public static String multiColumnTable(String[] str, int width) {
- StringBuilder s = new StringBuilder();
- s.append("<table border=\"0\" cellpadding=\"3\" cellspacing=\"0\" width=\"" + width + "%\"><tr>");
- for (int i = 0; i < str.length; i++) {
- s.append("<td>");
- s.append(str[i]);
- s.append("</td>");
- }
- s.append("</tr></table>");
- return s.toString();
- }
-
- public static String beginMultiColumnTable(int width) {
- return beginMultiColumnTable(width, 0);
- }
-
- public static String beginMultiColumnTable(int width, int border) {
- return beginMultiColumnTable(width, border, null);
- }
-
- public static String beginMultiColumnTable(int width, int border, Integer color) {
- return "<table border=\"" + border + "\" " + (color != null ? "color=\"" + color + "\"" : "") + "cellpadding=\"3\" cellspacing=\"0\" width=\"" + width + "%\">";
- }
-
- public static String endMultiColumnTable() {
- return "</table>";
- }
-
- public static String addRowMultiColumnTable(String... str) {
- return addRowMultiColumnTable(str, null, null);
- }
-
- public static String addRowMultiColumnTable(String[] str, String[] colOptions) {
- return addRowMultiColumnTable(str, colOptions, null);
- }
-
- public static String addRowMultiColumnTable(String[] str, String[] colOptions, String backgroundColor) {
- StringBuilder s = new StringBuilder();
- if (backgroundColor != null) {
- s.append("<tr bgcolor=\"" + backgroundColor + "\">");
- } else {
- s.append("<tr>");
- }
- String show = "";
- for (int i = 0; i < str.length; i++) {
- show = str[i];
- if (show == null || show.equals("")) {
- show = AHTML.addSpace(1);
- }
- String colOptionStr = "";
- if (colOptions != null) {
- colOptionStr = colOptions[i];
- }
- s.append("<td" + (colOptionStr != null && !colOptionStr.equals("") ? colOptionStr : "") + ">" + show + "</td>");
- }
- s.append("</tr>");
- return s.toString();
- }
-
- public static String addRowSpanMultiColumnTable(String str, int span) {
- return "<tr><td colspan=" + span + ">" + str + "</td></tr>";
- }
-
- public static class CellItem {
- String text;
- private final String fgColor;
- private final String bgColor;
-
- public CellItem(String text) {
- this(text, null, null);
- }
-
- public CellItem(String text, String fgColor, String bgColor) {
- this.text = text;
- this.fgColor = fgColor;
- this.bgColor = bgColor;
- }
- }
-
- public static String addRowMultiColumnTable(Collection<CellItem> items) {
- StringBuilder s = new StringBuilder("<tr>");
- for (CellItem item : items) {
- if (item.text == null || item.text.equals("")) {
- item.text = ".";
- }
- if (item.bgColor != null) {
- s.append("<td bgcolor=\"" + item.bgColor + "\">");
- } else {
- s.append("<td>");
- }
- s.append(AHTML.color(item.fgColor, item.text));
- s.append("</td>");
- }
- s.append("</tr>");
- return s.toString();
- }
-
- public static String addHeaderRowMultiColumnTable(List<String> strs) {
- return addHeaderRowMultiColumnTable(strs.toArray(new String[strs.size()]));
- }
-
- public static String addHeaderRowMultiColumnTable(String[] str) {
- return addHeaderRowMultiColumnTable(str, null);
- }
-
- public static String addHeaderRowMultiColumnTable(String[] str, Integer width[]) {
- StringBuilder s = new StringBuilder("<tr>");
- String widthStr = "";
- for (int i = 0; i < str.length; i++) {
- if (width != null) {
- widthStr = " width =\"" + width[i] + "\"";
- }
- s.append("<th");
- s.append(widthStr);
- s.append(">");
- s.append(str[i]);
- s.append("</th>");
- }
- s.append("</tr>");
- return s.toString();
- }
-
- public static void addSimpleTableRow(Appendable appendable, String contents) throws IOException {
- appendable.append("<tr><td>");
- appendable.append(contents);
- appendable.append("</td></tr>");
- }
-
- public static void addSimpleHeaderRow(Appendable appendable, String contents) throws IOException {
- appendable.append("<tr><th>");
- appendable.append(contents);
- appendable.append("</th></tr>");
- }
-
- public static void beginSimpleTable(Appendable appendable) throws IOException {
- beginSimpleTable(appendable, 1, 100);
- }
-
- public static void beginSimpleTable(Appendable appendable, int border, int width) throws IOException {
- appendable.append("<table border=\"");
- appendable.append(String.valueOf(border));
- appendable.append("\" cellpadding=\"0\" cellspacing=\"0\" width=\"");
- appendable.append(String.valueOf(width));
- appendable.append("%\">");
- }
-
- public static void endSimpleTable(Appendable appendable) throws IOException {
- appendable.append("</table>");
- }
-
- public static String createTable(List<String> datas, String[] headers, int numColumns, int cellPadding, int border) {
- StringBuilder table = new StringBuilder(begin);
-
- if (datas == null) {
- throw new IllegalArgumentException("The data can not be null");
- }
- if (datas.size() % numColumns != 0) {
- throw new IllegalArgumentException(
- "The table could not be created becuase the data does not match the column size");
- }
- if (border > 0) {
- table.append("border=\"" + border + "\"");
- }
- if (cellPadding > 0) {
- table.append("cellpadding=\"" + cellPadding + "\"");
- }
- table.append(">");
-
- if (headers != null && headers.length == numColumns) {
- table.append("<tr>");
- for (String header : headers) {
- table.append("<th>" + header + "</th>");
- }
- table.append("</tr>");
- }
-
- int colIndex = 0;
- for (String data : datas) {
-
- if (colIndex == 0) {
- table.append("<tr>");
- }
- table.append("<td>" + data + "</td>");
- colIndex++;
-
- if (colIndex == numColumns) {
- table.append("</tr>");
- colIndex = 0;
- }
- }
- return table.toString();
- }
+ private static final String HTTP_CHARSET_ENCODING =
+ "<meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\">";
+ private static final String begin = "<table ";
+ public final static String LABEL_FONT = "<font color=\"black\" face=\"Arial\" size=\"-1\">";
+
+ public static String getHyperlink(String url, String name) {
+ return String.format("<a href=\"%s\">%s</a>", url, name);
+ }
+
+ //TODO: replace with ReservedCharacters.java
+ public static String textToHtml(String text) {
+ if (text == null) {
+ return "";
+ }
+ text = text.replaceAll("&", "&amp;");
+ text = text.replaceAll(">", "&gt;");
+ text = text.replaceAll("<", "&lt;");
+ text = text.replaceAll("\"", "&quot;");
+ text = text.replaceAll("\\n", "<br/>");
+ text = text.replaceAll("\t", "&nbsp;&nbsp;&nbsp;&nbsp;");
+ text = text.replaceAll("[\\x0B\\f\\r]+", "");
+ return text;
+ }
+
+ //TODO: replace with ReservedCharacters.java
+ public static String htmlToText(String html) {
+ if (html == null) {
+ return "";
+ }
+ html = html.replaceAll("&amp;", "&");
+ html = html.replaceAll("&gt;", ">");
+ html = html.replaceAll("&lt;", "<");
+ html = html.replaceAll("&quot;", "\"");
+ html = html.replaceAll("&nbsp;", " ");
+ return html;
+ }
+
+ public static String getUrlPageHtml(String urlStr, InetSocketAddress addr) {
+ StringBuffer buffer = new StringBuffer();
+ try {
+ URL url = new URL(urlStr);
+ URLConnection connection = url.openConnection(new Proxy(Proxy.Type.HTTP, addr));
+ BufferedReader rd = new BufferedReader(new InputStreamReader(connection.getInputStream()));
+ String line = null;
+ while ((line = rd.readLine()) != null) {
+ buffer.append(line);
+ }
+ rd.close();
+ return buffer.toString();
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ return simplePage("Exception opening url " + ex.getLocalizedMessage());
+ }
+ }
+
+ public static String titledPage(String title, String text) {
+ return simplePage("<head><title>" + title + "</title></head>" + text);
+ }
+
+ public static String pageEncoding(String html) {
+ return HTTP_CHARSET_ENCODING + html;
+ }
+
+ public static String simplePage(String text) {
+ return pageEncoding("<html>" + text + "</html>");
+ }
+
+ public static String simplePageNoPageEncoding(String text) {
+ return "<html>" + text + "</html>";
+ }
+
+ public static String getLabelStr(String labelFont, String str) {
+ return labelFont + "<b>" + textToHtml(str) + "</b></font>";
+ }
+
+ public static String getLabelValueStr(String labelFont, String label, String value) {
+ return getLabelStr(labelFont, label) + value;
+ }
+
+ public static String getLabelValueStr(String label, String value) {
+ return getLabelStr(LABEL_FONT, label + ":") + "&nbsp;&nbsp;" + value;
+ }
+
+ public static String color(String color, String str) {
+ if (color == null) {
+ return str;
+ } else {
+ return "<font color=\"" + color + "\">" + str + "</font>";
+ }
+ }
+
+ public static String boldColor(String color, String str) {
+ return "<font color=\"" + color + "\"><b>" + textToHtml(str) + "</b></font>";
+ }
+
+ public static String bold(String str) {
+ return "<b>" + textToHtml(str) + "</b>";
+ }
+
+ public static String boldColorTags(String color, String str) {
+ return "<font color=\"" + color + "\"><b>" + str + "</b></font>";
+ }
+
+ public static String imageBlock(String description, String filename) {
+ String filenames[] = new String[1];
+ filenames[0] = filename;
+ return imageBlock(description, filenames);
+ }
+
+ public static String imageBlock(String description, String filenames[]) {
+ StringBuilder str = new StringBuilder();
+ str.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr><td>");
+ if (!description.equals("")) {
+ str.append(description);
+ str.append(AHTML.newline());
+ }
+ for (int i = 0; i < filenames.length; i++) {
+ str.append("<IMG SRC=\"" + filenames[i] + "\"><br>");
+ }
+ str.append("</td></tr></table>");
+ return str.toString();
+ }
+
+ public static String urlBlock(String description, String urls[]) {
+ StringBuilder str = new StringBuilder();
+ str.append("<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">");
+ if (!description.equals("")) {
+ str.append(description);
+ str.append(AHTML.newline());
+ }
+ for (int i = 0; i < urls.length; i++) {
+ str.append("<A HREF=\"" + urls[i] + "\">" + urls[i] + "</A><br>");
+ }
+ str.append("</td></tr></table>");
+ return str.toString();
+ }
+
+ public static String heading(int heading, String str, String id) {
+ return "<h" + heading + (id != null && !id.equals("") ? " id=\"" + id + "\"" : "") + ">" + textToHtml(str) + "</h" + heading + ">";
+ }
+
+ public static String heading(int heading, String str) {
+ return heading(heading, str, null);
+ }
+
+ public static String padSpace(int num, String str) {
+ StringBuilder out = new StringBuilder();
+ for (int i = 0; i < num; i++) {
+ out.append("&nbsp;");
+ }
+ out.append(str);
+ return out.toString();
+ }
+
+ public static String addSpace(int num) {
+ StringBuilder out = new StringBuilder();
+ for (int i = 0; i < num; i++) {
+ out.append("&nbsp;");
+ }
+ return out.toString();
+ }
+
+ public static String para(String str) {
+ return "<p>" + textToHtml(str) + "</p>";
+ }
+
+ public static String italics(String str) {
+ return "<i>" + textToHtml(str) + "</i>";
+ }
+
+ public static String pre(String str) {
+ return "<pre>" + str + "</pre>";
+ }
+
+ public static String blockQuote(String str) {
+ return "<blockquote>" + str + "</blockquote>";
+ }
+
+ public static String newline() {
+ return newline(1);
+ }
+
+ public static String newline(int num) {
+ StringBuilder str = new StringBuilder();
+ for (int i = 0; i < num; i++) {
+ str.append("<br />");
+ }
+ return str + "";
+ }
+
+ public static String name(int num) {
+ return nameTarget("" + num);
+ }
+
+ /**
+ * Create target for hyperlink to jump to
+ *
+ * @param str
+ * @return Return name target string
+ */
+ public static String nameTarget(String str) {
+ if (str == null) {
+ return "";
+ }
+ return "<A NAME=\"" + str + "\">";
+ }
+
+ /**
+ * Create &lt;a href> hyperlink to nameTarget
+ *
+ * @param num
+ * @param text
+ * @return Return name link string
+ */
+ public static String nameLink(int num, String text) {
+ return nameLink("" + num, text);
+ }
+
+ /**
+ * Create &lt;a href> hyperlink to nameTarget
+ *
+ * @param name
+ * @param text
+ * @return Return name link string
+ */
+ public static String nameLink(String name, String text) {
+ return "<A HREF=\"#" + name + "\">" + text + "</A>";
+ }
+
+ /**
+ * Create &lt;a href> hyperlink to nameTarget using name as hyperlink tag and display text
+ *
+ * @param name
+ * @return Return name link string
+ */
+ public static String nameLink(String name) {
+ return "<A HREF=\"#" + name + "\">" + name + "</A>";
+ }
+
+ public static String simpleTable(String str) {
+ return simpleTable(str, 100);
+ }
+
+ /**
+ * Create a table with one row/colum containing str
+ *
+ * @param str
+ * @param width
+ * @return return simple table string
+ */
+ public static String simpleTable(String str, int width) {
+ return "<table border=\"0\" cellpadding=\"3\" cellspacing=\"0\" width=\"" + width + "%\">" + "<tr><td>" + str + "</td></tr>" + "</table>";
+ }
+
+ /**
+ * Create a table with one row/colum containing str
+ *
+ * @param str
+ * @param width
+ * @param bgcolor
+ * @return Return border table string
+ */
+ public static String borderTable(String str, int width, String bgcolor, String caption) {
+ return startBorderTable(width, bgcolor, caption) + str + endBorderTable();
+ }
+
+ public static String startBorderTable(int width, String bgcolor, String caption) {
+ String capStr = "";
+ if (!caption.equals("")) {
+ capStr = "<caption ALIGN=top>" + caption + "</caption>";
+ }
+ return "<table border=\"1\" align=\"center\" bgcolor=\"" + bgcolor + "\" cellpadding=\"3\" cellspacing=\"0\" width=\"" + width + "%\">" + capStr + "<tr><td>";
+ }
+
+ public static String endBorderTable() {
+ return "</td></tr></table>";
+ }
+
+ /**
+ * Create a table with one row multi column containing str[]
+ *
+ * @param str = array of strings for columns
+ * @return Return multi-column table string
+ */
+ public static String multiColumnTable(String[] str) {
+ return multiColumnTable(str, 85);
+ }
+
+ /**
+ * Create a table with one row multi column containing str[]
+ *
+ * @param str - array of strings for columns
+ * @param width - percent (1..100) of screen for table
+ * @return Return multi-column table string
+ */
+ public static String multiColumnTable(String[] str, int width) {
+ StringBuilder s = new StringBuilder();
+ s.append("<table border=\"0\" cellpadding=\"3\" cellspacing=\"0\" width=\"" + width + "%\"><tr>");
+ for (int i = 0; i < str.length; i++) {
+ s.append("<td>");
+ s.append(str[i]);
+ s.append("</td>");
+ }
+ s.append("</tr></table>");
+ return s.toString();
+ }
+
+ public static String beginMultiColumnTable(int width) {
+ return beginMultiColumnTable(width, 0);
+ }
+
+ public static String beginMultiColumnTable(int width, int border) {
+ return beginMultiColumnTable(width, border, null);
+ }
+
+ public static String beginMultiColumnTable(int width, int border, Integer color) {
+ return "<table border=\"" + border + "\" " + (color != null ? "color=\"" + color + "\"" : "") + "cellpadding=\"3\" cellspacing=\"0\" width=\"" + width + "%\">";
+ }
+
+ public static String endMultiColumnTable() {
+ return "</table>";
+ }
+
+ public static String addRowMultiColumnTable(String... str) {
+ return addRowMultiColumnTable(str, null, null);
+ }
+
+ public static String addRowMultiColumnTable(String[] str, String[] colOptions) {
+ return addRowMultiColumnTable(str, colOptions, null);
+ }
+
+ public static String addRowMultiColumnTable(String[] str, String[] colOptions, String backgroundColor) {
+ StringBuilder s = new StringBuilder();
+ if (backgroundColor != null) {
+ s.append("<tr bgcolor=\"" + backgroundColor + "\">");
+ } else {
+ s.append("<tr>");
+ }
+ String show = "";
+ for (int i = 0; i < str.length; i++) {
+ show = str[i];
+ if (show == null || show.equals("")) {
+ show = AHTML.addSpace(1);
+ }
+ String colOptionStr = "";
+ if (colOptions != null) {
+ colOptionStr = colOptions[i];
+ }
+ s.append("<td" + (colOptionStr != null && !colOptionStr.equals("") ? colOptionStr : "") + ">" + show + "</td>");
+ }
+ s.append("</tr>");
+ return s.toString();
+ }
+
+ public static String addRowSpanMultiColumnTable(String str, int span) {
+ return "<tr><td colspan=" + span + ">" + str + "</td></tr>";
+ }
+
+ public static class CellItem {
+ String text;
+ private final String fgColor;
+ private final String bgColor;
+
+ public CellItem(String text) {
+ this(text, null, null);
+ }
+
+ public CellItem(String text, String fgColor, String bgColor) {
+ this.text = text;
+ this.fgColor = fgColor;
+ this.bgColor = bgColor;
+ }
+ }
+
+ public static String addRowMultiColumnTable(Collection<CellItem> items) {
+ StringBuilder s = new StringBuilder("<tr>");
+ for (CellItem item : items) {
+ if (item.text == null || item.text.equals("")) {
+ item.text = ".";
+ }
+ if (item.bgColor != null) {
+ s.append("<td bgcolor=\"" + item.bgColor + "\">");
+ } else {
+ s.append("<td>");
+ }
+ s.append(AHTML.color(item.fgColor, item.text));
+ s.append("</td>");
+ }
+ s.append("</tr>");
+ return s.toString();
+ }
+
+ public static String addHeaderRowMultiColumnTable(List<String> strs) {
+ return addHeaderRowMultiColumnTable(strs.toArray(new String[strs.size()]));
+ }
+
+ public static String addHeaderRowMultiColumnTable(String[] str) {
+ return addHeaderRowMultiColumnTable(str, null);
+ }
+
+ public static String addHeaderRowMultiColumnTable(String[] str, Integer width[]) {
+ StringBuilder s = new StringBuilder("<tr>");
+ String widthStr = "";
+ for (int i = 0; i < str.length; i++) {
+ if (width != null) {
+ widthStr = " width =\"" + width[i] + "\"";
+ }
+ s.append("<th");
+ s.append(widthStr);
+ s.append(">");
+ s.append(str[i]);
+ s.append("</th>");
+ }
+ s.append("</tr>");
+ return s.toString();
+ }
+
+ public static void addSimpleTableRow(Appendable appendable, String contents) throws IOException {
+ appendable.append("<tr><td>");
+ appendable.append(contents);
+ appendable.append("</td></tr>");
+ }
+
+ public static void addSimpleHeaderRow(Appendable appendable, String contents) throws IOException {
+ appendable.append("<tr><th>");
+ appendable.append(contents);
+ appendable.append("</th></tr>");
+ }
+
+ public static void beginSimpleTable(Appendable appendable) throws IOException {
+ beginSimpleTable(appendable, 1, 100);
+ }
+
+ public static void beginSimpleTable(Appendable appendable, int border, int width) throws IOException {
+ appendable.append("<table border=\"");
+ appendable.append(String.valueOf(border));
+ appendable.append("\" cellpadding=\"0\" cellspacing=\"0\" width=\"");
+ appendable.append(String.valueOf(width));
+ appendable.append("%\">");
+ }
+
+ public static void endSimpleTable(Appendable appendable) throws IOException {
+ appendable.append("</table>");
+ }
+
+ public static String createTable(List<String> datas, String[] headers, int numColumns, int cellPadding, int border) {
+ StringBuilder table = new StringBuilder(begin);
+
+ if (datas == null) {
+ throw new IllegalArgumentException("The data can not be null");
+ }
+ if (datas.size() % numColumns != 0) {
+ throw new IllegalArgumentException(
+ "The table could not be created becuase the data does not match the column size");
+ }
+ if (border > 0) {
+ table.append("border=\"" + border + "\"");
+ }
+ if (cellPadding > 0) {
+ table.append("cellpadding=\"" + cellPadding + "\"");
+ }
+ table.append(">");
+
+ if (headers != null && headers.length == numColumns) {
+ table.append("<tr>");
+ for (String header : headers) {
+ table.append("<th>" + header + "</th>");
+ }
+ table.append("</tr>");
+ }
+
+ int colIndex = 0;
+ for (String data : datas) {
+
+ if (colIndex == 0) {
+ table.append("<tr>");
+ }
+ table.append("<td>" + data + "</td>");
+ colIndex++;
+
+ if (colIndex == numColumns) {
+ table.append("</tr>");
+ colIndex = 0;
+ }
+ }
+ return table.toString();
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/Lib.java b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/Lib.java
index 4cd5b4a35aa..828bfc5a888 100644
--- a/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/Lib.java
+++ b/plugins/org.eclipse.osee.framework.jdk.core/src/org/eclipse/osee/framework/jdk/core/util/Lib.java
@@ -71,1665 +71,1669 @@ import org.eclipse.osee.framework.jdk.core.util.io.MatchFilter;
* @author Ryan D. Brooks
*/
public final class Lib {
- public final static Runtime runtime = Runtime.getRuntime();
-
- public final static String jarPath = getJarPath(Lib.class);
-
- public final static String basePath = getBasePath();
-
- public final static String lineSeparator = System.getProperty("line.separator");
-
- public static String toFirstCharUpperCase(String str) {
- if (str == null) {
- return null;
- }
- char[] chars = str.toCharArray();
- chars[0] = Character.toUpperCase(str.charAt(0));
- return new String(chars);
- }
-
- public static int numOccurances(String str, String regex) {
- int x = 0;
- Matcher m = Pattern.compile(regex).matcher(str);
- while (m.find()) {
- x++;
- }
- return x;
- }
-
- public static String exceptionToString(Throwable ex) {
- StringBuilder sb = new StringBuilder();
- exceptionToString(ex, sb);
- return sb.toString();
- }
-
- public static boolean validateEmail(String toValidate) {
- Pattern pattern =
- Pattern.compile("^[a-z0-9\\._-]" + "+@([a-z0-9][a-z0-9-]*" + "[a-z0-9]\\.)+" + "([a-z]+\\.)?([a-z]+)$",
- Pattern.CASE_INSENSITIVE);
- Matcher matcher = pattern.matcher(toValidate);
- return matcher.find();
- }
-
- private static void exceptionToString(Throwable ex, StringBuilder sb) {
- if (ex == null) {
- sb.append("Exception == null; can't display stack");
- return;
- }
- sb.append(ex.getMessage() + "\n");
- StackTraceElement st[] = ex.getStackTrace();
- for (int i = 0; i < st.length; i++) {
- StackTraceElement ste = st[i];
- sb.append(" at " + ste.toString() + "\n");
- }
- Throwable cause = ex.getCause();
- if (cause != null) {
- sb.append(" caused by ");
- exceptionToString(cause, sb);
- }
- }
-
- public static String changeExtension(String str, String newExt) {
- int pos = str.lastIndexOf('.');
- if (pos == -1) { // was -1 before + 1
- return str + "." + newExt;
- }
- return str.substring(0, pos + 1) + newExt;
- }
-
- /**
- * this version of changeExtension will work even if the extension we want to replace contains a .
- *
- * @param str
- * @param oldExt
- * @param newExt
- * @return String
- */
- public static String changeExtension(String str, String oldExt, String newExt) {
- int pos = str.lastIndexOf(oldExt);
- if (pos == -1) {
- return str + "." + newExt;
- }
- return str.substring(0, pos) + newExt;
- }
-
- /**
- * Move an object one before the previous object
- *
- * @param list
- * @param obj
- * @return true if successful
- */
- public static boolean moveBack(ArrayList<Object> list, Object obj) {
- if (list.contains(obj)) {
- int index = list.indexOf(obj);
- if (index > 0) {
- list.remove(index);
- list.add(index - 1, obj);
- return true;
- }
- }
- return false;
- }
-
- /**
- * Move an object one after the next object
- *
- * @param obj
- * @return true if successful
- */
- public static boolean moveForward(ArrayList<Object> list, Object obj) {
- int size = list.size();
- if (list.contains(obj)) {
- int index = list.indexOf(obj);
- if (index < size - 1) {
- list.remove(index);
- list.add(index + 1, obj);
- return true;
- }
- }
- return false;
- }
-
- public static void copyDirectory(File source, File destination) throws IOException {
- File[] files = source.listFiles();
-
- for (int i = 0; i < files.length; i++) {
- if (files[i].isDirectory()) {
- File dir = new File(destination, files[i].getName());
- dir.mkdir();
- copyDirectory(files[i], dir);
- } else { // else is a file
- copyFile(files[i], destination);
- }
- }
- }
-
- public static String exceptionToString(Exception ex) {
- StringWriter stringWriter = new StringWriter();
- PrintWriter printWriter = new PrintWriter(stringWriter);
- ex.printStackTrace(printWriter);
- return stringWriter.toString();
- }
-
- public static void copyFile(File source, File destination) throws IOException {
- final FileChannel in = new FileInputStream(source).getChannel();
- try {
- final FileChannel out;
- if (destination.isDirectory()) {
- out = new FileOutputStream(new File(destination, source.getName())).getChannel();
- } else {
- if (destination.exists()) {
- destination.delete(); // to work around some file permission
- }
- // problems
- out = new FileOutputStream(destination).getChannel();
- }
- try {
- long position = 0;
- long size = in.size();
- while (position < size) {
- position += in.transferTo(position, size, out);
- }
- } finally {
- out.close();
- }
- } finally {
- in.close();
- }
- }
-
- public static void copyFiles(File source, File destination) throws IOException {
- copyFiles(source, null, destination);
- }
-
- public static void copyFiles(File source, FilenameFilter filter, File destination) throws IOException {
- File[] files = source.listFiles(filter);
- if (!source.exists()) {
- throw new IllegalArgumentException("the directory " + source + " does not exist.");
- }
-
- if (files != null) {
- for (int i = 0; i < files.length; i++) {
- if (files[i].isFile()) {
- copyFile(files[i], destination);
- }
- }
- }
- }
-
- public static Image createImage(String path) {
- return createImageIcon(path).getImage();
- }
-
- public static ImageIcon createImageIcon(Class<?> clasaRef, String path) {
- URL imgURL = clasaRef.getResource(path);
- if (imgURL != null) {
- return new ImageIcon(imgURL);
- } else {
- System.err.println("Couldn't find the resource: " + path);
- return null;
- }
- }
-
- /** Returns an ImageIcon, or null if the path was invalid. */
- public static ImageIcon createImageIcon(String path) {
- return createImageIcon(Lib.class, path);
- }
-
- public static void deleteDir(File directory) {
- File[] files = directory.listFiles();
- if (files == null) {
- return;
- }
-
- for (int i = 0; i < files.length; i++) {
- if (files[i].isDirectory()) {
- deleteDir(files[i]);
- } else { // else is a file
- files[i].delete();
- }
- }
- directory.delete();
- }
-
- public static void deleteContents(File directory) {
- deleteContents(directory, null);
- }
-
- public static void deleteContents(File directory, FilenameFilter filter) {
- File[] files = directory.listFiles(filter);
-
- for (int i = 0; i < files.length; i++) {
- if (files[i].isDirectory()) {
- deleteContents(files[i]);
- }
- files[i].delete();
- }
- }
-
- /**
- * Delete the current file and all empty parents. The method will stop deleting empty parents once it reaches the
- * stopAt parent.
- *
- * @param stopAt path of the parent file to stop deleting at
- * @param file to delete
- * @return status <b>true</b> if successful
- */
- public static boolean deleteFileAndEmptyParents(String stopAt, File file) {
- boolean result = true;
- if (file != null) {
- if (file.isDirectory() != false) {
- if (file.list().length == 0) {
- result &= file.delete();
- }
- } else {
- result &= file.delete();
- }
- }
- File parent = file.getParentFile();
- if (parent != null && parent.getAbsolutePath().equals(stopAt) != true) {
- result &= deleteFileAndEmptyParents(stopAt, parent);
- }
- return result;
- }
-
- /**
- * Deletes all files from directory
- *
- * @param directory
- */
- public static void emptyDirectory(File directory) {
- File[] children = directory.listFiles();
- if (children != null) {
- for (File child : children) {
- if (child.isDirectory()) {
- emptyDirectory(child);
- } else { // else is a file
- child.delete();
- }
- }
- }
- }
-
- public static void inputStreamToOutputStream(InputStream inputStream, OutputStream outputStream) throws IOException {
- if (inputStream == null) {
- throw new IllegalArgumentException("inputStream was null");
- }
- if (outputStream == null) {
- throw new IllegalArgumentException("outputStream was null");
- }
-
- byte[] buf = new byte[10000];
- int count = -1;
- while ((count = inputStream.read(buf)) != -1) {
- outputStream.write(buf, 0, count);
- }
- }
-
- public static int getMatcherCount(Pattern p, String str) {
- return getMatcherCount(p.matcher(str));
- }
-
- public static int getMatcherCount(Matcher m) {
- int count = 0;
- while (m.find()) {
- count++;
- }
- return count;
- }
-
- public static String inputStreamToString(InputStream in) throws IOException {
- return inputStreamToChangeSet(in).toString();
- }
-
- public static ChangeSet inputStreamToChangeSet(InputStream in) throws IOException {
- InputStreamReader reader = new InputStreamReader(in, "UTF-8");
- ChangeSet set = new ChangeSet();
-
- char[] chars = new char[8000];
- int readCount = 0;
- while ((readCount = reader.read(chars)) != -1) {
- set.insertBefore(0, chars, 0, readCount, true);
- }
- return set;
- }
-
- public static byte[] inputStreamToBytes(InputStream inputStream) throws IOException {
- ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
- try {
- inputStreamToOutputStream(inputStream, outputStream);
- } finally {
- if (inputStream != null) {
- inputStream.close();
- }
- }
- return outputStream.toByteArray();
- }
-
- public static void inputStreamToFile(InputStream inputStream, File outFile) throws IOException {
- byte[] bytes = new byte[2024];
- FileOutputStream out = new FileOutputStream(outFile);
-
- int numBytesRead;
- while ((numBytesRead = inputStream.read(bytes)) != -1) {
- out.write(bytes, 0, numBytesRead);
- }
- out.close();
- }
-
- public static CharBuffer inputStreamToCharBuffer(InputStream in) throws IOException {
- return CharBuffer.wrap(inputStreamToChangeSet(in).toCharArray());
- }
-
- public static java.io.InputStream stringToInputStream(String value) throws Exception {
- if (value == null) {
- return null;
- }
- value = value.trim();
- java.io.InputStream in = new java.io.ByteArrayInputStream(value.getBytes("UTF-8"));
- return in;
- }
-
- public static InputStream byteBufferToInputStream(final ByteBuffer byteBuffer) {
-
- return new InputStream() {
- @Override
- public synchronized int read() throws IOException {
- if (!byteBuffer.hasRemaining()) {
- return -1;
- }
- return byteBuffer.get();
- }
-
- @Override
- public synchronized int read(byte[] bytes, int off, int len) throws IOException {
- len = Math.min(len, byteBuffer.remaining());
- if (off != len) {
- byteBuffer.get(bytes, off, len);
- } else {
- len = -1;
- }
- return len;
- }
-
- @Override
- public synchronized void reset() throws IOException {
- byteBuffer.rewind();
- }
-
- };
- }
-
- public static OutputStream byteBufferToOutputStream(final ByteBuffer byteBuffer) {
- return new OutputStream() {
- @Override
- public synchronized void write(int b) throws IOException {
- byteBuffer.put((byte) b);
- }
-
- @Override
- public synchronized void write(byte[] bytes, int off, int len) throws IOException {
- byteBuffer.put(bytes, off, len);
- }
- };
- }
-
- public static final Pattern numberListPattern = Pattern.compile("\\d+");
-
- public static List<Integer> stringToIntegerList(String numberList) {
- ArrayList<Integer> ints = new ArrayList<Integer>();
- Matcher transactionIdMatcher = numberListPattern.matcher(numberList);
- while (transactionIdMatcher.find()) {
- ints.add(Integer.parseInt(transactionIdMatcher.group()));
- }
- return ints;
- }
-
- public static String fileToString(File file) throws IOException {
- StringBuffer buffer = new StringBuffer();
- Reader inStream = new InputStreamReader(new FileInputStream(file), "UTF-8");
- Reader in = new BufferedReader(inStream);
- int ch;
- while ((ch = in.read()) > -1) {
- buffer.append((char) ch);
- }
- in.close();
- return buffer.toString();
- }
-
- public static byte[] fileToBytes(File file) throws IOException {
- InputStream inputStream = new FileInputStream(file);
- try {
- byte[] bytes = new byte[(int) file.length()];
- inputStream.read(bytes);
- return bytes;
- } finally {
- inputStream.close();
- }
- }
-
- /**
- * usage: char[] buf = new char[5500000]; for (Iterator iter = files.iterator(); iter.hasNext(); ) { // for each file
- * File file = (File)iter.next(); buf = Lib.fileToChars(file, buf);
- *
- * @param file
- * @param buf
- * @return char[]
- * @throws IOException
- */
- public static char[] fileToChars(File file, char[] buf) throws IOException {
- FileReader in = new FileReader(file);
- int size = (int) file.length();
-
- if (buf == null) {
- buf = new char[size];
- } else if (size > buf.length) {
- buf = null;
- System.gc(); // since the currently allocated buf might already be quite large
- buf = new char[size];
- }
-
- in.read(buf);
- in.close();
- return buf;
- }
-
- public static CharBuffer fileToCharBuffer(File file) throws IOException {
- FileReader in = new FileReader(file);
- char[] chars = new char[(int) file.length()];
- in.read(chars);
- in.close();
- return CharBuffer.wrap(chars);
- }
-
- public static String fillString(char c, int n) {
- char[] chars = new char[n];
- for (int i = 0; i < n; chars[i++] = c) {
- // must leave empty block here so the following line won't become
- // part of the loop
- }
- return new String(chars);
- }
-
- /**
- * Get file extension from the file path
- *
- * @param filepath
- * @return file extension
- */
- public static String getExtension(String filepath) {
- filepath = filepath.trim();
- String separatorRegEx = File.separator;
- if (Lib.isWindows()) {
- separatorRegEx = "\\\\";
- }
- String[] pathsArray = filepath.split(separatorRegEx);
-
- String fileName = pathsArray[0];
- if (pathsArray.length > 0) {
- fileName = pathsArray[pathsArray.length - 1];
- }
-
- int index = fileName.lastIndexOf('.');
- if (index >= 0 && index + 1 < fileName.length()) {
- return fileName.substring(index + 1);
- } else {
- return "";
- }
- }
-
- public static int handleProcess(Process proc) {
- return handleProcess(proc, new PrintWriter(System.out, true));
- }
-
- public static int handleProcess(Process proc, Writer output, String errName, String outName) {
- return handleProcess(proc, output, errName, outName, true);
- }
-
- public static int handleProcess(Process proc, Writer output, String errName, String outName, boolean verbose) {
- try {
- IOOutputThread errThread =
- new IOOutputThread(output, new BufferedReader(new InputStreamReader(proc.getErrorStream())), verbose);
- IOOutputThread outThread =
- new IOOutputThread(output, new BufferedReader(new InputStreamReader(proc.getInputStream())), verbose);
-
- errThread.setName(errName);
- outThread.setName(outName);
- errThread.start();
- outThread.start();
- proc.waitFor();
- int exitCode = proc.exitValue();
- if (exitCode != 0) {
- output.write("Process exit code is: " + exitCode + "\n");
- }
- int count = 0;
- while (errThread.isAlive() || outThread.isAlive()) {
- if (count > 10) {
- break;
- }
- synchronized (Thread.currentThread()) {
- Thread.currentThread().wait(500);
- }
- count++;
- }
- output.flush();
- return exitCode;
- } catch (IOException ex) {
- System.err.println(ex);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- return Integer.MIN_VALUE;
- }
-
- public static int handleProcess(Process proc, Writer output) {
- return handleProcess(proc, output, "err", "out");
- }
-
- public static int handleProcess(Process proc, Writer output, boolean verbose) {
- return handleProcess(proc, output, "err", "out", verbose);
- }
-
- /**
- * Sets up an error, input, and output stream for the given process. The error stream gives all information coming
- * FROM the process through it's err stream. The "outThread" will be what come from the FROM the process through it's
- * normal output stream. The "inThread" is the stream for issuing commands TO the process.
- *
- * @param proc The process whose streams we are setting up
- * @param output Where all info coming FROM the minicom is sent
- * @param input Where all data going TO the minicom is sent
- * @return An array of threads in the following order:<br>
- * --index 0 = Err Stream<br>
- * --index 1 = output stream<br>
- * --index 2 = input stream<br>
- */
- public static Thread[] handleMinicomProcess(Process proc, Writer output, Reader input) {
- IOOutputThread errThread =
- new IOOutputThread(output, new BufferedReader(new InputStreamReader(proc.getErrorStream())));
-
- InputBufferThread outThread = new InputBufferThread(proc.getInputStream());
-
- errThread.setName("err");
- outThread.setName("out");
- errThread.start();
- outThread.start();
-
- if (input != null) {
- IOInputThread inThread =
- new IOInputThread(input, new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())));
- inThread.setName("in");
- inThread.start();
- return new Thread[] {errThread, outThread, inThread};
- }
- return new Thread[] {errThread, outThread};
- }
-
- public static Thread[] handleProcessNoWait(Process proc, Writer output) {
- return handleProcessNoWait(proc, output, output, null);
- }
-
- public static Thread[] handleProcessNoWait(Process proc, Writer output, boolean verbose) {
- return handleProcessNoWait(proc, output, output, null, "err", "out", verbose);
- }
-
- public static Thread[] handleProcessNoWait(Process proc, Writer output, Writer errorWriter, Reader reader) {
- return handleProcessNoWait(proc, output, errorWriter, reader, "err", "out", true);
- }
-
- public static Thread[] handleProcessNoWait(Process proc, Writer outputWriter, Writer errorWriter, Reader reader, String errName, String outName) {
- return handleProcessNoWait(proc, outputWriter, errorWriter, reader, errName, outName, true);
- }
-
- public static Thread[] handleProcessNoWait(Process proc, Writer outputWriter, Writer errorWriter, Reader reader, String errName, String outName, boolean verbose) {
- IOOutputThread errThread =
- new IOOutputThread(errorWriter, new BufferedReader(new InputStreamReader(proc.getErrorStream())), verbose);
- IOOutputThread outThread =
- new IOOutputThread(outputWriter, new BufferedReader(new InputStreamReader(proc.getInputStream())), verbose);
- errThread.setName(errName);
- outThread.setName(outName);
- errThread.start();
- outThread.start();
- if (reader != null) {
- IOInputThread inThread =
- new IOInputThread(reader, new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())));
- inThread.setName("in");
- inThread.start();
- return new Thread[] {errThread, outThread, inThread};
- }
- return new Thread[] {errThread, outThread};
- }
-
- public static void makeDirClean(File directory) {
- if (directory.exists()) {
- Lib.deleteContents(directory);
- } else {
- directory.mkdir();
- }
- }
-
- public static void moveFiles(File source, File destination) {
- moveFiles(source, null, destination);
- }
-
- public static void moveFiles(File source, FilenameFilter filter, File destination) {
- File[] files = source.listFiles(filter);
-
- for (int i = 0; i < files.length; i++) {
- if (files[i].isFile()) {
- files[i].renameTo(new File(destination, files[i].getName()));
- }
- }
- }
-
- public static String getSpace(int length) {
- return getCharacter(' ', length);
- }
-
- public static String getCharacter(char c, int length) {
- StringBuilder out = new StringBuilder();
- for (int i = 0; i < length; i++) {
- out.append(c);
- }
- return out.toString();
- }
-
- public static String padLeading(String str, char c, int n) {
- char[] chars = new char[n];
- int pos = Math.min(n, str.length());
- str.getChars(0, pos, chars, n - pos);
- for (int i = 0; i < n - pos; chars[i++] = c) {
- // must leave empty block here so the following line won't become
- // part of the loop
- }
- return new String(chars);
- }
-
- public static String padTrailing(String str, char c, int n) {
- char[] chars = new char[n];
- int pos = Math.min(n, str.length());
- str.getChars(0, pos, chars, 0);
- for (int i = pos; i < n; chars[i++] = c) {
- // must leave empty block here so the following line won't become
- // part of the loop
- }
- return new String(chars);
- }
-
- public static int printAndExec(String[] callAndArgs) {
- return printAndExec(callAndArgs, null, new BufferedWriter(new PrintWriter(System.out, true)));
- }
-
- public static int printAndExec(String[] callAndArgs, File dir) {
- return printAndExec(callAndArgs, dir, new PrintWriter(System.out, true));
- }
-
- public static int printAndExec(String[] callAndArgs, File dir, Writer output) {
- try {
- for (int j = 0; j < callAndArgs.length; j++) {
- output.write(callAndArgs[j] + " ");
- }
- output.write("\n");
- output.flush();
-
- return Lib.handleProcess(runtime.exec(callAndArgs, null, dir), output);
- } catch (IOException ex) {
- System.err.println("error: " + ex);
- return -1;
- }
- }
-
- public static ArrayList<String> readListFromDir(File directory, FilenameFilter filter, boolean keepExtension) {
- ArrayList<String> list = new ArrayList<String>(400);
-
- if (directory == null) {
- System.out.println("Invalid path: " + directory);
- return list;
- }
-
- File[] files = directory.listFiles(filter);
- if (files == null) {
- System.out.println("Invalid path: " + directory);
- return list;
- }
- if (files.length > 0) {
- Arrays.sort(files);
- }
-
- if (keepExtension) {
- for (int i = 0; i < files.length; i++) {
- list.add(files[i].getName());
- }
- } else {
- for (int i = 0; i < files.length; i++) {
- list.add(Lib.removeExtension(files[i].getName()));
- }
- }
-
- return list;
- }
-
- public static ArrayList<String> readListFromDir(String directory, FilenameFilter filter) {
- return readListFromDir(new File(directory), filter, false);
- }
-
- public static ArrayList<String> readListFromFile(File file, boolean keepExtension) throws IOException {
- BufferedReader in = new BufferedReader(new FileReader(file));
- ArrayList<String> list = new ArrayList<String>(120);
-
- String line = null;
-
- if (keepExtension) {
- while ((line = in.readLine()) != null) {
- list.add(line);
- }
- } else {
- while ((line = in.readLine()) != null) {
- list.add(Lib.removeExtension(line));
- }
- }
- in.close();
- return list;
- }
-
- public static ArrayList<String> readListFromFile(String file) throws IOException {
- return readListFromFile(new File(file), true);
- }
-
- public static boolean isLink(File file) {
- if (!file.exists()) {
- return true;
- }
- try {
- return !file.getAbsolutePath().equals(file.getCanonicalPath());
- } catch (IOException ex) {
- return true;
- }
- }
-
- public static List<File> recursivelyListFilesAndDirectories(ArrayList<File> fileList, File rootPath, Pattern filePathP, boolean includeDirectories) {
- LinkedList<File> dirList = new LinkedList<File>();
- dirList.add(rootPath);
-
- Matcher fileNameM = null;
- if (filePathP != null) {
- fileNameM = filePathP.matcher("");
- }
-
- while (!dirList.isEmpty()) {
- File parent = dirList.removeFirst();
- if (parent == null) {
- System.out.println("Invalid path.");
- continue;
- }
-
- if (parent.getName().startsWith(".Rational")) {
- continue;
- }
-
- File[] files = parent.listFiles();
- if (files == null) {
- System.out.println("Invalid path: " + parent);
- continue;
- }
-
- for (int i = 0; i < files.length; i++) {
- if (files[i].isDirectory()) {
- dirList.add(files[i]);
- if (includeDirectories) {
- fileList.add(files[i]);
- }
- } else { // else is a file
- if (fileNameM == null) {
- fileList.add(files[i]);
- } else {
- fileNameM.reset(files[i].getPath());
- if (fileNameM.matches()) {
- fileList.add(files[i]);
- }
- }
- }
- }
- }
- return fileList;
- }
-
- /**
- * Returns an array list of File objects
- *
- * @param fileList
- * @param rootPath
- * @param fileNameP
- * @return List
- */
- public static List<File> recursivelyListFiles(ArrayList<File> fileList, File rootPath, Pattern filePathP) {
- return recursivelyListFilesAndDirectories(fileList, rootPath, filePathP, false);
- }
-
- public static List<File> recursivelyListFiles(File rootPath, Pattern fileNameP) {
- return recursivelyListFiles(new ArrayList<File>(400), rootPath, fileNameP);
- }
-
- /**
- * Assumptions: block comments are not nested and comment blocks have an ending Note: may be fooled by string
- * literals that contains the block comment indicators
- *
- * @param charBuf
- * @return CharBuffer
- */
- public static CharBuffer stripBlockComments(CharBuffer charBuf) {
- char[] chars = charBuf.array();
- int i = 0;
- int k = 0;
-
- try {
- while (i < chars.length) {
- if (chars[i] == '/' && chars[i + 1] == '*') {
- i += 2;
- while (!(chars[i++] == '*' && chars[i] == '/')) {
- // must leave empty block here so the following line
- // won't become part of the loop
- }
- i++;
- } else {
- chars[k++] = chars[i++];
- }
- }
- charBuf.limit(k);
- return charBuf;
- } catch (ArrayIndexOutOfBoundsException ex) {
- throw new IllegalArgumentException("Incorrectly formatted comments.");
- }
- }
-
- /**
- * Remove the file extension from the file path
- *
- * @param filepath
- * @return modified file path
- */
- public static String removeExtension(String filepath) {
- String ext = getExtension(filepath);
- if (ext != null && ext.length() > 0) {
- filepath = filepath.substring(0, filepath.length() - (ext.length() + 1));
- }
- return filepath;
- }
-
- public static String removeExtension(File file) {
- return removeExtension(file.getName());
- }
-
- /**
- * Remove the file extension from the file path
- *
- * @param string
- * @return string with no leading or trailing
- */
- public static String removeLeadingAndTrailingSpaces(String str) {
- String ext = str.replaceFirst("^ *", "");
- return ext.replaceFirst(" *$", "");
- }
-
- /**
- * Determine if file is a compressed file
- *
- * @param file to check
- * @return <b>true</b> if the files is a compressed file
- */
- public static boolean isCompressed(File file) {
- boolean toReturn = false;
- String ext = getExtension(file.getAbsolutePath());
- if (ext.equals("zip")) {
- toReturn = true;
- }
- return toReturn;
- }
-
- // replaces the first capturing group of the match in fileToModify with
- // replaceSeq and write this back to fileToModify
- public static boolean updateFile(File fileToModify, Pattern pattern, CharSequence replaceSeq) throws IOException {
- CharBuffer modifyBuf = Lib.fileToCharBuffer(fileToModify);
-
- Matcher matcher = pattern.matcher(modifyBuf);
- if (!matcher.find()) {
- System.out.println(fileToModify.getPath() + " does not contain the pattern: " + pattern.pattern());
- return false;
- }
- CharBuffer topSection = (CharBuffer) modifyBuf.subSequence(0, matcher.start(1)); // everything
- // before the
- // pattern
- CharBuffer bottomSection = null;
- int bottomLen = 0;
- if (matcher.end(1) != modifyBuf.length()) {
- bottomSection = (CharBuffer) modifyBuf.subSequence(matcher.end(1), modifyBuf.length());
- bottomLen = bottomSection.length();
- }
-
- CharBuffer outBuf = CharBuffer.allocate(topSection.length() + replaceSeq.length() + bottomLen);
- outBuf.put(topSection);
- if (replaceSeq instanceof String) {
- outBuf.put((String) replaceSeq);
- } else if (replaceSeq instanceof CharBuffer) {
- outBuf.put((CharBuffer) replaceSeq);
- } else {
- outBuf.put(replaceSeq.toString());
- }
- if (bottomSection != null) {
- outBuf.put(bottomSection);
- }
- Lib.writeCharBufferToFile(outBuf, fileToModify);
-
- return true;
- }
-
- public static boolean updateFile(File fileToModify, Pattern pattern, File original) throws IOException {
- return updateFile(fileToModify, pattern, fileToCharBuffer(original));
- }
-
- public static void writeCharBufferToFile(CharBuffer charBuf, File outFile) throws IOException {
- writeCharsToFile(charBuf.array(), outFile);
- }
-
- public static void writeCharsToFile(char[] chars, File outFile) throws IOException {
- FileWriter out = new FileWriter(outFile);
- out.write(chars, 0, chars.length);
- out.close();
- }
-
- public static void writeStringToFile(String str, File outFile) throws IOException {
- OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8");
- char[] chars = str.toCharArray();
- out.write(chars, 0, chars.length);
- out.close();
- }
-
- public static String getBasePath() {
- return Lib.getBasePath(Lib.class);
- }
-
- public static String getDateTimeString() {
- return new SimpleDateFormat("yyyy-MM-dd_hh-mm").format(new Date());
- }
-
- public static String getJarPath(Class<Lib> base) {
- // the leading '/' tells getResource not to append the package name
- // (instead the leading / is just stripped off)
- String className = "/" + base.getName().replace('.', '/') + ".class";
- String path = base.getResource(className).getPath();
-
- int pos = path.lastIndexOf("!");
- if (pos == -1) { // class is not in a jar file
- return null;
- } else { // class is in a jar file
- String jarpath = path.substring("file:".length(), pos);
- return jarpath.replaceAll("%20", " ");
- }
- }
-
- /**
- * @param base
- * @return The path which was used to load the class file. If the file was loaded from a .jar, then the full path to
- * the jar. If the file was loaded from a .class, then the path up to the root of the package.
- */
- public static String getClassLoadPath(Class<?> base) {
- /*
- * Using the getProtectionDomain() method seems to be yield more consistent results than
- * getResource(className).getPath(); particularly when being run with the Eclipse class
- * loader. It was found that the Eclipse class loader did not always return the full path when
- * asked for the resource.
- */
-
- ProtectionDomain pd = base.getProtectionDomain();
- CodeSource cs = pd.getCodeSource();
- URL csLoc = cs.getLocation();
- String path = csLoc.getPath();
- path = path.replaceAll("%20", " ");
- return path;
- }
-
- public static String getBasePath(Class<?> base) {
- String path = getClassLoadPath(base);
- path = path.replaceAll("%20", " ");
-
- if (path.endsWith(".jar")) {
- int end = path.lastIndexOf('/');
- path = path.substring(0, end);
- }
- return path;
-
- }
-
- public static URL resolveToUrl(String path) {
- URL url = null;
- System.out.println("resolveToUrl: " + path);
- if (path != null && !path.equals("")) {
- if (path.indexOf("://") == -1) { // if not a full URL yet
- if (!path.startsWith("/")) { // if not absolute then prepend
- // base path
- try {
- path = new File(Lib.basePath + "/" + path).getCanonicalPath();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- path = "file://" + path;
- }
- try {
- url = new URL(path);
- } catch (MalformedURLException ex) {
- ex.printStackTrace();
- }
- }
- return url;
- }
-
- public static String escapeForRegex(String text) {
- char[] chars = text.toCharArray();
- StringBuffer strB = new StringBuffer(chars.length + 5);
-
- for (int i = 0; i < chars.length; i++) {
- switch (chars[i]) {
- case '\\':
- case '[':
- case ']':
- case '.':
- case '{':
- case '}':
- case '^':
- case '$':
- case '?':
- case '*':
- case '+':
- case '|':
- strB.append('\\');
- }
- strB.append(chars[i]);
- }
- return strB.toString();
- }
-
- public static String determineGroup() {
- try {
- Process proc =
- Runtime.getRuntime().exec(
- new String[] {"/usr/bin/bash", "-c", "touch whichGroup; ls -g whichGroup; rm whichGroup"}, null,
- new File("/tmp"));
- BufferedReader inOutput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
- String line = inOutput.readLine();
- return line.substring(15, line.indexOf(' ', 16)); // 15 based on
- // format of
- // line printed
- // by ls
- } catch (IOException ex) {
- System.out.println(ex);
- return "no group";
- }
- }
-
- /**
- * Returns a list of the arguments in the source String passed. It assumes that the first character is a '(' and
- * matches till it finds the matching ')'.
- *
- * @param source
- * @return String[]
- */
- public static String[] getArguments(String source) {
- ArrayList<String> theResults = new ArrayList<String>();
- try {
- if (source.charAt(0) != '(') {
- System.err.println("In getArguments, first char must be \'(\'.");
- return null;
- }
-
- int currentArg = 1;
- int startPos = 1;
- int parens = 0;
- boolean foundValidChar = false;
-
- for (int i = 1; i < source.length(); i++) {
- char theChar = source.charAt(i);
-
- if (theChar == '(') {
- parens++;
- } else if (theChar == ')') {
- parens--;
- if (parens < 0) {
- theResults.add(source.substring(startPos, i));
- break;
- }
- } else if (theChar == ',' && parens == 0) {
- theResults.add(source.substring(startPos, i));
- startPos = i + 1;
- currentArg++;
- foundValidChar = false;
- } else if (!foundValidChar) {
- if (Character.isWhitespace(theChar)) {
- startPos++;
- } else {
- foundValidChar = true;
- }
- }
- }
-
- String[] theTrueResults = new String[theResults.size()];
- theResults.toArray(theTrueResults);
-
- if (theTrueResults.length != currentArg) {
- System.err.println("In getArguments, number of argument mismatch.");
- }
-
- return theTrueResults;
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
-
- public static int getArgsLength(String source) {
- try {
- if (source.charAt(0) != '(') {
- System.err.println("In getArguments, first char must be \'(\'.");
- return -1;
- }
- int parens = 0;
-
- for (int i = 1; i < source.length(); i++) {
- char theChar = source.charAt(i);
-
- if (theChar == '(') {
- parens++;
- } else if (theChar == ')') {
- parens--;
- if (parens < 0) {
- return i - 1;
- }
- }
- }
-
- System.err.println("In getArguments, problem occurred.");
- return -1;
- } catch (Exception e) {
- e.printStackTrace();
- return -1;
- }
- }
-
- /**
- * Returns a list of Strings representing each comma separated string in the string passed. It ignores commas inside
- * () or {}.
- *
- * @param source
- * @return String[]
- */
- public static String[] getCommaSeparatedItems(String source) {
- ArrayList<String> theResults = new ArrayList<String>();
- int startPos = 0;
- int parensCount = 0;
-
- for (int i = 0; i < source.length(); i++) {
- char theChar = source.charAt(i);
-
- if (theChar == '(' || theChar == '{') {
- parensCount++;
- } else if (theChar == ')' || theChar == '}') {
- parensCount--;
- } else if (parensCount == 0 && theChar == ',') {
- theResults.add(source.substring(startPos, i).trim());
- startPos = i + 1;
- }
- }
- theResults.add(source.substring(startPos).trim());
- String[] results = new String[theResults.size()];
- theResults.toArray(results);
- return results;
- }
-
- /**
- * Finds the index of the closing bracket for a function.
- *
- * @param start -the index of the character AFTER the opening bracket for the function
- * @param seq -sequence containing the local function
- * @return -the index of the matching bracket to the opening bracket of this function
- */
- public static int findTheEnd(int start, CharSequence seq) {
- int stack = 1;
- char[] array = seq.subSequence(start, seq.length()).toString().toCharArray();
- int i;
- // print( "checking: " + seq.subSequence(start,
- // seq.length()).toString());
- for (i = 0; i < array.length; i++) {
- // System.out.print( array[i]);
- if (array[i] == '/' && array[i + 1] == '*') {
-
- while (array[i] != '*' || array[i + 1] != '/') {
- i++;
- }
- }
- if (array[i] == '"') {
- i++;
- while (array[i] != '"' || array[i - 1] == '\\') {
- i++;
- }
- }
- if (array[i] == '{') {
- stack++;
-
- } else if (array[i] == '}') {
- stack--;
-
- }
- if (stack == 0) {
- return start + i - 1;
- }
- }
- return start + i - 1;
-
- }
-
- public static final URL getUrlFromString(String path) throws MalformedURLException {
- if (!path.matches("(file:/|file://|http://|C:).*")) {
- return new URL("file://" + path);
- }
- return new URL(path);
- }
-
- public static final URL[] getUrlFromString(String[] path) throws MalformedURLException {
- URL[] urls = new URL[path.length];
- for (int i = 0; i < urls.length; i++) {
- urls[i] = getUrlFromString(path[i]);
- }
- return urls;
- }
-
- public static final String convertToJavaClassName(String name) {
- ChangeSet changeSet = new ChangeSet(name);
- Matcher matcher = Pattern.compile("_([a-zA-Z])").matcher(changeSet.toString());
-
- changeSet.replace(0, 1, Character.toUpperCase(name.charAt(0)));
- while (matcher.find()) {
- changeSet.replace(matcher.start(), matcher.end(), Character.toUpperCase(matcher.group(1).charAt(0)));
- }
-
- return changeSet.applyChangesToSelf().toString();
- }
-
- /**
- * This method takes in any name separated by underscores and converts it into a java standard variable name.
- *
- * @param name
- * @return java variable name
- */
- public static final String convertToJavaVariableName(String name) {
- name = name.toLowerCase();
- StringBuffer sb = new StringBuffer();
- char[] chars = name.toCharArray();
- for (int i = 0; i < chars.length; i++) {
- if (chars[i] == '_') {
- if (chars.length > i + 1 && chars[i + 1] != '_') {
- sb.append(Character.toUpperCase(chars[i + 1]));
- i++;
- }
- } else {
- sb.append(chars[i]);
- }
- }
- return sb.toString();
- }
-
- public static URL getJarFileURL(File directory, String title, String version) throws IOException {
- if (!directory.isDirectory()) {
- throw new IllegalArgumentException(directory.getPath() + " is not a valid directory.");
- }
- File[] jars = directory.listFiles(new MatchFilter(".*\\.jar"));
- for (int i = 0; i < jars.length; i++) {
- JarFile jar = new JarFile(jars[i]);
- Attributes attributes = jar.getManifest().getMainAttributes();
- String jarTitle = attributes.getValue("Implementation-Title");
- String jarVersion = attributes.getValue("Implementation-Version");
- if (jarTitle != null && jarVersion != null && jarTitle.equals(title) && jarVersion.equals(version)) {
- return jars[i].toURI().toURL();
- }
- }
- throw new IllegalArgumentException("The specified version: " + version + " for " + title + " was not found.");
- }
-
- public static URL[] getClasspath() throws MalformedURLException {
- String[] strPaths = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
- URL[] urlPaths = new URL[strPaths.length];
- for (int i = 0; i < strPaths.length; i++) {
- urlPaths[i] = new File(strPaths[i]).toURI().toURL();
- }
- return urlPaths;
- }
-
- public static String getJarFileVersion(String jarFilePath) throws IOException {
- Manifest manifest;
- File jarFile = new File(jarFilePath);
- if (!jarFile.isFile()) {// maybe it's an http connection
- JarInputStream jis = null;
- try {
- URL u = new URL(jarFilePath);
- URLConnection uc = u.openConnection();
- jis = new JarInputStream(uc.getInputStream());
- manifest = jis.getManifest();
- } catch (IOException ex) {
- throw new IllegalArgumentException(jarFilePath + " is not a valid file or URL.");
- } finally {
- Lib.close(jis);
- }
- } else {
- manifest = new JarFile(jarFile).getManifest();
- }
- return manifest.getMainAttributes().getValue("Implementation-Version");
- }
-
- public static String getElapseString(long startTime) {
- return asTimeString(System.currentTimeMillis() - startTime);
- }
-
- private static String asTimeString(long value) {
- long leftOverMs = value % 1000;
- long seconds = value / 1000;
- long leftOverSeconds = seconds % 60;
- long minutes = seconds / 60;
- long leftOverMinutes = minutes % 60;
- long hours = minutes / 60;
- return String.format("%d:%02d:%02d.%03d", hours, leftOverMinutes, leftOverSeconds, leftOverMs);
- }
-
- /**
- * Determine is OS is windows
- *
- * @return <b>true</b> if OS is windows
- */
- public static boolean isWindows() {
- return System.getProperty("os.name").indexOf("indows") != -1;
- }
-
- public static void writeBytesToFile(byte[] data, File file) throws IOException {
- OutputStream os = new FileOutputStream(file);
- try {
- os.write(data);
- } finally {
- os.close();
- }
- }
-
- public static void extractJarEntry(File jarFile, File destination, String entry) throws IOException {
- if (!destination.getParentFile().exists()) {
- destination.getParentFile().mkdirs();
- }
- int BUFFER = 2048;
- try {
- JarFile jarfile = new JarFile(jarFile.getAbsolutePath());
- JarEntry jarEntry = jarfile.getJarEntry(entry);
- BufferedInputStream is = new BufferedInputStream(jarfile.getInputStream(jarEntry));
- int count;
- long total = 0;
- byte data[] = new byte[BUFFER];
- FileOutputStream fos = new FileOutputStream(destination);
- BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
- while ((count = is.read(data, 0, BUFFER)) != -1) {
- dest.write(data, 0, count);
- total += BUFFER;
- }
- dest.flush();
- dest.close();
- is.close();
- } catch (Exception ex) {
- String information =
- "JarFile: " + jarFile.getAbsolutePath() + "\n" + "Entry: " + (entry != null ? entry.toString() : "NULL") + "\n" + "Destination: " + (destination != null ? destination.getAbsoluteFile().toString() : "NULL") + "\n";
- throw new IOException(information + ex.getMessage());
- }
- }
-
- public static byte[] compressStream(InputStream in, String name) throws IOException {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ZipOutputStream out = null;
- try {
- out = new ZipOutputStream(bos);
- // Add ZIP entry to output stream.
- out.putNextEntry(new ZipEntry(name));
- inputStreamToOutputStream(in, out);
- } finally {
- if (out != null) {
- out.closeEntry();
- out.close();
- }
- }
- return bos.toByteArray();
- }
-
- public static byte[] compressFile(File file) throws IOException {
- ByteArrayOutputStream bos = new ByteArrayOutputStream();
- ZipOutputStream outputStream = new ZipOutputStream(bos);
- compressFile(null, file, outputStream);
- outputStream.closeEntry();
- outputStream.close();
- return bos.toByteArray();
- }
-
- public static void compressFiles(String basePath, Collection<File> files, String zipTarget) throws IOException {
- if (Strings.isValid(zipTarget) != true) {
- throw new IllegalArgumentException("Error target zip filename is invalid");
- }
- ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipTarget));
- for (File file : files) {
- if (file.isDirectory() != true) {
- Lib.compressFile(basePath, file, out);
- }
- }
- out.close();
- }
-
- private static void compressFile(String basePath, File file, ZipOutputStream outputStream) throws IOException {
- FileInputStream inputStream = null;
- try {
- inputStream = new FileInputStream(file);
- String entryName = file.getPath();
- if (Strings.isValid(basePath) && entryName.startsWith(basePath)) {
- if (basePath.endsWith(File.separator) != true) {
- basePath = basePath + File.separator;
- }
- entryName = entryName.replace(basePath, "");
- }
- ZipEntry entry = new ZipEntry(entryName);
- outputStream.putNextEntry(entry);
- inputStreamToOutputStream(inputStream, outputStream);
- } finally {
- if (inputStream != null) {
- inputStream.close();
- }
- }
- }
-
- private static void compressDirectory(String basePath, File source, ZipOutputStream outputStream, boolean includeSubDirectories) throws IOException {
- File[] children = source.listFiles();
- for (File file : children) {
- if (file.isDirectory() != true) {
- compressFile(basePath, file, outputStream);
- } else {
- if (includeSubDirectories) {
- compressDirectory(basePath, file, outputStream, includeSubDirectories);
- }
- }
- }
- }
-
- public static void compressDirectory(File directory, String zipTarget, boolean includeSubDirectories) throws IOException, IllegalArgumentException {
- if (directory.isDirectory() != true) {
- throw new IllegalArgumentException(String.format("Error source is not a directory: [%s]", directory));
- }
- if (Strings.isValid(zipTarget) != true) {
- throw new IllegalArgumentException("Error target zip filename is invalid");
- }
- ZipOutputStream outputStream = null;
- try {
- outputStream = new ZipOutputStream(new FileOutputStream(zipTarget));
- compressDirectory(directory.getPath(), directory, outputStream, includeSubDirectories);
- } finally {
- Lib.close(outputStream);
- }
- }
-
- public static String decompressStream(InputStream inputStream, OutputStream outputStream) throws IOException {
- String zipEntryName = null;
- ZipInputStream zipInputStream = null;
- try {
- zipInputStream = new ZipInputStream(inputStream);
- ZipEntry entry = zipInputStream.getNextEntry();
- zipEntryName = entry.getName();
- // Transfer bytes from the ZIP file to the output file
- inputStreamToOutputStream(zipInputStream, outputStream);
- } finally {
- if (zipInputStream != null) {
- zipInputStream.close();
- }
- }
- return zipEntryName;
- }
-
- public static void decompressStream(InputStream inputStream, File targetDirectory) throws IOException {
- ZipInputStream zipInputStream = null;
- try {
- zipInputStream = new ZipInputStream(inputStream);
- if (!targetDirectory.exists()) {
- targetDirectory.mkdirs();
- }
- ZipEntry entry = null;
- while ((entry = zipInputStream.getNextEntry()) != null) {
- String zipEntryName = entry.getName();
-
- OutputStream outputStream = null;
- try {
- File target = new File(targetDirectory, zipEntryName);
- if (target != null && !entry.isDirectory()) {
- File parent = target.getParentFile();
- if (parent != null && !parent.exists()) {
- parent.mkdirs();
- }
- outputStream = new BufferedOutputStream(new FileOutputStream(target));
- inputStreamToOutputStream(zipInputStream, outputStream);
- }
- } finally {
- if (outputStream != null) {
- outputStream.close();
- }
- }
- }
- } finally {
- if (zipInputStream != null) {
- zipInputStream.close();
- }
- }
- }
-
- public static byte[] decompressBytes(InputStream inputStream) throws IOException {
- ByteArrayOutputStream out = null;
- // Open the ZIP file
- ZipInputStream in = new ZipInputStream(inputStream);
-
- // Get the first entry
- in.getNextEntry();
-
- // Open the output file
- out = new ByteArrayOutputStream();
-
- inputStreamToOutputStream(in, out);
-
- // Close the streams
- out.close();
- in.close();
- return out.toByteArray();
- }
-
- public static void chmod777(File file) {
- if (file == null || !file.exists()) {
- return;
- }
- try {
- String command = "chmod 777 " + file.getAbsolutePath();
- Runtime r = Runtime.getRuntime();
- Process p = r.exec(command);
-
- Lib.handleProcess(p);
- } catch (IOException ioe) {
- ioe.printStackTrace();
- }
- }
-
- public static String getSortedJavaArrayInitializer(String[] strings) {
- Arrays.sort(strings);
- StringBuilder strB = new StringBuilder();
- strB.append("new String[] {\"");
- for (String element : strings) {
- strB.append(element);
- strB.append("\", \"");
- }
- strB.replace(strB.length() - 3, strB.length(), "};");
- return strB.toString();
- }
-
- /**
- * Determine whether the input stream is word xml content.
- *
- * @param inputStream
- * @return <b>true</b> is the input stream is word xml content.
- */
- public static boolean isWordML(InputStream inputStream) {
- boolean toReturn = false;
- try {
- inputStream.mark(250);
- byte[] buffer = new byte[200];
- int index = 0;
- for (; index < buffer.length; index++) {
- if (inputStream.available() > 0) {
- buffer[index] = (byte) inputStream.read();
- } else {
- break;
- }
- }
- if (index > 0) {
- String header = new String(buffer).toLowerCase();
- if (header.contains("word.document") || header.contains("worddocument") || header.contains("<w:")) {
- toReturn = true;
- }
- }
- } catch (Exception ex) {
- ex.printStackTrace();
- } finally {
- try {
- inputStream.reset();
- } catch (IOException ex) {
- // Do Nothing
- }
- }
- return toReturn;
- }
-
- public static void close(Closeable closable) {
- if (closable != null) {
- try {
- closable.close();
- } catch (IOException ex) {
- // Do Nothing
- }
- }
- }
-
- public static String getMemoryInfo() {
- MemoryUsage heapMem = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
- StringBuffer buffer = new StringBuffer();
- buffer.append("Heap Memory Usage:\n");
- buffer.append(String.format("\tUsed: [%s]\n", toMBytes(heapMem.getUsed())));
- buffer.append(String.format("\tAllocated: [%s]\n", toMBytes(heapMem.getCommitted())));
- buffer.append(String.format("\tMax: [%s]\n", toMBytes(heapMem.getMax())));
- return buffer.toString();
- }
-
- public static String toMBytes(long valInBytes) {
- NumberFormat format = NumberFormat.getInstance();
- return String.format("%s MBytes", format.format(valInBytes / 1024.0 / 1024.0));
- }
+ public final static Runtime runtime = Runtime.getRuntime();
+
+ public final static String jarPath = getJarPath(Lib.class);
+
+ public final static String basePath = getBasePath();
+
+ public final static String lineSeparator = System.getProperty("line.separator");
+
+ public static String toFirstCharUpperCase(String str) {
+ if (str == null) {
+ return null;
+ }
+ char[] chars = str.toCharArray();
+ chars[0] = Character.toUpperCase(str.charAt(0));
+ return new String(chars);
+ }
+
+ public static int numOccurances(String str, String regex) {
+ int x = 0;
+ Matcher m = Pattern.compile(regex).matcher(str);
+ while (m.find()) {
+ x++;
+ }
+ return x;
+ }
+
+ public static String exceptionToString(Throwable ex) {
+ StringBuilder sb = new StringBuilder();
+ exceptionToString(ex, sb);
+ return sb.toString();
+ }
+
+ public static boolean validateEmail(String toValidate) {
+ Pattern pattern =
+ Pattern.compile("^[a-z0-9\\._-]" + "+@([a-z0-9][a-z0-9-]*" + "[a-z0-9]\\.)+" + "([a-z]+\\.)?([a-z]+)$",
+ Pattern.CASE_INSENSITIVE);
+ Matcher matcher = pattern.matcher(toValidate);
+ return matcher.find();
+ }
+
+ private static void exceptionToString(Throwable ex, StringBuilder sb) {
+ if (ex == null) {
+ sb.append("Exception == null; can't display stack");
+ return;
+ }
+ sb.append(ex.getMessage() + "\n");
+ StackTraceElement st[] = ex.getStackTrace();
+ for (int i = 0; i < st.length; i++) {
+ StackTraceElement ste = st[i];
+ sb.append(" at " + ste.toString() + "\n");
+ }
+ Throwable cause = ex.getCause();
+ if (cause != null) {
+ sb.append(" caused by ");
+ exceptionToString(cause, sb);
+ }
+ }
+
+ public static String changeExtension(String str, String newExt) {
+ int pos = str.lastIndexOf('.');
+ if (pos == -1) { // was -1 before + 1
+ return str + "." + newExt;
+ }
+ return str.substring(0, pos + 1) + newExt;
+ }
+
+ /**
+ * this version of changeExtension will work even if the extension we want to replace contains a .
+ *
+ * @param str
+ * @param oldExt
+ * @param newExt
+ * @return String
+ */
+ public static String changeExtension(String str, String oldExt, String newExt) {
+ int pos = str.lastIndexOf(oldExt);
+ if (pos == -1) {
+ return str + "." + newExt;
+ }
+ return str.substring(0, pos) + newExt;
+ }
+
+ /**
+ * Move an object one before the previous object
+ *
+ * @param list
+ * @param obj
+ * @return true if successful
+ */
+ public static boolean moveBack(ArrayList<Object> list, Object obj) {
+ if (list.contains(obj)) {
+ int index = list.indexOf(obj);
+ if (index > 0) {
+ list.remove(index);
+ list.add(index - 1, obj);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Move an object one after the next object
+ *
+ * @param obj
+ * @return true if successful
+ */
+ public static boolean moveForward(ArrayList<Object> list, Object obj) {
+ int size = list.size();
+ if (list.contains(obj)) {
+ int index = list.indexOf(obj);
+ if (index < size - 1) {
+ list.remove(index);
+ list.add(index + 1, obj);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static void copyDirectory(File source, File destination) throws IOException {
+ File[] files = source.listFiles();
+
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isDirectory()) {
+ File dir = new File(destination, files[i].getName());
+ dir.mkdir();
+ copyDirectory(files[i], dir);
+ } else { // else is a file
+ copyFile(files[i], destination);
+ }
+ }
+ }
+
+ public static String exceptionToString(Exception ex) {
+ StringWriter stringWriter = new StringWriter();
+ PrintWriter printWriter = new PrintWriter(stringWriter);
+ ex.printStackTrace(printWriter);
+ return stringWriter.toString();
+ }
+
+ public static void copyFile(File source, File destination) throws IOException {
+ final FileChannel in = new FileInputStream(source).getChannel();
+ try {
+ final FileChannel out;
+ if (destination.isDirectory()) {
+ out = new FileOutputStream(new File(destination, source.getName())).getChannel();
+ } else {
+ if (destination.exists()) {
+ destination.delete(); // to work around some file permission
+ }
+ // problems
+ out = new FileOutputStream(destination).getChannel();
+ }
+ try {
+ long position = 0;
+ long size = in.size();
+ while (position < size) {
+ position += in.transferTo(position, size, out);
+ }
+ } finally {
+ out.close();
+ }
+ } finally {
+ in.close();
+ }
+ }
+
+ public static void copyFiles(File source, File destination) throws IOException {
+ copyFiles(source, null, destination);
+ }
+
+ public static void copyFiles(File source, FilenameFilter filter, File destination) throws IOException {
+ File[] files = source.listFiles(filter);
+ if (!source.exists()) {
+ throw new IllegalArgumentException("the directory " + source + " does not exist.");
+ }
+
+ if (files != null) {
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isFile()) {
+ copyFile(files[i], destination);
+ }
+ }
+ }
+ }
+
+ public static Image createImage(String path) {
+ return createImageIcon(path).getImage();
+ }
+
+ public static ImageIcon createImageIcon(Class<?> clasaRef, String path) {
+ URL imgURL = clasaRef.getResource(path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL);
+ } else {
+ System.err.println("Couldn't find the resource: " + path);
+ return null;
+ }
+ }
+
+ /** Returns an ImageIcon, or null if the path was invalid. */
+ public static ImageIcon createImageIcon(String path) {
+ return createImageIcon(Lib.class, path);
+ }
+
+ public static void deleteDir(File directory) {
+ File[] files = directory.listFiles();
+ if (files == null) {
+ return;
+ }
+
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isDirectory()) {
+ deleteDir(files[i]);
+ } else { // else is a file
+ files[i].delete();
+ }
+ }
+ directory.delete();
+ }
+
+ public static void deleteContents(File directory) {
+ deleteContents(directory, null);
+ }
+
+ public static void deleteContents(File directory, FilenameFilter filter) {
+ File[] files = directory.listFiles(filter);
+
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isDirectory()) {
+ deleteContents(files[i]);
+ }
+ files[i].delete();
+ }
+ }
+
+ /**
+ * Delete the current file and all empty parents. The method will stop deleting empty parents once it reaches the
+ * stopAt parent.
+ *
+ * @param stopAt path of the parent file to stop deleting at
+ * @param file to delete
+ * @return status <b>true</b> if successful
+ */
+ public static boolean deleteFileAndEmptyParents(String stopAt, File file) {
+ boolean result = true;
+ if (file != null) {
+ if (file.isDirectory() != false) {
+ if (file.list().length == 0) {
+ result &= file.delete();
+ }
+ } else {
+ result &= file.delete();
+ }
+ }
+ File parent = file.getParentFile();
+ if (parent != null && parent.getAbsolutePath().equals(stopAt) != true) {
+ result &= deleteFileAndEmptyParents(stopAt, parent);
+ }
+ return result;
+ }
+
+ /**
+ * Deletes all files from directory
+ *
+ * @param directory
+ */
+ public static void emptyDirectory(File directory) {
+ File[] children = directory.listFiles();
+ if (children != null) {
+ for (File child : children) {
+ if (child.isDirectory()) {
+ emptyDirectory(child);
+ } else { // else is a file
+ child.delete();
+ }
+ }
+ }
+ }
+
+ public static void inputStreamToOutputStream(InputStream inputStream, OutputStream outputStream) throws IOException {
+ if (inputStream == null) {
+ throw new IllegalArgumentException("inputStream was null");
+ }
+ if (outputStream == null) {
+ throw new IllegalArgumentException("outputStream was null");
+ }
+
+ byte[] buf = new byte[10000];
+ int count = -1;
+ while ((count = inputStream.read(buf)) != -1) {
+ outputStream.write(buf, 0, count);
+ }
+ }
+
+ public static int getMatcherCount(Pattern p, String str) {
+ return getMatcherCount(p.matcher(str));
+ }
+
+ public static int getMatcherCount(Matcher m) {
+ int count = 0;
+ while (m.find()) {
+ count++;
+ }
+ return count;
+ }
+
+ public static String inputStreamToString(InputStream in) throws IOException {
+ return inputStreamToChangeSet(in).toString();
+ }
+
+ public static ChangeSet inputStreamToChangeSet(InputStream in) throws IOException {
+ InputStreamReader reader = new InputStreamReader(in, "UTF-8");
+ ChangeSet set = new ChangeSet();
+
+ char[] chars = new char[8000];
+ int readCount = 0;
+ while ((readCount = reader.read(chars)) != -1) {
+ set.insertBefore(0, chars, 0, readCount, true);
+ }
+ return set;
+ }
+
+ public static byte[] inputStreamToBytes(InputStream inputStream) throws IOException {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ try {
+ inputStreamToOutputStream(inputStream, outputStream);
+ } finally {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ }
+ return outputStream.toByteArray();
+ }
+
+ public static void inputStreamToFile(InputStream inputStream, File outFile) throws IOException {
+ byte[] bytes = new byte[2024];
+ FileOutputStream out = new FileOutputStream(outFile);
+
+ int numBytesRead;
+ while ((numBytesRead = inputStream.read(bytes)) != -1) {
+ out.write(bytes, 0, numBytesRead);
+ }
+ out.close();
+ }
+
+ public static CharBuffer inputStreamToCharBuffer(InputStream in) throws IOException {
+ return CharBuffer.wrap(inputStreamToChangeSet(in).toCharArray());
+ }
+
+ public static java.io.InputStream stringToInputStream(String value) throws Exception {
+ if (value == null) {
+ return null;
+ }
+ value = value.trim();
+ java.io.InputStream in = new java.io.ByteArrayInputStream(value.getBytes("UTF-8"));
+ return in;
+ }
+
+ public static InputStream byteBufferToInputStream(final ByteBuffer byteBuffer) {
+
+ return new InputStream() {
+ @Override
+ public synchronized int read() throws IOException {
+ if (!byteBuffer.hasRemaining()) {
+ return -1;
+ }
+ return byteBuffer.get();
+ }
+
+ @Override
+ public synchronized int read(byte[] bytes, int off, int len) throws IOException {
+ len = Math.min(len, byteBuffer.remaining());
+ if (off != len) {
+ byteBuffer.get(bytes, off, len);
+ } else {
+ len = -1;
+ }
+ return len;
+ }
+
+ @Override
+ public synchronized void reset() throws IOException {
+ byteBuffer.rewind();
+ }
+
+ };
+ }
+
+ public static OutputStream byteBufferToOutputStream(final ByteBuffer byteBuffer) {
+ return new OutputStream() {
+ @Override
+ public synchronized void write(int b) throws IOException {
+ byteBuffer.put((byte) b);
+ }
+
+ @Override
+ public synchronized void write(byte[] bytes, int off, int len) throws IOException {
+ byteBuffer.put(bytes, off, len);
+ }
+ };
+ }
+
+ public static final Pattern numberListPattern = Pattern.compile("\\d+");
+
+ public static List<Integer> stringToIntegerList(String numberList) {
+ ArrayList<Integer> ints = new ArrayList<Integer>();
+ Matcher transactionIdMatcher = numberListPattern.matcher(numberList);
+ while (transactionIdMatcher.find()) {
+ ints.add(Integer.parseInt(transactionIdMatcher.group()));
+ }
+ return ints;
+ }
+
+ public static String fileToString(File file) throws IOException {
+ StringBuffer buffer = new StringBuffer();
+ Reader inStream = new InputStreamReader(new FileInputStream(file), "UTF-8");
+ Reader in = new BufferedReader(inStream);
+ int ch;
+ while ((ch = in.read()) > -1) {
+ buffer.append((char) ch);
+ }
+ in.close();
+ return buffer.toString();
+ }
+
+ public static byte[] fileToBytes(File file) throws IOException {
+ InputStream inputStream = new FileInputStream(file);
+ try {
+ byte[] bytes = new byte[(int) file.length()];
+ inputStream.read(bytes);
+ return bytes;
+ } finally {
+ inputStream.close();
+ }
+ }
+
+ /**
+ * usage: char[] buf = new char[5500000]; for (Iterator iter = files.iterator(); iter.hasNext(); ) { // for each file
+ * File file = (File)iter.next(); buf = Lib.fileToChars(file, buf);
+ *
+ * @param file
+ * @param buf
+ * @return char[]
+ * @throws IOException
+ */
+ public static char[] fileToChars(File file, char[] buf) throws IOException {
+ FileReader in = new FileReader(file);
+ int size = (int) file.length();
+
+ if (buf == null) {
+ buf = new char[size];
+ } else if (size > buf.length) {
+ buf = null;
+ System.gc(); // since the currently allocated buf might already be quite large
+ buf = new char[size];
+ }
+
+ in.read(buf);
+ in.close();
+ return buf;
+ }
+
+ public static CharBuffer fileToCharBuffer(File file) throws IOException {
+ return fileToCharBuffer(file, "UTF8");
+ }
+
+ public static CharBuffer fileToCharBuffer(File file, String charset) throws IOException {
+ InputStreamReader in = new InputStreamReader(new FileInputStream(file), charset);
+ char[] chars = new char[(int) file.length()];
+ in.read(chars);
+ in.close();
+ return CharBuffer.wrap(chars);
+ }
+
+ public static String fillString(char c, int n) {
+ char[] chars = new char[n];
+ for (int i = 0; i < n; chars[i++] = c) {
+ // must leave empty block here so the following line won't become
+ // part of the loop
+ }
+ return new String(chars);
+ }
+
+ /**
+ * Get file extension from the file path
+ *
+ * @param filepath
+ * @return file extension
+ */
+ public static String getExtension(String filepath) {
+ filepath = filepath.trim();
+ String separatorRegEx = File.separator;
+ if (Lib.isWindows()) {
+ separatorRegEx = "\\\\";
+ }
+ String[] pathsArray = filepath.split(separatorRegEx);
+
+ String fileName = pathsArray[0];
+ if (pathsArray.length > 0) {
+ fileName = pathsArray[pathsArray.length - 1];
+ }
+
+ int index = fileName.lastIndexOf('.');
+ if (index >= 0 && index + 1 < fileName.length()) {
+ return fileName.substring(index + 1);
+ } else {
+ return "";
+ }
+ }
+
+ public static int handleProcess(Process proc) {
+ return handleProcess(proc, new PrintWriter(System.out, true));
+ }
+
+ public static int handleProcess(Process proc, Writer output, String errName, String outName) {
+ return handleProcess(proc, output, errName, outName, true);
+ }
+
+ public static int handleProcess(Process proc, Writer output, String errName, String outName, boolean verbose) {
+ try {
+ IOOutputThread errThread =
+ new IOOutputThread(output, new BufferedReader(new InputStreamReader(proc.getErrorStream())), verbose);
+ IOOutputThread outThread =
+ new IOOutputThread(output, new BufferedReader(new InputStreamReader(proc.getInputStream())), verbose);
+
+ errThread.setName(errName);
+ outThread.setName(outName);
+ errThread.start();
+ outThread.start();
+ proc.waitFor();
+ int exitCode = proc.exitValue();
+ if (exitCode != 0) {
+ output.write("Process exit code is: " + exitCode + "\n");
+ }
+ int count = 0;
+ while (errThread.isAlive() || outThread.isAlive()) {
+ if (count > 10) {
+ break;
+ }
+ synchronized (Thread.currentThread()) {
+ Thread.currentThread().wait(500);
+ }
+ count++;
+ }
+ output.flush();
+ return exitCode;
+ } catch (IOException ex) {
+ System.err.println(ex);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ return Integer.MIN_VALUE;
+ }
+
+ public static int handleProcess(Process proc, Writer output) {
+ return handleProcess(proc, output, "err", "out");
+ }
+
+ public static int handleProcess(Process proc, Writer output, boolean verbose) {
+ return handleProcess(proc, output, "err", "out", verbose);
+ }
+
+ /**
+ * Sets up an error, input, and output stream for the given process. The error stream gives all information coming
+ * FROM the process through it's err stream. The "outThread" will be what come from the FROM the process through it's
+ * normal output stream. The "inThread" is the stream for issuing commands TO the process.
+ *
+ * @param proc The process whose streams we are setting up
+ * @param output Where all info coming FROM the minicom is sent
+ * @param input Where all data going TO the minicom is sent
+ * @return An array of threads in the following order:<br> --index 0 = Err Stream<br> --index 1 = output stream<br>
+ * --index 2 = input stream<br>
+ */
+ public static Thread[] handleMinicomProcess(Process proc, Writer output, Reader input) {
+ IOOutputThread errThread =
+ new IOOutputThread(output, new BufferedReader(new InputStreamReader(proc.getErrorStream())));
+
+ InputBufferThread outThread = new InputBufferThread(proc.getInputStream());
+
+ errThread.setName("err");
+ outThread.setName("out");
+ errThread.start();
+ outThread.start();
+
+ if (input != null) {
+ IOInputThread inThread =
+ new IOInputThread(input, new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())));
+ inThread.setName("in");
+ inThread.start();
+ return new Thread[] {errThread, outThread, inThread};
+ }
+ return new Thread[] {errThread, outThread};
+ }
+
+ public static Thread[] handleProcessNoWait(Process proc, Writer output) {
+ return handleProcessNoWait(proc, output, output, null);
+ }
+
+ public static Thread[] handleProcessNoWait(Process proc, Writer output, boolean verbose) {
+ return handleProcessNoWait(proc, output, output, null, "err", "out", verbose);
+ }
+
+ public static Thread[] handleProcessNoWait(Process proc, Writer output, Writer errorWriter, Reader reader) {
+ return handleProcessNoWait(proc, output, errorWriter, reader, "err", "out", true);
+ }
+
+ public static Thread[] handleProcessNoWait(Process proc, Writer outputWriter, Writer errorWriter, Reader reader, String errName, String outName) {
+ return handleProcessNoWait(proc, outputWriter, errorWriter, reader, errName, outName, true);
+ }
+
+ public static Thread[] handleProcessNoWait(Process proc, Writer outputWriter, Writer errorWriter, Reader reader, String errName, String outName, boolean verbose) {
+ IOOutputThread errThread =
+ new IOOutputThread(errorWriter, new BufferedReader(new InputStreamReader(proc.getErrorStream())),
+ verbose);
+ IOOutputThread outThread =
+ new IOOutputThread(outputWriter, new BufferedReader(new InputStreamReader(proc.getInputStream())),
+ verbose);
+ errThread.setName(errName);
+ outThread.setName(outName);
+ errThread.start();
+ outThread.start();
+ if (reader != null) {
+ IOInputThread inThread =
+ new IOInputThread(reader, new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())));
+ inThread.setName("in");
+ inThread.start();
+ return new Thread[] {errThread, outThread, inThread};
+ }
+ return new Thread[] {errThread, outThread};
+ }
+
+ public static void makeDirClean(File directory) {
+ if (directory.exists()) {
+ Lib.deleteContents(directory);
+ } else {
+ directory.mkdir();
+ }
+ }
+
+ public static void moveFiles(File source, File destination) {
+ moveFiles(source, null, destination);
+ }
+
+ public static void moveFiles(File source, FilenameFilter filter, File destination) {
+ File[] files = source.listFiles(filter);
+
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isFile()) {
+ files[i].renameTo(new File(destination, files[i].getName()));
+ }
+ }
+ }
+
+ public static String getSpace(int length) {
+ return getCharacter(' ', length);
+ }
+
+ public static String getCharacter(char c, int length) {
+ StringBuilder out = new StringBuilder();
+ for (int i = 0; i < length; i++) {
+ out.append(c);
+ }
+ return out.toString();
+ }
+
+ public static String padLeading(String str, char c, int n) {
+ char[] chars = new char[n];
+ int pos = Math.min(n, str.length());
+ str.getChars(0, pos, chars, n - pos);
+ for (int i = 0; i < n - pos; chars[i++] = c) {
+ // must leave empty block here so the following line won't become
+ // part of the loop
+ }
+ return new String(chars);
+ }
+
+ public static String padTrailing(String str, char c, int n) {
+ char[] chars = new char[n];
+ int pos = Math.min(n, str.length());
+ str.getChars(0, pos, chars, 0);
+ for (int i = pos; i < n; chars[i++] = c) {
+ // must leave empty block here so the following line won't become
+ // part of the loop
+ }
+ return new String(chars);
+ }
+
+ public static int printAndExec(String[] callAndArgs) {
+ return printAndExec(callAndArgs, null, new BufferedWriter(new PrintWriter(System.out, true)));
+ }
+
+ public static int printAndExec(String[] callAndArgs, File dir) {
+ return printAndExec(callAndArgs, dir, new PrintWriter(System.out, true));
+ }
+
+ public static int printAndExec(String[] callAndArgs, File dir, Writer output) {
+ try {
+ for (int j = 0; j < callAndArgs.length; j++) {
+ output.write(callAndArgs[j] + " ");
+ }
+ output.write("\n");
+ output.flush();
+
+ return Lib.handleProcess(runtime.exec(callAndArgs, null, dir), output);
+ } catch (IOException ex) {
+ System.err.println("error: " + ex);
+ return -1;
+ }
+ }
+
+ public static ArrayList<String> readListFromDir(File directory, FilenameFilter filter, boolean keepExtension) {
+ ArrayList<String> list = new ArrayList<String>(400);
+
+ if (directory == null) {
+ System.out.println("Invalid path: " + directory);
+ return list;
+ }
+
+ File[] files = directory.listFiles(filter);
+ if (files == null) {
+ System.out.println("Invalid path: " + directory);
+ return list;
+ }
+ if (files.length > 0) {
+ Arrays.sort(files);
+ }
+
+ if (keepExtension) {
+ for (int i = 0; i < files.length; i++) {
+ list.add(files[i].getName());
+ }
+ } else {
+ for (int i = 0; i < files.length; i++) {
+ list.add(Lib.removeExtension(files[i].getName()));
+ }
+ }
+
+ return list;
+ }
+
+ public static ArrayList<String> readListFromDir(String directory, FilenameFilter filter) {
+ return readListFromDir(new File(directory), filter, false);
+ }
+
+ public static ArrayList<String> readListFromFile(File file, boolean keepExtension) throws IOException {
+ BufferedReader in = new BufferedReader(new FileReader(file));
+ ArrayList<String> list = new ArrayList<String>(120);
+
+ String line = null;
+
+ if (keepExtension) {
+ while ((line = in.readLine()) != null) {
+ list.add(line);
+ }
+ } else {
+ while ((line = in.readLine()) != null) {
+ list.add(Lib.removeExtension(line));
+ }
+ }
+ in.close();
+ return list;
+ }
+
+ public static ArrayList<String> readListFromFile(String file) throws IOException {
+ return readListFromFile(new File(file), true);
+ }
+
+ public static boolean isLink(File file) {
+ if (!file.exists()) {
+ return true;
+ }
+ try {
+ return !file.getAbsolutePath().equals(file.getCanonicalPath());
+ } catch (IOException ex) {
+ return true;
+ }
+ }
+
+ public static List<File> recursivelyListFilesAndDirectories(ArrayList<File> fileList, File rootPath, Pattern filePathP, boolean includeDirectories) {
+ LinkedList<File> dirList = new LinkedList<File>();
+ dirList.add(rootPath);
+
+ Matcher fileNameM = null;
+ if (filePathP != null) {
+ fileNameM = filePathP.matcher("");
+ }
+
+ while (!dirList.isEmpty()) {
+ File parent = dirList.removeFirst();
+ if (parent == null) {
+ System.out.println("Invalid path.");
+ continue;
+ }
+
+ if (parent.getName().startsWith(".Rational")) {
+ continue;
+ }
+
+ File[] files = parent.listFiles();
+ if (files == null) {
+ System.out.println("Invalid path: " + parent);
+ continue;
+ }
+
+ for (int i = 0; i < files.length; i++) {
+ if (files[i].isDirectory()) {
+ dirList.add(files[i]);
+ if (includeDirectories) {
+ fileList.add(files[i]);
+ }
+ } else { // else is a file
+ if (fileNameM == null) {
+ fileList.add(files[i]);
+ } else {
+ fileNameM.reset(files[i].getPath());
+ if (fileNameM.matches()) {
+ fileList.add(files[i]);
+ }
+ }
+ }
+ }
+ }
+ return fileList;
+ }
+
+ /**
+ * Returns an array list of File objects
+ *
+ * @param fileList
+ * @param rootPath
+ * @param fileNameP
+ * @return List
+ */
+ public static List<File> recursivelyListFiles(ArrayList<File> fileList, File rootPath, Pattern filePathP) {
+ return recursivelyListFilesAndDirectories(fileList, rootPath, filePathP, false);
+ }
+
+ public static List<File> recursivelyListFiles(File rootPath, Pattern fileNameP) {
+ return recursivelyListFiles(new ArrayList<File>(400), rootPath, fileNameP);
+ }
+
+ /**
+ * Assumptions: block comments are not nested and comment blocks have an ending Note: may be fooled by string
+ * literals that contains the block comment indicators
+ *
+ * @param charBuf
+ * @return CharBuffer
+ */
+ public static CharBuffer stripBlockComments(CharBuffer charBuf) {
+ char[] chars = charBuf.array();
+ int i = 0;
+ int k = 0;
+
+ try {
+ while (i < chars.length) {
+ if (chars[i] == '/' && chars[i + 1] == '*') {
+ i += 2;
+ while (!(chars[i++] == '*' && chars[i] == '/')) {
+ // must leave empty block here so the following line
+ // won't become part of the loop
+ }
+ i++;
+ } else {
+ chars[k++] = chars[i++];
+ }
+ }
+ charBuf.limit(k);
+ return charBuf;
+ } catch (ArrayIndexOutOfBoundsException ex) {
+ throw new IllegalArgumentException("Incorrectly formatted comments.");
+ }
+ }
+
+ /**
+ * Remove the file extension from the file path
+ *
+ * @param filepath
+ * @return modified file path
+ */
+ public static String removeExtension(String filepath) {
+ String ext = getExtension(filepath);
+ if (ext != null && ext.length() > 0) {
+ filepath = filepath.substring(0, filepath.length() - (ext.length() + 1));
+ }
+ return filepath;
+ }
+
+ public static String removeExtension(File file) {
+ return removeExtension(file.getName());
+ }
+
+ /**
+ * Remove the file extension from the file path
+ *
+ * @param string
+ * @return string with no leading or trailing
+ */
+ public static String removeLeadingAndTrailingSpaces(String str) {
+ String ext = str.replaceFirst("^ *", "");
+ return ext.replaceFirst(" *$", "");
+ }
+
+ /**
+ * Determine if file is a compressed file
+ *
+ * @param file to check
+ * @return <b>true</b> if the files is a compressed file
+ */
+ public static boolean isCompressed(File file) {
+ boolean toReturn = false;
+ String ext = getExtension(file.getAbsolutePath());
+ if (ext.equals("zip")) {
+ toReturn = true;
+ }
+ return toReturn;
+ }
+
+ // replaces the first capturing group of the match in fileToModify with
+ // replaceSeq and write this back to fileToModify
+ public static boolean updateFile(File fileToModify, Pattern pattern, CharSequence replaceSeq) throws IOException {
+ CharBuffer modifyBuf = Lib.fileToCharBuffer(fileToModify);
+
+ Matcher matcher = pattern.matcher(modifyBuf);
+ if (!matcher.find()) {
+ System.out.println(fileToModify.getPath() + " does not contain the pattern: " + pattern.pattern());
+ return false;
+ }
+ CharBuffer topSection = (CharBuffer) modifyBuf.subSequence(0, matcher.start(1)); // everything
+ // before the
+ // pattern
+ CharBuffer bottomSection = null;
+ int bottomLen = 0;
+ if (matcher.end(1) != modifyBuf.length()) {
+ bottomSection = (CharBuffer) modifyBuf.subSequence(matcher.end(1), modifyBuf.length());
+ bottomLen = bottomSection.length();
+ }
+
+ CharBuffer outBuf = CharBuffer.allocate(topSection.length() + replaceSeq.length() + bottomLen);
+ outBuf.put(topSection);
+ if (replaceSeq instanceof String) {
+ outBuf.put((String) replaceSeq);
+ } else if (replaceSeq instanceof CharBuffer) {
+ outBuf.put((CharBuffer) replaceSeq);
+ } else {
+ outBuf.put(replaceSeq.toString());
+ }
+ if (bottomSection != null) {
+ outBuf.put(bottomSection);
+ }
+ Lib.writeCharBufferToFile(outBuf, fileToModify);
+
+ return true;
+ }
+
+ public static boolean updateFile(File fileToModify, Pattern pattern, File original) throws IOException {
+ return updateFile(fileToModify, pattern, fileToCharBuffer(original));
+ }
+
+ public static void writeCharBufferToFile(CharBuffer charBuf, File outFile) throws IOException {
+ writeCharsToFile(charBuf.array(), outFile);
+ }
+
+ public static void writeCharsToFile(char[] chars, File outFile) throws IOException {
+ FileWriter out = new FileWriter(outFile);
+ out.write(chars, 0, chars.length);
+ out.close();
+ }
+
+ public static void writeStringToFile(String str, File outFile) throws IOException {
+ OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(outFile), "UTF-8");
+ char[] chars = str.toCharArray();
+ out.write(chars, 0, chars.length);
+ out.close();
+ }
+
+ public static String getBasePath() {
+ return Lib.getBasePath(Lib.class);
+ }
+
+ public static String getDateTimeString() {
+ return new SimpleDateFormat("yyyy-MM-dd_hh-mm").format(new Date());
+ }
+
+ public static String getJarPath(Class<Lib> base) {
+ // the leading '/' tells getResource not to append the package name
+ // (instead the leading / is just stripped off)
+ String className = "/" + base.getName().replace('.', '/') + ".class";
+ String path = base.getResource(className).getPath();
+
+ int pos = path.lastIndexOf("!");
+ if (pos == -1) { // class is not in a jar file
+ return null;
+ } else { // class is in a jar file
+ String jarpath = path.substring("file:".length(), pos);
+ return jarpath.replaceAll("%20", " ");
+ }
+ }
+
+ /**
+ * @param base
+ * @return The path which was used to load the class file. If the file was loaded from a .jar, then the full path to
+ * the jar. If the file was loaded from a .class, then the path up to the root of the package.
+ */
+ public static String getClassLoadPath(Class<?> base) {
+ /*
+ * Using the getProtectionDomain() method seems to be yield more consistent results than
+ * getResource(className).getPath(); particularly when being run with the Eclipse class loader. It was found that
+ * the Eclipse class loader did not always return the full path when asked for the resource.
+ */
+
+ ProtectionDomain pd = base.getProtectionDomain();
+ CodeSource cs = pd.getCodeSource();
+ URL csLoc = cs.getLocation();
+ String path = csLoc.getPath();
+ path = path.replaceAll("%20", " ");
+ return path;
+ }
+
+ public static String getBasePath(Class<?> base) {
+ String path = getClassLoadPath(base);
+ path = path.replaceAll("%20", " ");
+
+ if (path.endsWith(".jar")) {
+ int end = path.lastIndexOf('/');
+ path = path.substring(0, end);
+ }
+ return path;
+
+ }
+
+ public static URL resolveToUrl(String path) {
+ URL url = null;
+ System.out.println("resolveToUrl: " + path);
+ if (path != null && !path.equals("")) {
+ if (path.indexOf("://") == -1) { // if not a full URL yet
+ if (!path.startsWith("/")) { // if not absolute then prepend
+ // base path
+ try {
+ path = new File(Lib.basePath + "/" + path).getCanonicalPath();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+ path = "file://" + path;
+ }
+ try {
+ url = new URL(path);
+ } catch (MalformedURLException ex) {
+ ex.printStackTrace();
+ }
+ }
+ return url;
+ }
+
+ public static String escapeForRegex(String text) {
+ char[] chars = text.toCharArray();
+ StringBuffer strB = new StringBuffer(chars.length + 5);
+
+ for (int i = 0; i < chars.length; i++) {
+ switch (chars[i]) {
+ case '\\':
+ case '[':
+ case ']':
+ case '.':
+ case '{':
+ case '}':
+ case '^':
+ case '$':
+ case '?':
+ case '*':
+ case '+':
+ case '|':
+ strB.append('\\');
+ }
+ strB.append(chars[i]);
+ }
+ return strB.toString();
+ }
+
+ public static String determineGroup() {
+ try {
+ Process proc =
+ Runtime.getRuntime().exec(
+ new String[] {"/usr/bin/bash", "-c", "touch whichGroup; ls -g whichGroup; rm whichGroup"},
+ null,
+ new File("/tmp"));
+ BufferedReader inOutput = new BufferedReader(new InputStreamReader(proc.getInputStream()));
+ String line = inOutput.readLine();
+ return line.substring(15, line.indexOf(' ', 16)); // 15 based on
+ // format of
+ // line printed
+ // by ls
+ } catch (IOException ex) {
+ System.out.println(ex);
+ return "no group";
+ }
+ }
+
+ /**
+ * Returns a list of the arguments in the source String passed. It assumes that the first character is a '(' and
+ * matches till it finds the matching ')'.
+ *
+ * @param source
+ * @return String[]
+ */
+ public static String[] getArguments(String source) {
+ ArrayList<String> theResults = new ArrayList<String>();
+ try {
+ if (source.charAt(0) != '(') {
+ System.err.println("In getArguments, first char must be \'(\'.");
+ return null;
+ }
+
+ int currentArg = 1;
+ int startPos = 1;
+ int parens = 0;
+ boolean foundValidChar = false;
+
+ for (int i = 1; i < source.length(); i++) {
+ char theChar = source.charAt(i);
+
+ if (theChar == '(') {
+ parens++;
+ } else if (theChar == ')') {
+ parens--;
+ if (parens < 0) {
+ theResults.add(source.substring(startPos, i));
+ break;
+ }
+ } else if (theChar == ',' && parens == 0) {
+ theResults.add(source.substring(startPos, i));
+ startPos = i + 1;
+ currentArg++;
+ foundValidChar = false;
+ } else if (!foundValidChar) {
+ if (Character.isWhitespace(theChar)) {
+ startPos++;
+ } else {
+ foundValidChar = true;
+ }
+ }
+ }
+
+ String[] theTrueResults = new String[theResults.size()];
+ theResults.toArray(theTrueResults);
+
+ if (theTrueResults.length != currentArg) {
+ System.err.println("In getArguments, number of argument mismatch.");
+ }
+
+ return theTrueResults;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ public static int getArgsLength(String source) {
+ try {
+ if (source.charAt(0) != '(') {
+ System.err.println("In getArguments, first char must be \'(\'.");
+ return -1;
+ }
+ int parens = 0;
+
+ for (int i = 1; i < source.length(); i++) {
+ char theChar = source.charAt(i);
+
+ if (theChar == '(') {
+ parens++;
+ } else if (theChar == ')') {
+ parens--;
+ if (parens < 0) {
+ return i - 1;
+ }
+ }
+ }
+
+ System.err.println("In getArguments, problem occurred.");
+ return -1;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return -1;
+ }
+ }
+
+ /**
+ * Returns a list of Strings representing each comma separated string in the string passed. It ignores commas inside
+ * () or {}.
+ *
+ * @param source
+ * @return String[]
+ */
+ public static String[] getCommaSeparatedItems(String source) {
+ ArrayList<String> theResults = new ArrayList<String>();
+ int startPos = 0;
+ int parensCount = 0;
+
+ for (int i = 0; i < source.length(); i++) {
+ char theChar = source.charAt(i);
+
+ if (theChar == '(' || theChar == '{') {
+ parensCount++;
+ } else if (theChar == ')' || theChar == '}') {
+ parensCount--;
+ } else if (parensCount == 0 && theChar == ',') {
+ theResults.add(source.substring(startPos, i).trim());
+ startPos = i + 1;
+ }
+ }
+ theResults.add(source.substring(startPos).trim());
+ String[] results = new String[theResults.size()];
+ theResults.toArray(results);
+ return results;
+ }
+
+ /**
+ * Finds the index of the closing bracket for a function.
+ *
+ * @param start -the index of the character AFTER the opening bracket for the function
+ * @param seq -sequence containing the local function
+ * @return -the index of the matching bracket to the opening bracket of this function
+ */
+ public static int findTheEnd(int start, CharSequence seq) {
+ int stack = 1;
+ char[] array = seq.subSequence(start, seq.length()).toString().toCharArray();
+ int i;
+ // print( "checking: " + seq.subSequence(start,
+ // seq.length()).toString());
+ for (i = 0; i < array.length; i++) {
+ // System.out.print( array[i]);
+ if (array[i] == '/' && array[i + 1] == '*') {
+
+ while (array[i] != '*' || array[i + 1] != '/') {
+ i++;
+ }
+ }
+ if (array[i] == '"') {
+ i++;
+ while (array[i] != '"' || array[i - 1] == '\\') {
+ i++;
+ }
+ }
+ if (array[i] == '{') {
+ stack++;
+
+ } else if (array[i] == '}') {
+ stack--;
+
+ }
+ if (stack == 0) {
+ return start + i - 1;
+ }
+ }
+ return start + i - 1;
+
+ }
+
+ public static final URL getUrlFromString(String path) throws MalformedURLException {
+ if (!path.matches("(file:/|file://|http://|C:).*")) {
+ return new URL("file://" + path);
+ }
+ return new URL(path);
+ }
+
+ public static final URL[] getUrlFromString(String[] path) throws MalformedURLException {
+ URL[] urls = new URL[path.length];
+ for (int i = 0; i < urls.length; i++) {
+ urls[i] = getUrlFromString(path[i]);
+ }
+ return urls;
+ }
+
+ public static final String convertToJavaClassName(String name) {
+ ChangeSet changeSet = new ChangeSet(name);
+ Matcher matcher = Pattern.compile("_([a-zA-Z])").matcher(changeSet.toString());
+
+ changeSet.replace(0, 1, Character.toUpperCase(name.charAt(0)));
+ while (matcher.find()) {
+ changeSet.replace(matcher.start(), matcher.end(), Character.toUpperCase(matcher.group(1).charAt(0)));
+ }
+
+ return changeSet.applyChangesToSelf().toString();
+ }
+
+ /**
+ * This method takes in any name separated by underscores and converts it into a java standard variable name.
+ *
+ * @param name
+ * @return java variable name
+ */
+ public static final String convertToJavaVariableName(String name) {
+ name = name.toLowerCase();
+ StringBuffer sb = new StringBuffer();
+ char[] chars = name.toCharArray();
+ for (int i = 0; i < chars.length; i++) {
+ if (chars[i] == '_') {
+ if (chars.length > i + 1 && chars[i + 1] != '_') {
+ sb.append(Character.toUpperCase(chars[i + 1]));
+ i++;
+ }
+ } else {
+ sb.append(chars[i]);
+ }
+ }
+ return sb.toString();
+ }
+
+ public static URL getJarFileURL(File directory, String title, String version) throws IOException {
+ if (!directory.isDirectory()) {
+ throw new IllegalArgumentException(directory.getPath() + " is not a valid directory.");
+ }
+ File[] jars = directory.listFiles(new MatchFilter(".*\\.jar"));
+ for (int i = 0; i < jars.length; i++) {
+ JarFile jar = new JarFile(jars[i]);
+ Attributes attributes = jar.getManifest().getMainAttributes();
+ String jarTitle = attributes.getValue("Implementation-Title");
+ String jarVersion = attributes.getValue("Implementation-Version");
+ if (jarTitle != null && jarVersion != null && jarTitle.equals(title) && jarVersion.equals(version)) {
+ return jars[i].toURI().toURL();
+ }
+ }
+ throw new IllegalArgumentException("The specified version: " + version + " for " + title + " was not found.");
+ }
+
+ public static URL[] getClasspath() throws MalformedURLException {
+ String[] strPaths = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
+ URL[] urlPaths = new URL[strPaths.length];
+ for (int i = 0; i < strPaths.length; i++) {
+ urlPaths[i] = new File(strPaths[i]).toURI().toURL();
+ }
+ return urlPaths;
+ }
+
+ public static String getJarFileVersion(String jarFilePath) throws IOException {
+ Manifest manifest;
+ File jarFile = new File(jarFilePath);
+ if (!jarFile.isFile()) {// maybe it's an http connection
+ JarInputStream jis = null;
+ try {
+ URL u = new URL(jarFilePath);
+ URLConnection uc = u.openConnection();
+ jis = new JarInputStream(uc.getInputStream());
+ manifest = jis.getManifest();
+ } catch (IOException ex) {
+ throw new IllegalArgumentException(jarFilePath + " is not a valid file or URL.");
+ } finally {
+ Lib.close(jis);
+ }
+ } else {
+ manifest = new JarFile(jarFile).getManifest();
+ }
+ return manifest.getMainAttributes().getValue("Implementation-Version");
+ }
+
+ public static String getElapseString(long startTime) {
+ return asTimeString(System.currentTimeMillis() - startTime);
+ }
+
+ private static String asTimeString(long value) {
+ long leftOverMs = value % 1000;
+ long seconds = value / 1000;
+ long leftOverSeconds = seconds % 60;
+ long minutes = seconds / 60;
+ long leftOverMinutes = minutes % 60;
+ long hours = minutes / 60;
+ return String.format("%d:%02d:%02d.%03d", hours, leftOverMinutes, leftOverSeconds, leftOverMs);
+ }
+
+ /**
+ * Determine is OS is windows
+ *
+ * @return <b>true</b> if OS is windows
+ */
+ public static boolean isWindows() {
+ return System.getProperty("os.name").indexOf("indows") != -1;
+ }
+
+ public static void writeBytesToFile(byte[] data, File file) throws IOException {
+ OutputStream os = new FileOutputStream(file);
+ try {
+ os.write(data);
+ } finally {
+ os.close();
+ }
+ }
+
+ public static void extractJarEntry(File jarFile, File destination, String entry) throws IOException {
+ if (!destination.getParentFile().exists()) {
+ destination.getParentFile().mkdirs();
+ }
+ int BUFFER = 2048;
+ try {
+ JarFile jarfile = new JarFile(jarFile.getAbsolutePath());
+ JarEntry jarEntry = jarfile.getJarEntry(entry);
+ BufferedInputStream is = new BufferedInputStream(jarfile.getInputStream(jarEntry));
+ int count;
+ long total = 0;
+ byte data[] = new byte[BUFFER];
+ FileOutputStream fos = new FileOutputStream(destination);
+ BufferedOutputStream dest = new BufferedOutputStream(fos, BUFFER);
+ while ((count = is.read(data, 0, BUFFER)) != -1) {
+ dest.write(data, 0, count);
+ total += BUFFER;
+ }
+ dest.flush();
+ dest.close();
+ is.close();
+ } catch (Exception ex) {
+ String information =
+ "JarFile: " + jarFile.getAbsolutePath() + "\n" + "Entry: " + (entry != null ? entry.toString() : "NULL") + "\n" + "Destination: " + (destination != null ? destination.getAbsoluteFile().toString() : "NULL") + "\n";
+ throw new IOException(information + ex.getMessage());
+ }
+ }
+
+ public static byte[] compressStream(InputStream in, String name) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ZipOutputStream out = null;
+ try {
+ out = new ZipOutputStream(bos);
+ // Add ZIP entry to output stream.
+ out.putNextEntry(new ZipEntry(name));
+ inputStreamToOutputStream(in, out);
+ } finally {
+ if (out != null) {
+ out.closeEntry();
+ out.close();
+ }
+ }
+ return bos.toByteArray();
+ }
+
+ public static byte[] compressFile(File file) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ZipOutputStream outputStream = new ZipOutputStream(bos);
+ compressFile(null, file, outputStream);
+ outputStream.closeEntry();
+ outputStream.close();
+ return bos.toByteArray();
+ }
+
+ public static void compressFiles(String basePath, Collection<File> files, String zipTarget) throws IOException {
+ if (Strings.isValid(zipTarget) != true) {
+ throw new IllegalArgumentException("Error target zip filename is invalid");
+ }
+ ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipTarget));
+ for (File file : files) {
+ if (file.isDirectory() != true) {
+ Lib.compressFile(basePath, file, out);
+ }
+ }
+ out.close();
+ }
+
+ private static void compressFile(String basePath, File file, ZipOutputStream outputStream) throws IOException {
+ FileInputStream inputStream = null;
+ try {
+ inputStream = new FileInputStream(file);
+ String entryName = file.getPath();
+ if (Strings.isValid(basePath) && entryName.startsWith(basePath)) {
+ if (basePath.endsWith(File.separator) != true) {
+ basePath = basePath + File.separator;
+ }
+ entryName = entryName.replace(basePath, "");
+ }
+ ZipEntry entry = new ZipEntry(entryName);
+ outputStream.putNextEntry(entry);
+ inputStreamToOutputStream(inputStream, outputStream);
+ } finally {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ }
+ }
+
+ private static void compressDirectory(String basePath, File source, ZipOutputStream outputStream, boolean includeSubDirectories) throws IOException {
+ File[] children = source.listFiles();
+ for (File file : children) {
+ if (file.isDirectory() != true) {
+ compressFile(basePath, file, outputStream);
+ } else {
+ if (includeSubDirectories) {
+ compressDirectory(basePath, file, outputStream, includeSubDirectories);
+ }
+ }
+ }
+ }
+
+ public static void compressDirectory(File directory, String zipTarget, boolean includeSubDirectories) throws IOException, IllegalArgumentException {
+ if (directory.isDirectory() != true) {
+ throw new IllegalArgumentException(String.format("Error source is not a directory: [%s]", directory));
+ }
+ if (Strings.isValid(zipTarget) != true) {
+ throw new IllegalArgumentException("Error target zip filename is invalid");
+ }
+ ZipOutputStream outputStream = null;
+ try {
+ outputStream = new ZipOutputStream(new FileOutputStream(zipTarget));
+ compressDirectory(directory.getPath(), directory, outputStream, includeSubDirectories);
+ } finally {
+ Lib.close(outputStream);
+ }
+ }
+
+ public static String decompressStream(InputStream inputStream, OutputStream outputStream) throws IOException {
+ String zipEntryName = null;
+ ZipInputStream zipInputStream = null;
+ try {
+ zipInputStream = new ZipInputStream(inputStream);
+ ZipEntry entry = zipInputStream.getNextEntry();
+ zipEntryName = entry.getName();
+ // Transfer bytes from the ZIP file to the output file
+ inputStreamToOutputStream(zipInputStream, outputStream);
+ } finally {
+ if (zipInputStream != null) {
+ zipInputStream.close();
+ }
+ }
+ return zipEntryName;
+ }
+
+ public static void decompressStream(InputStream inputStream, File targetDirectory) throws IOException {
+ ZipInputStream zipInputStream = null;
+ try {
+ zipInputStream = new ZipInputStream(inputStream);
+ if (!targetDirectory.exists()) {
+ targetDirectory.mkdirs();
+ }
+ ZipEntry entry = null;
+ while ((entry = zipInputStream.getNextEntry()) != null) {
+ String zipEntryName = entry.getName();
+
+ OutputStream outputStream = null;
+ try {
+ File target = new File(targetDirectory, zipEntryName);
+ if (target != null && !entry.isDirectory()) {
+ File parent = target.getParentFile();
+ if (parent != null && !parent.exists()) {
+ parent.mkdirs();
+ }
+ outputStream = new BufferedOutputStream(new FileOutputStream(target));
+ inputStreamToOutputStream(zipInputStream, outputStream);
+ }
+ } finally {
+ if (outputStream != null) {
+ outputStream.close();
+ }
+ }
+ }
+ } finally {
+ if (zipInputStream != null) {
+ zipInputStream.close();
+ }
+ }
+ }
+
+ public static byte[] decompressBytes(InputStream inputStream) throws IOException {
+ ByteArrayOutputStream out = null;
+ // Open the ZIP file
+ ZipInputStream in = new ZipInputStream(inputStream);
+
+ // Get the first entry
+ in.getNextEntry();
+
+ // Open the output file
+ out = new ByteArrayOutputStream();
+
+ inputStreamToOutputStream(in, out);
+
+ // Close the streams
+ out.close();
+ in.close();
+ return out.toByteArray();
+ }
+
+ public static void chmod777(File file) {
+ if (file == null || !file.exists()) {
+ return;
+ }
+ try {
+ String command = "chmod 777 " + file.getAbsolutePath();
+ Runtime r = Runtime.getRuntime();
+ Process p = r.exec(command);
+
+ Lib.handleProcess(p);
+ } catch (IOException ioe) {
+ ioe.printStackTrace();
+ }
+ }
+
+ public static String getSortedJavaArrayInitializer(String[] strings) {
+ Arrays.sort(strings);
+ StringBuilder strB = new StringBuilder();
+ strB.append("new String[] {\"");
+ for (String element : strings) {
+ strB.append(element);
+ strB.append("\", \"");
+ }
+ strB.replace(strB.length() - 3, strB.length(), "};");
+ return strB.toString();
+ }
+
+ /**
+ * Determine whether the input stream is word xml content.
+ *
+ * @param inputStream
+ * @return <b>true</b> is the input stream is word xml content.
+ */
+ public static boolean isWordML(InputStream inputStream) {
+ boolean toReturn = false;
+ try {
+ inputStream.mark(250);
+ byte[] buffer = new byte[200];
+ int index = 0;
+ for (; index < buffer.length; index++) {
+ if (inputStream.available() > 0) {
+ buffer[index] = (byte) inputStream.read();
+ } else {
+ break;
+ }
+ }
+ if (index > 0) {
+ String header = new String(buffer).toLowerCase();
+ if (header.contains("word.document") || header.contains("worddocument") || header.contains("<w:")) {
+ toReturn = true;
+ }
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ } finally {
+ try {
+ inputStream.reset();
+ } catch (IOException ex) {
+ // Do Nothing
+ }
+ }
+ return toReturn;
+ }
+
+ public static void close(Closeable closable) {
+ if (closable != null) {
+ try {
+ closable.close();
+ } catch (IOException ex) {
+ // Do Nothing
+ }
+ }
+ }
+
+ public static String getMemoryInfo() {
+ MemoryUsage heapMem = ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("Heap Memory Usage:\n");
+ buffer.append(String.format("\tUsed: [%s]\n", toMBytes(heapMem.getUsed())));
+ buffer.append(String.format("\tAllocated: [%s]\n", toMBytes(heapMem.getCommitted())));
+ buffer.append(String.format("\tMax: [%s]\n", toMBytes(heapMem.getMax())));
+ return buffer.toString();
+ }
+
+ public static String toMBytes(long valInBytes) {
+ NumberFormat format = NumberFormat.getInstance();
+ return String.format("%s MBytes", format.format(valInBytes / 1024.0 / 1024.0));
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Fast_Suite.java b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Fast_Suite.java
index d1999552210..7222e363b78 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Fast_Suite.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Fast_Suite.java
@@ -27,6 +27,7 @@ import org.eclipse.osee.framework.skynet.core.test.cases.TransactionManagerTest;
import org.eclipse.osee.framework.skynet.core.test.event.EventBasicGuidArtifactTest;
import org.eclipse.osee.framework.skynet.core.test.event.EventBasicGuidRelationTest;
import org.eclipse.osee.framework.skynet.core.test.event.EventChangeTypeBasicGuidArtifactTest;
+import org.eclipse.osee.framework.skynet.core.test.importing.parsers.ParsersSuite;
import org.eclipse.osee.framework.skynet.core.test.relation.RelationTestSuite;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
@@ -34,21 +35,21 @@ import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({EventBasicGuidArtifactTest.class, EventBasicGuidRelationTest.class,
- EventChangeTypeBasicGuidArtifactTest.class, ArtifactQueryTestDemo.class, TransactionManagerTest.class,
- BranchTestSuite.class, RelationTestSuite.class, ArtifactTypeInheritanceTest.class,
- Artifact_setAttributeValues.class, Artifact_getLastModified.class, CsvArtifactTest.class,
- SevereLogMonitorTest.class, RelationDeletionTest.class, StaticIdManagerTest.class, DuplicateHridTest.class,
- RelationOrderingTest.class})
+ EventChangeTypeBasicGuidArtifactTest.class, ArtifactQueryTestDemo.class, TransactionManagerTest.class,
+ BranchTestSuite.class, RelationTestSuite.class, ArtifactTypeInheritanceTest.class,
+ Artifact_setAttributeValues.class, Artifact_getLastModified.class, CsvArtifactTest.class,
+ SevereLogMonitorTest.class, RelationDeletionTest.class, StaticIdManagerTest.class, DuplicateHridTest.class,
+ RelationOrderingTest.class, ParsersSuite.class})
/**
* @author Donald G. Dunne
*/
public class FrameworkCore_Demo_Fast_Suite {
- @BeforeClass
- public static void setUp() throws Exception {
- assertTrue("Demo Application Server must be running.",
- ClientSessionManager.getAuthenticationProtocols().contains("demo"));
- assertTrue("Client must authenticate using demo protocol",
- ClientSessionManager.getSession().getAuthenticationProtocol().equals("demo"));
- }
+ @BeforeClass
+ public static void setUp() throws Exception {
+ assertTrue("Demo Application Server must be running.",
+ ClientSessionManager.getAuthenticationProtocols().contains("demo"));
+ assertTrue("Client must authenticate using demo protocol",
+ ClientSessionManager.getSession().getAuthenticationProtocol().equals("demo"));
+ }
}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Suite.java b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Suite.java
index ed6649802b7..15e0cb73b41 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Suite.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/FrameworkCore_Demo_Suite.java
@@ -42,6 +42,7 @@ import org.eclipse.osee.framework.skynet.core.test.event.BranchEventManagerTest;
import org.eclipse.osee.framework.skynet.core.test.event.TransactionEventLoopbackTest;
import org.eclipse.osee.framework.skynet.core.test.event.TransactionEventTest;
import org.eclipse.osee.framework.skynet.core.test.importing.ReqNumberingTest;
+import org.eclipse.osee.framework.skynet.core.test.importing.parsers.ParsersSuite;
import org.eclipse.osee.framework.skynet.core.test.relation.RelationTestSuite;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
@@ -49,24 +50,24 @@ import org.junit.runners.Suite;
@RunWith(Suite.class)
@Suite.SuiteClasses({ArtifactEventFiltersTest.class, BranchEventFiltersTest.class, BranchEventManagerTest.class,
- BranchEventManagerLoopbackTest.class, ArtifactLoaderTest.class, ArtifactEventManagerTest.class,
- ArtifactEventManagerLoopbackTest.class, TransactionEventTest.class, TransactionEventLoopbackTest.class,
- ArtifactQueryTestDemo.class, TransactionManagerTest.class, BranchTestSuite.class, BranchManagerTest.class,
- RelationTestSuite.class, ArtifactTypeInheritanceTest.class, ArtifactPurgeTest.class, BranchPurgeTest.class,
- PurgeTransactionTest.class, Artifact_setAttributeValues.class, Artifact_getLastModified.class,
- CsvArtifactTest.class, NativeArtifactTest.class, ConflictTest.class, ChangeManagerTest.class,
- SevereLogMonitorTest.class, RelationDeletionTest.class, StaticIdManagerTest.class, BranchStateTest.class,
- DuplicateHridTest.class, RelationOrderingTest.class, ReqNumberingTest.class})
+ BranchEventManagerLoopbackTest.class, ArtifactLoaderTest.class, ArtifactEventManagerTest.class,
+ ArtifactEventManagerLoopbackTest.class, TransactionEventTest.class, TransactionEventLoopbackTest.class,
+ ArtifactQueryTestDemo.class, TransactionManagerTest.class, BranchTestSuite.class, BranchManagerTest.class,
+ RelationTestSuite.class, ArtifactTypeInheritanceTest.class, ArtifactPurgeTest.class, BranchPurgeTest.class,
+ PurgeTransactionTest.class, Artifact_setAttributeValues.class, Artifact_getLastModified.class,
+ CsvArtifactTest.class, NativeArtifactTest.class, ConflictTest.class, ChangeManagerTest.class,
+ SevereLogMonitorTest.class, RelationDeletionTest.class, StaticIdManagerTest.class, BranchStateTest.class,
+ DuplicateHridTest.class, RelationOrderingTest.class, ReqNumberingTest.class, ParsersSuite.class})
/**
* @author Donald G. Dunne
*/
public class FrameworkCore_Demo_Suite {
- @BeforeClass
- public static void setUp() throws Exception {
- assertTrue("Demo Application Server must be running.",
- ClientSessionManager.getAuthenticationProtocols().contains("demo"));
- assertTrue("Client must authenticate using demo protocol",
- ClientSessionManager.getSession().getAuthenticationProtocol().equals("demo"));
- }
+ @BeforeClass
+ public static void setUp() throws Exception {
+ assertTrue("Demo Application Server must be running.",
+ ClientSessionManager.getAuthenticationProtocols().contains("demo"));
+ assertTrue("Client must authenticate using demo protocol",
+ ClientSessionManager.getSession().getAuthenticationProtocol().equals("demo"));
+ }
}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/MockResolutionGui.java b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/MockResolutionGui.java
new file mode 100644
index 00000000000..9d0d1f198a6
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/MockResolutionGui.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.skynet.core.test.importing.parsers;
+
+import java.util.Collection;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.skynet.core.importing.parsers.WordOutlineExtractorDelegate.ContentType;
+import org.eclipse.osee.framework.skynet.core.importing.parsers.WordOutlineExtractorDelegate.IConflictResolvingGui;
+
+public final class MockResolutionGui implements IConflictResolvingGui {
+
+ private ContentType resultingEnum;
+
+ public MockResolutionGui() {
+ this.resultingEnum = null;
+ }
+
+ public MockResolutionGui(ContentType resultingEnum) {
+ this.resultingEnum = resultingEnum;
+ }
+
+ public void setMockUserAnswer(ContentType resultingEnum) {
+ this.resultingEnum = resultingEnum;
+ }
+
+ @Override
+ public ContentType determineContentType(Collection<String> paramList) throws OseeCoreException {
+ return resultingEnum;
+ }
+}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/OutlineResolutionAndNumberTest.java b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/OutlineResolutionAndNumberTest.java
new file mode 100644
index 00000000000..5a616c2b5ff
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/OutlineResolutionAndNumberTest.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.skynet.core.test.importing.parsers;
+
+import junit.framework.Assert;
+import junit.framework.TestCase;
+import org.eclipse.osee.framework.skynet.core.importing.parsers.OutlineResolution;
+import org.junit.Test;
+
+/**
+ * @link OutlineResolution
+ * @author Karol M. Wilk
+ */
+public final class OutlineResolutionAndNumberTest extends TestCase {
+
+ private static final String LAST_OUTLINE_NUMBER = "3.1.1.2.1.7"; /* realistic outline number */
+ private final OutlineResolution outlineResolution = new OutlineResolution();
+
+ /**
+ * ! Asserting true in general means GUI should be called for user to make decision; false - opposite
+ */
+
+ @Test
+ public void testLowerOutlineNumbers() {
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("3.1.1.2.1.6", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("3.0", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("3.1.1.1", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("2.1.13.1", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("3.1.0", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("2.9", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("2.10", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("2.1", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("1.8", LAST_OUTLINE_NUMBER));
+ }
+
+ @Test
+ public void testHigherOutlineNumbers() {
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("3.1.1.2.1.8", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("3.2.1.3", LAST_OUTLINE_NUMBER));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("4.0", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("4.2", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("4.2.5.10", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("3.1.1.4.1.1", LAST_OUTLINE_NUMBER));
+ }
+
+ @Test
+ public void testRandomOutlineNumbers() {
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("6.5", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("0.25", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("10.48", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("-5.6", LAST_OUTLINE_NUMBER));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("34.fin3bbtb34fm34", LAST_OUTLINE_NUMBER));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("", ""));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber(null, null));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("200.12.3", LAST_OUTLINE_NUMBER));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("4.0", "3.1"));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("2.1.1.1.2", "2.1.1.1.1"));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("2.1.1.1.1.1", "2.1.1.1.1"));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("2.1.1.1.1.2", "2.1.1.1.1"));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("3.0", "2.1.1.1.1"));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("2.2", "2.1.1.1.1"));
+ Assert.assertFalse(outlineResolution.isInvalidOutlineNumber("2.1.2", "2.1.1.1.1"));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("3.2", "2.1.1.1.1"));
+ Assert.assertTrue(outlineResolution.isInvalidOutlineNumber("b", "c"));
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/ParsersSuite.java b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/ParsersSuite.java
new file mode 100644
index 00000000000..86e6fdb556a
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/ParsersSuite.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.skynet.core.test.importing.parsers;
+
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+@RunWith(Suite.class)
+@Suite.SuiteClasses({ //
+WordMLExtractorDelegateTableOfContentsTest.class, //
+ WordOutlineTest.class, //
+ OutlineResolutionAndNumberTest.class, //
+ WordMlResolutionGuiTest.class, //
+})
+public class ParsersSuite {
+
+}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordMLExtractorDelegateTableOfContentsTest.java b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordMLExtractorDelegateTableOfContentsTest.java
new file mode 100644
index 00000000000..28a38399700
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordMLExtractorDelegateTableOfContentsTest.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.skynet.core.test.importing.parsers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import junit.framework.Assert;
+import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.jdk.core.util.Lib;
+import org.eclipse.osee.framework.skynet.core.importing.parsers.WordOutlineExtractorDelegate;
+import org.junit.Test;
+
+/**
+ * Tests for if table of contents links pass as valid outline numbers, outline titles, ultimately forming artifacts.
+ *
+ * @link:WordOutlineExtractorDelegate
+ * @author Karol M. Wilk
+ */
+public class WordMLExtractorDelegateTableOfContentsTest {
+
+ private static final Pattern PARAGRAPHREGEX = Pattern.compile("<w:p[ >].*?</w:p>", Pattern.DOTALL);
+
+ private static final String TABLE_OF_CONTENTS_FILE = "tableOfContentsHyperlinkTest.xml";
+ private final WordOutlineExtractorDelegate delegate = new WordOutlineExtractorDelegate();
+
+ @Test
+ public void tableOfContentsLinksInput() throws Exception {
+ delegate.initialize();
+ Matcher matcher = PARAGRAPHREGEX.matcher(getFileAsString(TABLE_OF_CONTENTS_FILE));
+ boolean foundSomething = false;
+ if (matcher.find()) {
+ foundSomething = true;
+ try {
+ delegate.processContent(null, false, false, null, null, null, matcher.group(), false);
+ } catch (OseeCoreException ex) {
+ //we should get an exception because
+ Assert.assertTrue(true);
+ }
+ }
+ Assert.assertTrue(foundSomething);
+ Assert.assertTrue(delegate.getLastHeaderNumber().isEmpty());
+ Assert.assertTrue(delegate.getLastHeaderName().isEmpty());
+ Assert.assertTrue(delegate.getLastContent().isEmpty());
+ }
+
+ private static String getFileAsString(String nameOfFile) {
+ StringBuilder buffer = new StringBuilder();
+ InputStream inputStream = null;
+ try {
+ inputStream =
+ WordMLExtractorDelegateTableOfContentsTest.class.getResourceAsStream(TABLE_OF_CONTENTS_FILE);
+ buffer.append(Lib.inputStreamToString(inputStream));
+ Assert.assertTrue(buffer.length() != 0);
+ } catch (IOException ex) {
+ Assert.assertTrue(
+ String.format("%s something when wrong while reading a file...",
+ WordMLExtractorDelegateTableOfContentsTest.class.getName()), true);
+ } finally {
+ Lib.close(inputStream);
+ }
+
+ return buffer.toString();
+ }
+
+}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordMlResolutionGuiTest.java b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordMlResolutionGuiTest.java
new file mode 100644
index 00000000000..188d1452c75
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordMlResolutionGuiTest.java
@@ -0,0 +1,119 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.skynet.core.test.importing.parsers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import junit.framework.Assert;
+import org.eclipse.osee.framework.jdk.core.util.Lib;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.skynet.core.importing.RoughArtifact;
+import org.eclipse.osee.framework.skynet.core.importing.RoughArtifactKind;
+import org.eclipse.osee.framework.skynet.core.importing.operations.RoughArtifactCollector;
+import org.eclipse.osee.framework.skynet.core.importing.parsers.WordOutlineExtractorDelegate;
+import org.eclipse.osee.framework.skynet.core.importing.parsers.WordOutlineExtractorDelegate.ContentType;
+import org.junit.After;
+import org.junit.Test;
+
+/**
+ * @formatter:off
+ * Tests by inputing the whole requirements sample ICD file.
+ * Tests:
+ * - if user answers store as content vs store as an outline number,
+ * depending on what user selects.
+ *
+ * THESE TESTS MUST RUN AS PART OF THE SUITE, RoughArtifact* classes need
+ * the osee caching service.
+ *
+ * @link WordOutlineExtractorDelegate
+ *
+ * @author Karol M. Wilk
+ */
+//@formatter:on
+public class WordMlResolutionGuiTest {
+
+ private static final Pattern PARAGRAPH_REGEX =
+ Pattern.compile("<w:p[ >].*?</w:p>", Pattern.DOTALL);
+
+ private static final String FILE_INPUT =
+ "outlineResolutionCausingInput_no_toc_formatted.xml";
+
+ private WordOutlineExtractorDelegate delegate = null;
+
+ public WordMlResolutionGuiTest() {
+ delegate = new WordOutlineExtractorDelegate(
+ new MockResolutionGui());
+ }
+
+ @Test
+ public void uiResolutionTests() throws Exception {
+ //init some ds in delegate
+ delegate.initialize();
+
+ //TODO: not finished, needs to be able to compare resulting rough artifact to data
+ RoughArtifact testRoughArtifactParent = new RoughArtifact(RoughArtifactKind.CONTAINER);
+ RoughArtifactCollector testCollector = new RoughArtifactCollector(testRoughArtifactParent);
+
+ MockResolutionGui resolvingGui =
+ (MockResolutionGui)
+ delegate.getOutlineResolvingUi();
+ //as if the user selected content
+ //if asked answer No, treat questions as content
+ resolvingGui.setMockUserAnswer(ContentType.CONTENT);
+
+ //pre load with some real data
+ String rawData = getResourceData(FILE_INPUT);
+ Matcher matcher = PARAGRAPH_REGEX.matcher(rawData);
+ boolean foundSomething = false;
+ matcher.find();//skip 1.0
+ matcher.find();//skip 1.1
+ //read the 3.1
+ if (matcher.find()) {
+ foundSomething = true;
+ String singleWp = matcher.group();
+ //TODO: pass in the real testCollector
+ delegate.processContent(null, false, false, null,
+ null, null, singleWp, false);
+ }
+
+ //TODO:
+ //because this case puts stuff into content
+ //there should be a node containing 'Meters and 5.4 Meters'
+ //i.e. testRoughArtifactParent.getContent().equals( "Meters and 5.4 Meters" );
+
+ Assert.assertTrue(foundSomething);
+ }
+
+ @After
+ public void testCleanup() {
+ delegate.dispose();
+ Assert.assertNull(delegate.getLastHeaderNumber());
+ Assert.assertNull(delegate.getLastHeaderName());
+ Assert.assertNull(delegate.getLastContent());
+ }
+
+ private static String getResourceData(String name)
+ throws IOException {
+
+ InputStream inputStream = null;
+ try {
+ inputStream =
+ WordMlResolutionGuiTest.class.getResourceAsStream(name);
+ String data = Lib.inputStreamToString(inputStream);
+ Assert.assertTrue(Strings.isValid(data));
+ return data;
+ } finally {
+ Lib.close(inputStream);
+ }
+ }
+}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordOutlineTest.java b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordOutlineTest.java
new file mode 100644
index 00000000000..897c3d1de5e
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/WordOutlineTest.java
@@ -0,0 +1,213 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.skynet.core.test.importing.parsers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import junit.framework.Assert;
+import org.eclipse.osee.framework.jdk.core.util.Lib;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+import org.eclipse.osee.framework.skynet.core.importing.parsers.WordOutlineExtractorDelegate;
+import org.junit.After;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ * Tests different forms of outline numbers and titles
+ *
+ * @link WordOutlineExtractorDelegate
+ * @author Karol M. Wilk
+ */
+@RunWith(Parameterized.class)
+public final class WordOutlineTest {
+
+ private static final Pattern paragraphRegex = Pattern.compile("<w:p[ >].*?</w:p>");
+ private static final Pattern outlineNumber = Pattern.compile("((?>\\d+\\.)+\\d*)\\s*");
+
+ private static final String outlineNameWithNumber = "outlineNameWithNumber.xml";
+ private static final String outlineNameNumberAndContent = "outlineNameNumberAndContent.xml";
+ private static final String numberEmbeddedInTheContent = "numberEmbeddedInTheContent.xml";
+
+ private final WordOutlineExtractorDelegate delegate;
+ private final String dataFileName;
+ private final DelegateData[] expectedData;
+
+ public WordOutlineTest(String dataFileName, DelegateData... expectedData) {
+ this.delegate = new WordOutlineExtractorDelegate();
+ this.dataFileName = dataFileName;
+ this.expectedData = expectedData;
+ }
+
+ /**
+ * @formatter:off
+ * Note: some of the data objects need to repeat data
+ * from previous test because they are considered to
+ * be lastHeaderNumber or lastHeaderName or lastContent
+ *
+ * @return collection of data sets used as input for parameterized unit test
+ */
+ //@formatter:on
+ @Parameters
+ public static Collection<Object[]> getData() {
+ List<Object[]> data = new ArrayList<Object[]>();
+ data.add(new Object[] {outlineNameWithNumber, new DelegateData[] {data("1.", "Outline TITLE", "")}});
+ data.add(new Object[] {
+ outlineNameNumberAndContent,
+ new DelegateData[] {data("5.", "SCOPE", ""), data("5.", "SCOPE", "content content content more content")}});
+ data.add(new Object[] {
+ numberEmbeddedInTheContent,
+ new DelegateData[] {data("1.", "SCOPE", ""),
+ data("1.", "SCOPE", "This 1.6 is some interesting content 2.3SAMPL–10.")}});
+ return data;
+ }
+
+ private static DelegateData data(String headerNumber, String headerName, String content) {
+ return new DelegateData(headerNumber, headerName, content);
+ }
+
+ private static String getResourceData(String name) throws IOException {
+ InputStream inputStream = null;
+ try {
+ inputStream = WordOutlineTest.class.getResourceAsStream(name);
+ String data = Lib.inputStreamToString(inputStream);
+ Assert.assertTrue(Strings.isValid(data));
+ return data;
+ } finally {
+ Lib.close(inputStream);
+ }
+ }
+
+ @Test
+ public void testDelegate() throws Exception {
+ delegate.initialize();
+
+ String rawData = getResourceData(dataFileName);
+ Matcher matcher = paragraphRegex.matcher(rawData);
+ boolean foundSomething = false;
+
+ List<DelegateData> actualData = new ArrayList<DelegateData>();
+
+ while (matcher.find()) {
+ foundSomething = true;
+ String data = matcher.group();
+ delegate.processContent(null, false, false, null, null, null, data, false);
+
+ String headerNumber = delegate.getLastHeaderNumber().trim();
+ String headerName = delegate.getLastHeaderName().trim();
+ String content = delegate.getLastContent().trim();
+
+ actualData.add(data(headerNumber, headerName, content));
+ }
+
+ Assert.assertTrue("WordOutlineTester no paragraphs found...", foundSomething);
+ for (int index = 0; index < expectedData.length; index++) {
+ DelegateData expected = expectedData[index];
+ DelegateData actual = actualData.get(index);
+ Assert.assertEquals(
+ String.format(
+ "\nChecking %s of %s,\nEXPECTED: \n\t Number:\"%s\" \n\t Title:\"%s\" \n\t Content:\"%s\"\nACTUAL: \n\t Number:\"%s\" \n\t Title:\"%s\" \n\t Content:\"%s\"\n",
+ index, dataFileName, expected.getHeaderNumber(), expected.getHeaderName(),
+ expected.getContent(),
+ actual.getHeaderNumber(), actual.getHeaderName(), actual.getContent()), expected, actual);
+ if (Strings.isValid(expected.getHeaderNumber())) {
+ Assert.assertTrue("WordOutlineTester doesn't look like a outline number...", outlineNumber.matcher(
+ actual.getHeaderNumber()).matches());
+ }
+ }
+ }
+
+ @After
+ public void testCleanup() {
+ delegate.dispose();
+ Assert.assertNull(delegate.getLastHeaderNumber());
+ Assert.assertNull(delegate.getLastHeaderName());
+ Assert.assertNull(delegate.getLastContent());
+ }
+
+ private static class DelegateData {
+ private final String headerNumber;
+ private final String headerName;
+ private final String content;
+
+ public DelegateData(String headerNumber, String headerName, String content) {
+ super();
+ this.headerNumber = headerNumber;
+ this.headerName = headerName;
+ this.content = content;
+ }
+
+ public String getHeaderNumber() {
+ return this.headerNumber;
+ }
+
+ public String getHeaderName() {
+ return this.headerName;
+ }
+
+ public String getContent() {
+ return this.content;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + ((content == null) ? 0 : content.hashCode());
+ result = prime * result + ((headerName == null) ? 0 : headerName.hashCode());
+ result = prime * result + ((headerNumber == null) ? 0 : headerNumber.hashCode());
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ DelegateData other = (DelegateData) obj;
+ if (content == null) {
+ if (other.content != null) {
+ return false;
+ }
+ } else if (!content.equals(other.content)) {
+ return false;
+ }
+ if (headerName == null) {
+ if (other.headerName != null) {
+ return false;
+ }
+ } else if (!headerName.equals(other.headerName)) {
+ return false;
+ }
+ if (headerNumber == null) {
+ if (other.headerNumber != null) {
+ return false;
+ }
+ } else if (!headerNumber.equals(other.headerNumber)) {
+ return false;
+ }
+ return true;
+ }
+
+ }
+}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/numberEmbeddedInTheContent.xml b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/numberEmbeddedInTheContent.xml
new file mode 100644
index 00000000000..3ee206c567a
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/numberEmbeddedInTheContent.xml
@@ -0,0 +1,2 @@
+<w:p wsp:rsidR="00AC5806" wsp:rsidRDefault="00A6010B"><w:pPr><w:pStyle w:val="lvl2on"/><w:spacing w:before="8" w:line="273" w:line-rule="at-least"/></w:pPr><w:r><w:rPr><w:b/><w:b-cs/><w:caps/></w:rPr><w:t>1. SCOPE</w:t></w:r></w:p>
+<w:p wsp:rsidR="00sC5806" wsp:rsidRDefault="00A6010B"><w:pPr><w:pStyle w:val="Ltxt"/><w:spacing w:before="48" w:line="273" w:line-rule="at-least"/></w:pPr><w:r><w:t>This 1.6 is some interesting content 2.3</w:t></w:r><w:r wsp:rsidR="00DC3082"><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText>fe "SAMPL-10"</w:instrText></w:r><w:r wsp:rsidR="00DC3082"><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t>SAMPL–10.</w:t></w:r></w:p>
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineNameNumberAndContent.xml b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineNameNumberAndContent.xml
new file mode 100644
index 00000000000..9891d31a758
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineNameNumberAndContent.xml
@@ -0,0 +1,2 @@
+<w:p wsp:rsidR="00AC5806" wsp:rsidRDefault="00A6010B"><w:pPr><w:pStyle w:val="lvl2on"/><w:spacing w:before="8" w:line="273" w:line-rule="at-least"/></w:pPr><w:r><w:rPr><w:b/><w:b-cs/><w:caps/></w:rPr><w:t>5. SCOPE</w:t></w:r></w:p>
+<w:p wsp:rsidR="00As5806" wsp:rsidRDefault="00A6010B"><w:pPr><w:pStyle w:val="Ltxt"/><w:spacing w:before="48" w:line="273" w:line-rule="at-least"/></w:pPr><w:r><w:t>content content content</w:t></w:r><w:r wsp:rsidR="00DC3082"><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText>blah</w:instrText></w:r><w:r wsp:rsidR="00DC3082"><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t> more content</w:t></w:r></w:p>
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineNameWithNumber.xml b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineNameWithNumber.xml
new file mode 100644
index 00000000000..9f5ec8f1f81
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineNameWithNumber.xml
@@ -0,0 +1 @@
+<w:p wsp:rsidR="00s5806" wsp:rsidRDefault="00A6010B"><w:pPr><w:pStyle w:val="lvl2on"/><w:spacing w:before="8" w:line="273" w:line-rule="at-least"/></w:pPr><w:r><w:rPr><w:b/><w:b-cs/><w:caps/></w:rPr><w:t>1. Outline TITLE </w:t></w:r></w:p>
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineResolutionCausingInput_no_toc_formatted.xml b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineResolutionCausingInput_no_toc_formatted.xml
new file mode 100644
index 00000000000..a9e489c8020
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/outlineResolutionCausingInput_no_toc_formatted.xml
@@ -0,0 +1,255 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<?mso-application progid="Word.Document"?>
+<w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:sl="http://schemas.microsoft.com/schemaLibrary/2003/core" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:dt="uuid:C2F41010-65B3-11d1-A29F-00AA00C14882" xmlns:wsp="http://schemas.microsoft.com/office/word/2003/wordml/sp2" w:macrosPresent="no" w:embeddedObjPresent="yes" w:ocxPresent="no" xml:space="preserve"><w:ignoreElements w:val="http://schemas.microsoft.com/office/word/2003/wordml/sp2"/><o:DocumentProperties><o:Title>ERROR</o:Title><o:Author>b1592199</o:Author><o:LastAuthor>b1797896</o:LastAuthor><o:Revision>8</o:Revision><o:TotalTime>35</o:TotalTime><o:LastPrinted>2003-07-10T20:07:00Z</o:LastPrinted><o:Created>2010-06-14T18:16:00Z</o:Created><o:LastSaved>2010-07-14T20:24:00Z</o:LastSaved><o:Pages>1</o:Pages><o:Words>11</o:Words><o:Characters>65</o:Characters><o:Company> </o:Company><o:Lines>1</o:Lines><o:Paragraphs>1</o:Paragraphs><o:CharactersWithSpaces>75</o:CharactersWithSpaces><o:Version>11.0000</o:Version></o:DocumentProperties><o:CustomDocumentProperties><o:Contract_x0020__x0023_ dt:dt="string"> </o:Contract_x0020__x0023_><o:Revision dt:dt="string">AVNS-PRF-10844</o:Revision><o:Date dt:dt="string">TBD</o:Date><o:Left_x0020_Page_x0020_Head dt:dt="string"> </o:Left_x0020_Page_x0020_Head><o:Right_x0020_Page_x0020_Head dt:dt="string"> </o:Right_x0020_Page_x0020_Head><o:Left_x0020_Page_x0020_Foot dt:dt="string"> </o:Left_x0020_Page_x0020_Foot><o:Right_x0020_Page_x0020_Foot dt:dt="string"> </o:Right_x0020_Page_x0020_Foot><o:Style_x0020_Sheet_x0020_ID dt:dt="string">\\sw\mes\SE-RQMT_DB\SLATE_Templates\ExportTemplateBlockIII_PRF_LRIP.dot</o:Style_x0020_Sheet_x0020_ID><o:Title dt:dt="string"> </o:Title><o:Agency_x0020_Code dt:dt="string"> </o:Agency_x0020_Code><o:Document_x0020_Classification dt:dt="string">None</o:Document_x0020_Classification><o:FSC_x0020_Code dt:dt="string"> </o:FSC_x0020_Code><o:Manufacturer_x0020_Code dt:dt="string"> </o:Manufacturer_x0020_Code><o:Part_x0020_Identification dt:dt="string"> </o:Part_x0020_Identification><o:Security_x0020_Marking dt:dt="string">Unclassified</o:Security_x0020_Marking><o:Specification_x0020_Number dt:dt="string"> </o:Specification_x0020_Number><o:Auto-Generate dt:dt="string">None</o:Auto-Generate><o:Description dt:dt="string"> </o:Description><o:Series_x0020_Label dt:dt="string">A:</o:Series_x0020_Label><o:Style_x0020_Catalog dt:dt="string">1Level;2Level;3Level;4Level;5Level;6Level;7Level;8Level;9Level;</o:Style_x0020_Catalog><o:Classification_x0020_Dictionary dt:dt="string">Unclassified</o:Classification_x0020_Dictionary><o:Title_x0020_Page dt:dt="string">
+ &lt;PARA DocTitle&gt;[ slsgetValue . TITLE false false ]
+
+
+
+
+
+
+ &lt;PARA DocDate&gt; Date: [sl8getAttribute . Date ]
+ &lt;PARA Prepared By&gt; Author: [sl8getAttribute . {Prepared By} ]
+ &lt;PARA Prepared For&gt; Prepared for: [sl8getAttribute . {Prepared For} ]
+
+
+ &lt;</o:Title_x0020_Page><o:ImportedFromFile dt:dt="string"> </o:ImportedFromFile><o:MS_x0020_Word_x0020_Export_x0020_To dt:dt="string"> </o:MS_x0020_Word_x0020_Export_x0020_To><o:Document_x0020_Status dt:dt="string">Released</o:Document_x0020_Status><o:Subsystem_x0020_Owner dt:dt="string"> </o:Subsystem_x0020_Owner><o:Supersedes dt:dt="string"> </o:Supersedes><o:Assigned_x0020_To dt:dt="string">None</o:Assigned_x0020_To><o:sl8ExportUser dt:dt="string">b1592199</o:sl8ExportUser><o:sl8ExportProject dt:dt="string">Apache_Block_3 LOID:1.0.1476703</o:sl8ExportProject><o:sl8ExportOptions dt:dt="string">ShowTables ShowGraphics FigureTitleBelow UpdateWordDoc AutofitTables CenterGraphics ExportDocAttr WordTrackRevs AutoNumFigures TableTitleAbove HideWord CorrectTitles ShowGraphicLockedDialog ShowDialog ListOfTables ShowTables ShowGraphics FigureTitleBelow </o:sl8ExportOptions><o:sl8ExportDocObj dt:dt="string">WIN:36984704:64305800</o:sl8ExportDocObj><o:sl8ExportVersion dt:dt="string">V4.8B15</o:sl8ExportVersion><o:sl8ExportDate dt:dt="string">2010/03/25 14:13:15</o:sl8ExportDate></o:CustomDocumentProperties><w:fonts><w:defaultFonts w:ascii="Times New Roman" w:fareast="Times New Roman" w:h-ansi="Times New Roman" w:cs="Times New Roman"/><w:font w:name="Helvetica"><w:panose-1 w:val="020B0604020202020204"/><w:charset w:val="00"/><w:family w:val="Swiss"/><w:pitch w:val="variable"/><w:sig w:usb-0="20007A87" w:usb-1="80000000" w:usb-2="00000008" w:usb-3="00000000" w:csb-0="000001FF" w:csb-1="00000000"/></w:font><w:font w:name="Wingdings"><w:panose-1 w:val="05000000000000000000"/><w:charset w:val="02"/><w:family w:val="Auto"/><w:pitch w:val="variable"/><w:sig w:usb-0="00000000" w:usb-1="10000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="80000000" w:csb-1="00000000"/></w:font><w:font w:name="MS Mincho"><w:altName w:val="MS 明�"/><w:panose-1 w:val="02020609040205080304"/><w:charset w:val="80"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="fixed"/><w:sig w:usb-0="00000001" w:usb-1="08070000" w:usb-2="00000010" w:usb-3="00000000" w:csb-0="00020000" w:csb-1="00000000"/></w:font><w:font w:name="Tahoma"><w:panose-1 w:val="020B0604030504040204"/><w:charset w:val="00"/><w:family w:val="Swiss"/><w:pitch w:val="variable"/><w:sig w:usb-0="61007A87" w:usb-1="80000000" w:usb-2="00000008" w:usb-3="00000000" w:csb-0="000101FF" w:csb-1="00000000"/></w:font><w:font w:name="Times"><w:panose-1 w:val="02020603050405020304"/><w:charset w:val="00"/><w:family w:val="Roman"/><w:pitch w:val="variable"/><w:sig w:usb-0="20007A87" w:usb-1="80000000" w:usb-2="00000008" w:usb-3="00000000" w:csb-0="000001FF" w:csb-1="00000000"/></w:font><w:font w:name="Palatino"><w:altName w:val="Book Antiqua"/><w:panose-1 w:val="00000000000000000000"/><w:charset w:val="00"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="variable"/><w:sig w:usb-0="00000003" w:usb-1="00000000" w:usb-2="00000000" w:usb-3="00000000" w:csb-0="00000001" w:csb-1="00000000"/></w:font><w:font w:name="@MS Mincho"><w:panose-1 w:val="00000000000000000000"/><w:charset w:val="80"/><w:family w:val="Roman"/><w:notTrueType/><w:pitch w:val="fixed"/><w:sig w:usb-0="00000001" w:usb-1="08070000" w:usb-2="00000010" w:usb-3="00000000" w:csb-0="00020000" w:csb-1="00000000"/></w:font></w:fonts><w:lists><w:listDef w:listDefId="0"><w:lsid w:val="FFFFFF7D"/><w:plt w:val="SingleLevel"/><w:tmpl w:val="860E6234"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="%1."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr></w:lvl></w:listDef><w:listDef w:listDefId="1"><w:lsid w:val="FFFFFF7E"/><w:plt w:val="SingleLevel"/><w:tmpl w:val="4C7819C4"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="%1."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1080"/></w:tabs><w:ind w:left="1080" w:hanging="360"/></w:pPr></w:lvl></w:listDef><w:listDef w:listDefId="2"><w:lsid w:val="0AAA3E7C"/><w:plt w:val="SingleLevel"/><w:tmpl w:val="B3EA9E2C"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="%1."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="360"/></w:tabs><w:ind w:left="360" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Times" w:h-ansi="Times" w:hint="default"/><w:sz w:val="24"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="3"><w:lsid w:val="2080797B"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="9176EC16"/><w:lvl w:ilvl="0" w:tplc="545CBCEA"><w:start w:val="1"/><w:nfc w:val="1"/><w:lvlText w:val="Table %1."/><w:lvlJc w:val="center"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090019" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText w:val="%2."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="2" w:tplc="0409001B" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText w:val="%3."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="180"/></w:pPr></w:lvl><w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="on"><w:start w:val="1"/><w:lvlText w:val="%4."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="180"/></w:pPr></w:lvl><w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="on"><w:start w:val="1"/><w:lvlText w:val="%7."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="180"/></w:pPr></w:lvl></w:listDef><w:listDef w:listDefId="4"><w:lsid w:val="24132BF9"/><w:plt w:val="SingleLevel"/><w:tmpl w:val="EC506922"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="Figure %1:"/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="504"/></w:tabs><w:ind w:left="504" w:hanging="216"/></w:pPr></w:lvl></w:listDef><w:listDef w:listDefId="5"><w:lsid w:val="38683B09"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="1592F8FE"/><w:lvl w:ilvl="0" w:tplc="0409000F"><w:start w:val="1"/><w:lvlText w:val="%1."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1080"/></w:tabs><w:ind w:left="1080" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090019" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText w:val="%2."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1800"/></w:tabs><w:ind w:left="1800" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="2" w:tplc="0409001B" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText w:val="%3."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2520"/></w:tabs><w:ind w:left="2520" w:hanging="180"/></w:pPr></w:lvl><w:lvl w:ilvl="3" w:tplc="0409000F" w:tentative="on"><w:start w:val="1"/><w:lvlText w:val="%4."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3240"/></w:tabs><w:ind w:left="3240" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090019" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText w:val="%5."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3960"/></w:tabs><w:ind w:left="3960" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="5" w:tplc="0409001B" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText w:val="%6."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4680"/></w:tabs><w:ind w:left="4680" w:hanging="180"/></w:pPr></w:lvl><w:lvl w:ilvl="6" w:tplc="0409000F" w:tentative="on"><w:start w:val="1"/><w:lvlText w:val="%7."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5400"/></w:tabs><w:ind w:left="5400" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090019" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="4"/><w:lvlText w:val="%8."/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6120"/></w:tabs><w:ind w:left="6120" w:hanging="360"/></w:pPr></w:lvl><w:lvl w:ilvl="8" w:tplc="0409001B" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="2"/><w:lvlText w:val="%9."/><w:lvlJc w:val="right"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6840"/></w:tabs><w:ind w:left="6840" w:hanging="180"/></w:pPr></w:lvl></w:listDef><w:listDef w:listDefId="6"><w:lsid w:val="3FA60D2F"/><w:plt w:val="HybridMultilevel"/><w:tmpl w:val="F676D226"/><w:lvl w:ilvl="0" w:tplc="7D28D874"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="360"/></w:tabs><w:ind w:left="360" w:hanging="216"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/><w:sz w:val="20"/><w:sz-cs w:val="20"/></w:rPr></w:lvl><w:lvl w:ilvl="1" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1440"/></w:tabs><w:ind w:left="1440" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2160"/></w:tabs><w:ind w:left="2160" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="2880"/></w:tabs><w:ind w:left="2880" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="3600"/></w:tabs><w:ind w:left="3600" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="4320"/></w:tabs><w:ind w:left="4320" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6" w:tplc="04090001" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5040"/></w:tabs><w:ind w:left="5040" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7" w:tplc="04090003" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val="o"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="5760"/></w:tabs><w:ind w:left="5760" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Courier New" w:h-ansi="Courier New" w:cs="Courier New" w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8" w:tplc="04090005" w:tentative="on"><w:start w:val="1"/><w:nfc w:val="23"/><w:lvlText w:val=""/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="6480"/></w:tabs><w:ind w:left="6480" w:hanging="360"/></w:pPr><w:rPr><w:rFonts w:ascii="Wingdings" w:h-ansi="Wingdings" w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="7"><w:lsid w:val="44360111"/><w:plt w:val="Multilevel"/><w:tmpl w:val="A4E2EF5A"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="%1.0 "/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl><w:lvl w:ilvl="1"><w:start w:val="1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl><w:lvl w:ilvl="2"><w:start w:val="1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl><w:lvl w:ilvl="3"><w:start w:val="1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl><w:lvl w:ilvl="4"><w:start w:val="1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl><w:lvl w:ilvl="5"><w:start w:val="1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl><w:lvl w:ilvl="6"><w:start w:val="1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl><w:lvl w:ilvl="7"><w:start w:val="1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl><w:lvl w:ilvl="8"><w:start w:val="1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8.%9 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr></w:lvl></w:listDef><w:listDef w:listDefId="8"><w:lsid w:val="47C16D26"/><w:plt w:val="SingleLevel"/><w:tmpl w:val="25988476"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="Figure %1: "/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1080"/></w:tabs><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:ascii="Times" w:h-ansi="Times" w:hint="default"/><w:b/><w:i w:val="off"/><w:sz w:val="24"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="9"><w:lsid w:val="4C3C59FD"/><w:plt w:val="SingleLevel"/><w:tmpl w:val="D514EE84"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="Table %1: "/><w:lvlJc w:val="center"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="720"/></w:tabs><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:ascii="Times" w:h-ansi="Times" w:hint="default"/><w:b/><w:i w:val="off"/><w:sz w:val="24"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="10"><w:lsid w:val="65007170"/><w:plt w:val="SingleLevel"/><w:tmpl w:val="A3C40B62"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="Table %1:"/><w:lvlJc w:val="left"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1080"/></w:tabs><w:ind w:left="360" w:hanging="360"/></w:pPr></w:lvl></w:listDef><w:listDef w:listDefId="11"><w:lsid w:val="688B6D0E"/><w:plt w:val="Multilevel"/><w:tmpl w:val="339AED1C"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:pStyle w:val="Heading1"/><w:suff w:val="Space"/><w:lvlText w:val="%1.0 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="1"><w:start w:val="1"/><w:pStyle w:val="Heading2"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="2"><w:start w:val="1"/><w:pStyle w:val="Heading3"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="3"><w:start w:val="1"/><w:pStyle w:val="Heading4"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="4"><w:start w:val="1"/><w:pStyle w:val="Heading5"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="5"><w:start w:val="1"/><w:pStyle w:val="Heading6"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="6"><w:start w:val="1"/><w:pStyle w:val="Heading7"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="7"><w:start w:val="1"/><w:pStyle w:val="Heading8"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl><w:lvl w:ilvl="8"><w:start w:val="1"/><w:pStyle w:val="Heading9"/><w:suff w:val="Space"/><w:lvlText w:val="%1.%2.%3.%4.%5.%6.%7.%8.%9 "/><w:lvlJc w:val="left"/><w:pPr><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><w:rFonts w:hint="default"/></w:rPr></w:lvl></w:listDef><w:listDef w:listDefId="12"><w:lsid w:val="7EBA0ACE"/><w:plt w:val="SingleLevel"/><w:tmpl w:val="E374984C"/><w:lvl w:ilvl="0"><w:start w:val="1"/><w:lvlText w:val="Figure %1: "/><w:lvlJc w:val="center"/><w:pPr><w:tabs><w:tab w:val="list" w:pos="1008"/></w:tabs><w:ind w:left="0" w:first-line="288"/></w:pPr></w:lvl></w:listDef><w:list w:ilfo="1"><w:ilst w:val="12"/></w:list><w:list w:ilfo="2"><w:ilst w:val="12"/></w:list><w:list w:ilfo="3"><w:ilst w:val="9"/></w:list><w:list w:ilfo="4"><w:ilst w:val="11"/></w:list><w:list w:ilfo="5"><w:ilst w:val="1"/></w:list><w:list w:ilfo="6"><w:ilst w:val="8"/></w:list><w:list w:ilfo="7"><w:ilst w:val="2"/></w:list><w:list w:ilfo="8"><w:ilst w:val="4"/></w:list><w:list w:ilfo="9"><w:ilst w:val="10"/></w:list><w:list w:ilfo="10"><w:ilst w:val="0"/></w:list><w:list w:ilfo="11"><w:ilst w:val="11"/></w:list><w:list w:ilfo="12"><w:ilst w:val="3"/></w:list><w:list w:ilfo="13"><w:ilst w:val="6"/></w:list><w:list w:ilfo="14"><w:ilst w:val="7"/></w:list><w:list w:ilfo="15"><w:ilst w:val="5"/></w:list></w:lists><w:styles><w:versionOfBuiltInStylenames w:val="4"/><w:latentStyles w:defLockedState="off" w:latentStyleCount="156"/><w:style w:type="paragraph" w:default="on" w:styleId="Normal"><w:name w:val="Normal"/><w:rsid w:val="00414030"/><w:pPr><w:jc w:val="both"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:sz w:val="22"/><w:sz-cs w:val="16"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading1"><w:name w:val="heading 1"/><wx:uiName wx:val="Heading 1"/><w:next w:val="Normal"/><w:rsid w:val="00074C93"/><w:pPr><w:pStyle w:val="Heading1"/><w:keepNext/><w:keepLines/><w:widowControl w:val="off"/><w:listPr><w:ilfo w:val="11"/></w:listPr><w:spacing w:before="240" w:after="240"/><w:outlineLvl w:val="0"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:smallCaps/><w:noProof/><w:kern w:val="28"/><w:sz w:val="28"/><w:sz-cs w:val="28"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading2"><w:name w:val="heading 2"/><wx:uiName wx:val="Heading 2"/><w:next w:val="Normal"/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="Heading2"/><w:keepNext/><w:keepLines/><w:widowControl w:val="off"/><w:listPr><w:ilvl w:val="1"/><w:ilfo w:val="11"/></w:listPr><w:spacing w:before="120" w:after="120"/><w:outlineLvl w:val="1"/></w:pPr><w:rPr><w:rFonts w:ascii="Times" w:h-ansi="Times"/><wx:font wx:val="Times"/><w:b/><w:noProof/><w:sz w:val="22"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading3"><w:name w:val="heading 3"/><wx:uiName wx:val="Heading 3"/><w:basedOn w:val="Heading2"/><w:next w:val="Normal"/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="Heading3"/><w:listPr><w:ilvl w:val="2"/></w:listPr><w:outlineLvl w:val="2"/></w:pPr><w:rPr><wx:font wx:val="Times"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading4"><w:name w:val="heading 4"/><wx:uiName wx:val="Heading 4"/><w:basedOn w:val="Heading3"/><w:next w:val="Normal"/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="Heading4"/><w:listPr><w:ilvl w:val="3"/></w:listPr><w:outlineLvl w:val="3"/></w:pPr><w:rPr><wx:font wx:val="Times"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading5"><w:name w:val="heading 5"/><wx:uiName wx:val="Heading 5"/><w:basedOn w:val="Heading4"/><w:next w:val="Normal"/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="Heading5"/><w:listPr><w:ilvl w:val="4"/></w:listPr><w:outlineLvl w:val="4"/></w:pPr><w:rPr><wx:font wx:val="Times"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading6"><w:name w:val="heading 6"/><wx:uiName wx:val="Heading 6"/><w:basedOn w:val="Heading5"/><w:next w:val="Normal"/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="Heading6"/><w:listPr><w:ilvl w:val="5"/></w:listPr><w:outlineLvl w:val="5"/></w:pPr><w:rPr><wx:font wx:val="Times"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading7"><w:name w:val="heading 7"/><wx:uiName wx:val="Heading 7"/><w:basedOn w:val="Heading6"/><w:next w:val="Normal"/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="Heading7"/><w:listPr><w:ilvl w:val="6"/></w:listPr><w:outlineLvl w:val="6"/></w:pPr><w:rPr><wx:font wx:val="Times"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading8"><w:name w:val="heading 8"/><wx:uiName wx:val="Heading 8"/><w:basedOn w:val="Heading7"/><w:next w:val="Normal"/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="Heading8"/><w:listPr><w:ilvl w:val="7"/></w:listPr><w:outlineLvl w:val="7"/></w:pPr><w:rPr><wx:font wx:val="Times"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Heading9"><w:name w:val="heading 9"/><wx:uiName wx:val="Heading 9"/><w:basedOn w:val="Heading8"/><w:next w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="Heading9"/><w:listPr><w:ilvl w:val="8"/></w:listPr><w:outlineLvl w:val="8"/></w:pPr><w:rPr><wx:font wx:val="Times"/></w:rPr></w:style><w:style w:type="character" w:default="on" w:styleId="DefaultParagraphFont"><w:name w:val="Default Paragraph Font"/><w:semiHidden/></w:style><w:style w:type="table" w:default="on" w:styleId="TableNormal"><w:name w:val="Normal Table"/><wx:uiName wx:val="Table Normal"/><w:semiHidden/><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr><w:tblPr><w:tblInd w:w="0" w:type="dxa"/><w:tblCellMar><w:top w:w="0" w:type="dxa"/><w:left w:w="108" w:type="dxa"/><w:bottom w:w="0" w:type="dxa"/><w:right w:w="108" w:type="dxa"/></w:tblCellMar></w:tblPr></w:style><w:style w:type="list" w:default="on" w:styleId="NoList"><w:name w:val="No List"/><w:semiHidden/></w:style><w:style w:type="paragraph" w:styleId="Salutation"><w:name w:val="Salutation"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Salutation"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Title"><w:name w:val="Title"/><w:next w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Title"/><w:spacing w:before="120" w:after="60"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:caps/><w:kern w:val="28"/><w:sz w:val="28"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="FigureTitle"><w:name w:val="FigureTitle"/><w:basedOn w:val="Caption"/><w:next w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="FigureTitle"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Caption"><w:name w:val="caption"/><wx:uiName wx:val="Caption"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Caption"/><w:spacing w:before="120" w:after="120"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableTitle"><w:name w:val="TableTitle"/><w:basedOn w:val="Caption"/><w:next w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableTitle"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="character" w:styleId="SecurityGraphic"><w:name w:val="Security Graphic"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00672228"/></w:style><w:style w:type="character" w:styleId="SecurityHeading"><w:name w:val="Security Heading"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00672228"/></w:style><w:style w:type="character" w:styleId="SecurityPage"><w:name w:val="Security Page"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00672228"/></w:style><w:style w:type="character" w:styleId="SecurityPara"><w:name w:val="Security Para"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00672228"/></w:style><w:style w:type="character" w:styleId="SecurityParaEnd"><w:name w:val="Security Para End"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00672228"/></w:style><w:style w:type="character" w:styleId="SecurityTable"><w:name w:val="Security Table"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00672228"/></w:style><w:style w:type="character" w:styleId="SecurityTitle"><w:name w:val="Security Title"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00672228"/></w:style><w:style w:type="paragraph" w:styleId="SignatureApproved"><w:name w:val="Signature:Approved"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="SignatureApproved"/><w:tabs><w:tab w:val="left" w:pos="0"/></w:tabs><w:spacing w:after="38" w:line="245" w:line-rule="at-least"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:snapToGrid w:val="off"/><w:sz w:val="22"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Date"><w:name w:val="Date"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Date"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Subtitle"><w:name w:val="Subtitle"/><w:basedOn w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Subtitle"/><w:spacing w:after="60"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:sz w:val="24"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="SignaturePrepared"><w:name w:val="Signature:Prepared"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="SignaturePrepared"/><w:tabs><w:tab w:val="left" w:pos="0"/></w:tabs><w:spacing w:before="13" w:after="38" w:line="245" w:line-rule="at-least"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:snapToGrid w:val="off"/><w:sz w:val="22"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="SignatureSignature"><w:name w:val="Signature:Signature"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="SignatureSignature"/><w:spacing w:before="13" w:after="38" w:line="245" w:line-rule="at-least"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:snapToGrid w:val="off"/><w:sz w:val="22"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Header"><w:name w:val="header"/><wx:uiName wx:val="Header"/><w:basedOn w:val="Normal"/><w:rsid w:val="00414030"/><w:pPr><w:pStyle w:val="Header"/><w:tabs><w:tab w:val="center" w:pos="4320"/><w:tab w:val="right" w:pos="8640"/></w:tabs><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="date0"><w:name w:val="date"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="date0"/><w:tabs><w:tab w:val="left" w:pos="0"/><w:tab w:val="left" w:pos="1440"/><w:tab w:val="left" w:pos="2880"/><w:tab w:val="left" w:pos="4320"/></w:tabs><w:spacing w:line="220" w:line-rule="at-least"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:snapToGrid w:val="off"/><w:sz w:val="22"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="specno"><w:name w:val="specno"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="specno"/><w:tabs><w:tab w:val="left" w:pos="0"/><w:tab w:val="left" w:pos="1440"/><w:tab w:val="left" w:pos="2880"/><w:tab w:val="left" w:pos="4320"/></w:tabs><w:spacing w:line="220" w:line-rule="at-least"/><w:jc w:val="right"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:snapToGrid w:val="off"/><w:sz w:val="22"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="character" w:styleId="PageNumber"><w:name w:val="page number"/><wx:uiName wx:val="Page Number"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00672228"/></w:style><w:style w:type="paragraph" w:styleId="TOC1"><w:name w:val="toc 1"/><wx:uiName wx:val="TOC 1"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC1"/><w:spacing w:before="160" w:after="160"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="codeident"><w:name w:val="codeident"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="codeident"/><w:tabs><w:tab w:val="left" w:pos="0"/><w:tab w:val="left" w:pos="1440"/><w:tab w:val="left" w:pos="2880"/><w:tab w:val="left" w:pos="4320"/></w:tabs><w:spacing w:before="60" w:line="220" w:line-rule="at-least"/><w:jc w:val="right"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:snapToGrid w:val="off"/><w:sz w:val="22"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="superseding"><w:name w:val="superseding"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="superseding"/><w:tabs><w:tab w:val="left" w:pos="0"/><w:tab w:val="left" w:pos="1440"/><w:tab w:val="left" w:pos="2880"/><w:tab w:val="left" w:pos="4320"/></w:tabs><w:spacing w:before="58" w:line="220" w:line-rule="at-least"/><w:jc w:val="right"/></w:pPr><w:rPr><w:rFonts w:ascii="Palatino" w:h-ansi="Palatino"/><wx:font wx:val="Palatino"/><w:snapToGrid w:val="off"/><w:sz w:val="22"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Footer"><w:name w:val="footer"/><wx:uiName wx:val="Footer"/><w:basedOn w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Footer"/><w:tabs><w:tab w:val="center" w:pos="4320"/><w:tab w:val="right" w:pos="8640"/></w:tabs><w:jc w:val="center"/></w:pPr><w:rPr><w:rFonts w:ascii="Helvetica" w:h-ansi="Helvetica" w:cs="Arial"/><wx:font wx:val="Helvetica"/><w:sz w:val="16"/><w:sz-cs w:val="18"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TOC2"><w:name w:val="toc 2"/><wx:uiName wx:val="TOC 2"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC2"/><w:ind w:left="200"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="HCellStart"><w:name w:val="HCellStart"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="HCellStart"/><w:spacing w:before="20"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="CellBody"><w:name w:val="CellBody"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="CellBody"/><w:spacing w:before="60" w:after="60"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:lang w:val="EN-US" w:fareast="EN-US" w:bidi="AR-SA"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="HCellEnd"><w:name w:val="HCellEnd"/><w:basedOn w:val="HCellStart"/><w:next w:val="CellBody"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="HCellEnd"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TOC3"><w:name w:val="toc 3"/><wx:uiName wx:val="TOC 3"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC3"/><w:ind w:left="400"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TOC4"><w:name w:val="toc 4"/><wx:uiName wx:val="TOC 4"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC4"/><w:ind w:left="600"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TOC5"><w:name w:val="toc 5"/><wx:uiName wx:val="TOC 5"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC5"/><w:ind w:left="800"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TOC6"><w:name w:val="toc 6"/><wx:uiName wx:val="TOC 6"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC6"/><w:ind w:left="1000"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TOC7"><w:name w:val="toc 7"/><wx:uiName wx:val="TOC 7"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC7"/><w:ind w:left="1200"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TOC8"><w:name w:val="toc 8"/><wx:uiName wx:val="TOC 8"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC8"/><w:ind w:left="1400"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TOC9"><w:name w:val="toc 9"/><wx:uiName wx:val="TOC 9"/><w:basedOn w:val="Normal"/><w:next w:val="Normal"/><w:autoRedefine/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TOC9"/><w:ind w:left="1600"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableofFigures"><w:name w:val="table of figures"/><wx:uiName wx:val="Table of Figures"/><w:basedOn w:val="Caption"/><w:next w:val="Normal"/><w:semiHidden/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableofFigures"/><w:ind w:left="400" w:hanging="400"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b w:val="off"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="CellBodyCenter"><w:name w:val="CellBodyCenter"/><w:basedOn w:val="CellBody"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="CellBodyCenter"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Legend"><w:name w:val="Legend"/><w:basedOn w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Legend"/><w:spacing w:before="20"/></w:pPr><w:rPr><w:rFonts w:ascii="Helvetica" w:h-ansi="Helvetica" w:cs="Arial"/><wx:font wx:val="Helvetica"/><w:sz w:val="16"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Notes"><w:name w:val="Notes"/><w:basedOn w:val="Title"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Notes"/><w:tabs><w:tab w:val="left" w:pos="360"/><w:tab w:val="left" w:pos="720"/></w:tabs><w:ind w:left="720" w:hanging="720"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b w:val="off"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Lista"><w:name w:val="List:a"/><w:basedOn w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Lista"/><w:tabs><w:tab w:val="left" w:pos="360"/><w:tab w:val="left" w:pos="720"/><w:tab w:val="left" w:pos="1080"/></w:tabs><w:spacing w:before="80" w:after="100" w:line="268" w:line-rule="at-least"/><w:ind w:left="720" w:hanging="360"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Style1"><w:name w:val="Style1"/><w:basedOn w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Style1"/><w:tabs><w:tab w:val="left" w:pos="2520"/><w:tab w:val="left" w:pos="3960"/></w:tabs><w:spacing w:before="40" w:after="80"/><w:ind w:left="3960" w:hanging="3960"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="RefDoc"><w:name w:val="RefDoc"/><w:basedOn w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="RefDoc"/><w:tabs><w:tab w:val="left" w:pos="2520"/><w:tab w:val="left" w:pos="3960"/></w:tabs><w:spacing w:before="60" w:after="60"/><w:ind w:left="3960" w:hanging="3960"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="list1"><w:name w:val="list:1"/><w:basedOn w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="list1"/><w:tabs><w:tab w:val="left" w:pos="360"/><w:tab w:val="left" w:pos="720"/><w:tab w:val="left" w:pos="1080"/></w:tabs><w:spacing w:before="60" w:after="100"/><w:ind w:left="1080" w:hanging="360"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Note"><w:name w:val="Note"/><w:basedOn w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Note"/><w:tabs><w:tab w:val="left" w:pos="720"/></w:tabs><w:spacing w:before="60" w:after="60"/><w:ind w:left="1080" w:hanging="720"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Acronym"><w:name w:val="Acronym"/><w:basedOn w:val="Normal"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Acronym"/><w:tabs><w:tab w:val="left" w:pos="2880"/></w:tabs><w:spacing w:before="60" w:after="60"/><w:ind w:left="3600" w:hanging="2880"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="CellTitle"><w:name w:val="CellTitle"/><w:basedOn w:val="CellBody"/><w:autoRedefine/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="CellTitle"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="LegendTitle"><w:name w:val="LegendTitle"/><w:basedOn w:val="Legend"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="LegendTitle"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Helvetica"/><w:b/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="LegendCenterd"><w:name w:val="LegendCenterd"/><w:basedOn w:val="Legend"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="LegendCenterd"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Helvetica"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="LegendCenterdItalic"><w:name w:val="LegendCenterdItalic"/><w:basedOn w:val="LegendCenterd"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="LegendCenterdItalic"/></w:pPr><w:rPr><wx:font wx:val="Helvetica"/><w:i/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableofTables"><w:name w:val="Table of Tables"/><w:basedOn w:val="TableTitle"/><w:next w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableofTables"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b w:val="off"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="list10"><w:name w:val="list:1)"/><w:basedOn w:val="lista0"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="list10"/><w:ind w:left="1800"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="lista0"><w:name w:val="list:a)"/><w:basedOn w:val="list1"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="lista0"/><w:ind w:left="1440"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="CellTitleCenter"><w:name w:val="CellTitleCenter"/><w:basedOn w:val="CellTitle"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="CellTitleCenter"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="HCellBody"><w:name w:val="HCellBody"/><w:basedOn w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="HCellBody"/><w:jc w:val="left"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:sz w:val="20"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="HCellBodyCenter"><w:name w:val="HCellBodyCenter"/><w:basedOn w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="HCellBodyCenter"/><w:jc w:val="left"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:sz w:val="20"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithLinesRightJustify"><w:name w:val="TableWithLines:RightJustify"/><w:basedOn w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithLinesRightJustify"/><w:jc w:val="left"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:sz w:val="20"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithLinesNotes"><w:name w:val="TableWithLines:Notes"/><w:basedOn w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithLinesNotes"/><w:jc w:val="left"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:sz w:val="20"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithLinesLeftJustify"><w:name w:val="TableWithLines:LeftJustify"/><w:basedOn w:val="HCellEnd"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithLinesLeftJustify"/><w:jc w:val="left"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b w:val="off"/><w:sz w:val="22"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Ltxt"><w:name w:val="Ltxt"/><w:basedOn w:val="Normal"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="Ltxt"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="listaleadtab"><w:name w:val="list:a:leadtab"/><w:basedOn w:val="HCellEnd"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="listaleadtab"/><w:ind w:left="720"/><w:jc w:val="left"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b w:val="off"/><w:sz w:val="22"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithLinesCenterJustify"><w:name w:val="TableWithLines:CenterJustify"/><w:basedOn w:val="HCellEnd"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithLinesCenterJustify"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b w:val="off"/><w:sz w:val="22"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithoutLinesRightJustify"><w:name w:val="TableWithoutLines:RightJustify"/><w:basedOn w:val="HCellEnd"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithoutLinesRightJustify"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b w:val="off"/><w:sz w:val="22"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithoutLinesLeftJustify"><w:name w:val="TableWithoutLines:LeftJustify"/><w:basedOn w:val="HCellEnd"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithoutLinesLeftJustify"/><w:jc w:val="left"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b w:val="off"/><w:sz w:val="22"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithoutLinesCenterJustify"><w:name w:val="TableWithoutLines:CenterJustify"/><w:basedOn w:val="HCellEnd"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithoutLinesCenterJustify"/></w:pPr><w:rPr><w:rFonts w:ascii="Symbol" w:h-ansi="Symbol"/><wx:font wx:val="Symbol"/><w:b w:val="off"/><w:sz w:val="22"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithLineshdr"><w:name w:val="TableWithLines:hdr"/><w:basedOn w:val="Ltxt"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithLineshdr"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:sz w:val="20"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="lista1"><w:name w:val="list:a"/><w:basedOn w:val="Lista"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="lista1"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="TableWithoutLineshdr"><w:name w:val="TableWithoutLines:hdr"/><w:basedOn w:val="Ltxt"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="TableWithoutLineshdr"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="CenterNoSpaceAbove"><w:name w:val="CenterNoSpaceAbove"/><w:basedOn w:val="Ltxt"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="CenterNoSpaceAbove"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="LeftNoSpaceAbove"><w:name w:val="LeftNoSpaceAbove"/><w:basedOn w:val="list1"/><w:rsid w:val="00672228"/><w:pPr><w:pStyle w:val="LeftNoSpaceAbove"/><w:tabs><w:tab w:val="clear" w:pos="360"/><w:tab w:val="clear" w:pos="720"/><w:tab w:val="clear" w:pos="1080"/></w:tabs><w:ind w:left="0" w:first-line="0"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="DetChg"><w:name w:val="DetChg"/><w:basedOn w:val="Normal"/><w:rsid w:val="00D735A0"/><w:pPr><w:pStyle w:val="DetChg"/><w:jc w:val="left"/></w:pPr><w:rPr><w:rFonts w:ascii="Arial" w:h-ansi="Arial"/><wx:font wx:val="Arial"/><w:b/><w:snapToGrid w:val="off"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Figure"><w:name w:val="Figure"/><w:basedOn w:val="Normal"/><w:rsid w:val="00690498"/><w:pPr><w:pStyle w:val="Figure"/><w:spacing w:before="240" w:after="240"/><w:jc w:val="center"/></w:pPr><w:rPr><w:rFonts w:fareast="MS Mincho"/><wx:font wx:val="Times New Roman"/><w:sz-cs w:val="24"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="Coverpagetitle1"><w:name w:val="Coverpage title #1"/><w:basedOn w:val="Normal"/><w:rsid w:val="00690498"/><w:pPr><w:pStyle w:val="Coverpagetitle1"/><w:widowControl w:val="off"/><w:autoSpaceDE w:val="off"/><w:autoSpaceDN w:val="off"/><w:adjustRightInd w:val="off"/><w:spacing w:after="240"/><w:jc w:val="center"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:b/><w:b-cs/><w:sz w:val="36"/><w:sz-cs w:val="36"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="HeaderRight"><w:name w:val="Header+Right"/><w:basedOn w:val="Header"/><w:rsid w:val="00864C5A"/><w:pPr><w:pStyle w:val="HeaderRight"/><w:jc w:val="right"/></w:pPr><w:rPr><wx:font wx:val="Times New Roman"/><w:lang w:val="FR"/></w:rPr></w:style><w:style w:type="character" w:styleId="Hyperlink"><w:name w:val="Hyperlink"/><w:basedOn w:val="DefaultParagraphFont"/><w:rsid w:val="00BF241C"/><w:rPr><w:color w:val="0000FF"/><w:u w:val="single"/></w:rPr></w:style><w:style w:type="paragraph" w:styleId="BalloonText"><w:name w:val="Balloon Text"/><w:basedOn w:val="Normal"/><w:semiHidden/><w:rsid w:val="00A86EC4"/><w:pPr><w:pStyle w:val="BalloonText"/></w:pPr><w:rPr><w:rFonts w:ascii="Tahoma" w:h-ansi="Tahoma" w:cs="Tahoma"/><wx:font wx:val="Tahoma"/><w:sz w:val="16"/></w:rPr></w:style></w:styles><w:docOleData><w:binData w:name="oledata.mso">0M8R4KGxGuEAAAAAAAAAAAAAAAAAAAAAPgADAP7/CQAGAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAA
+EAAAAgAAAAEAAAD+////AAAAAAAAAAD/////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////9
+/////v////7///8EAAAABQAAAAYAAAAHAAAACAAAAAkAAAAKAAAACwAAAAwAAAANAAAADgAAAA8A
+AAAQAAAAEQAAABIAAAD+////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////1IA
+bwBvAHQAIABFAG4AdAByAHkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAWAAUA//////////8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALDGkpaSI8sB
+AwAAAAAfAAAAAAAAXwAxADMANAAwADYAMQA5ADAAMwA3AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAABgAAgH/////AgAAAP////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAcw8AAAAAAABfADEAMwA0ADAANgAxADkAMAAzADgAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGAACAP///////////////wAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD4AAABzDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////////
+////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAA
+AAIAAAADAAAABAAAAAUAAAAGAAAABwAAAAgAAAAJAAAACgAAAAsAAAAMAAAADQAAAA4AAAAPAAAA
+EAAAABEAAAASAAAAEwAAABQAAAAVAAAAFgAAABcAAAAYAAAAGQAAABoAAAAbAAAAHAAAAB0AAAAe
+AAAAHwAAACAAAAAhAAAAIgAAACMAAAAkAAAAJQAAACYAAAAnAAAAKAAAACkAAAAqAAAAKwAAACwA
+AAAtAAAALgAAAC8AAAAwAAAAMQAAADIAAAAzAAAANAAAADUAAAA2AAAANwAAADgAAAA5AAAAOgAA
+ADsAAAA8AAAAPQAAAP7///8/AAAAQAAAAEEAAABCAAAAQwAAAEQAAABFAAAARgAAAEcAAABIAAAA
+SQAAAEoAAABLAAAATAAAAE0AAABOAAAATwAAAFAAAABRAAAAUgAAAFMAAABUAAAAVQAAAFYAAABX
+AAAAWAAAAFkAAABaAAAAWwAAAFwAAABdAAAAXgAAAF8AAABgAAAAYQAAAGIAAABjAAAAZAAAAGUA
+AABmAAAAZwAAAGgAAABpAAAAagAAAGsAAABsAAAAbQAAAG4AAABvAAAAcAAAAHEAAAByAAAAcwAA
+AHQAAAB1AAAAdgAAAHcAAAB4AAAAeQAAAHoAAAB7AAAA/v////////////////////////8AZgAA
+eJztnHtsVUd+x39zHtf3+voNMX7hGEOwsU3KEgiGoF0SCGDIQrrhlahVMWBsEz9YvyDdqutNgETZ
+qjLYsG0VdQ04UtWuggP8UzUBO1lVbRPAptlqV4HgSBtVagjcpOluCeDb729mzr3H1xf8SDY02vO7
++tzzmHPmNzNnfjO/OTP3DlxIHzr6es6HFCPfJpOGwwHyuc4JjZQ0okx9PBwOh53TYU++UXIbZOG5
+mcACNuBnngD8IAASQRAkgWSQAlJVFaB0kAGmgKngPl0f3OTgXC7IA9NBPrgfFIAZ+vqZ2M4CD4DZ
+oAgUgzk6vBTbMjAXPAj+AMwD39LhnkxOvkeN+LTgWTxODdg20XOxTcFdJRM1xonL4HoTMOT5PhW8
+0n1tX/Avjxya+Y6YFg3H89tAlbSN6qhqQnodSSFDuPMznns4hTtmq31By5H/etpN65GKXRPWnwH9
+3Aay7YxXP0uj3ppabwVKf2fk7MT0Tyb/Trt+wJiKOAS9Aou2IldYce/zxJPflZQTLfsULUi57GWU
++GgdLKIJ1lmJ9kHV2zT6k9XCql8dsJpBCxgd1wp6lD4LH8U2KeKuZOKoChZWSa2Ii9u7J7HfBKrl
+926qwbmV0MetIMsmqqX/Dp/CNsl2YklytVYFMakroCWbgjTtN+hJF/yHj4Tt7CSadVTJpw3ZixbT
+s/R5uJ97t0i8CTKuAnoCOpulfkOXQwsNp34a/gzbaLlY0NcGuO8rg936Zonkf05ho+22lwWHuFum
+9H01ImMH539Kz0Ka2tNBW3HmAVro/9Ej/h8tX5NJ69eY9IeAy7PGTyOKtEFqNURDHK3ziXvpNLqL
+yqk9/yPVkdT37RIxlr69Ul+G2OvSlxDRN1s+Fe7z08mcZY4zr5WzTHgZY2neJTUXil1xcvqQzGnG
+uHJayDkdQ5kq1flxS3WB1DXlKy1VFvbfgspVk/2T7KsKeF/Qsk1vR9IRGGVFXFfZve+AW9a2xIic
++yvemaeuiZhXaOR9L3U4V7iumacP0fUE/Lry632fa589T3iXoTp5uS/E3qnhV9afSNFRCOu5n0SI
+vcL5lBBi79G01q3aGnz579PMw/vrF2zdknc0TCe0lTm94zLK/zRNHqvz7e3t9FsuoVQyQv+WzXv+
+UMT1tTgxZqgmm7dWqFgqD4TSRhUXJzBR3sfPzyZ1/Sw7et60VA7+nYKhz7H/mNiALC8Xb+J7heDA
+x/ufQC5X9m/A9w/hVgg6Kzg9fbIMfy6/3xHvdRGdk/vn5XdYZFEWdeITQpYOi9vGm75e65x91jpj
+X7ZOSG5a3XaifVCSLXneLtbssDdKmu2Vkucli3AVUyzplmTbJyIk2mcQ6znJVeuS5LL1seS85qz1
+haTXCviOag5JsnwvaFqsIl8V2CR52DfHetwX1NwyFZ+ADzQXzA2+Ps3rmmOgE7SCnWAzWI1rF4MS
+TS5I0lwzmId9V8AA6AcnjSLfcdAlyfK1gWqwxQj4KsAS4wu7FOQZH9vJYFhcsq+DIck5exC8Jc7Y
+p0CP6Lb3iIN2jXjeflo022Vihz1dbLRTxCI7RMX2h5RtX6RE+zTdtF6lq9YROm+9SL1WLR2ynqEW
+ay1VWUtpEyi35tIcK59ywC0zlT4BH4ALoA9dyuvgGOgE+8BmsBosBiUgF9ddM1LpChgw8qkfHDfm
+0n7QZiylarDFWEsVIM94hpKNWhpGM8z1qEgUC4Pt5WeoZh4eXxpqR2sW4pYuQbaY6XJf6LbyXTPa
+VlqutvIVk9tKruHLRY4VbSu7BbeVfycm3lbW4MNt5UX0W0slYZpLKWIulYl8ySNgjSSVngY1mj3g
+ADgsSNIDTmneAoMIu65Jhq3lgVLYGlMBW6uQ9qZsrhq0webaYHNdxl7JceNFOmkcAa/CVpnTsNu3
+Yb/MRdjyhyBEtyVh2HeZKDGfFovNGslqcw84IDabPeCU2Gm+pRkUreZ1MCzZZyYb+8w8UAqWgAqw
+RdJpVoMu7DPHwUlNv6TVvKK5Jtlp3tYkmZvNXHO1WQIW6w8f8VmGr+ArW8E+3LkPsXRKBkC/cQxa
+jplD8ilfpEF6j7z25/87UZv2xbHpHYGoTdsum14QYJtemMA2fcPl/9RZbNMt1sRtOlfkCrbpQfg/
+N+A9bEfvXmXdMvvMoPW6JEczxzpmlrtYZXVKNmmqNC2SfZIXNIfAUU0vwt2cdXE+wjHzsuYqdDvc
+tPokiTZzQZJtf6D5xCy2b0kW2UFLkWMdtI9G6IZPxZyAn+XA3t5IrkY4N4KbES7Bj2M+hk/HfCEp
+HkHA57BoFAsTDlnTEqosfww3fG42RfivOLwvWSV5dwTlEd6MMGcUr/lyYghKfgrfUfGJ2aF5GL7h
+w/ANiySLJVnwDx0C8BMD8BG/sJnbBvOxfU1zxbikOWcPuOg3zrg4YZ+UdIOD9nHJ86DZ7pLscLFR
+s1Ky31gEil1kg0TNVatLs9+4GaENYdWaLbieqcC9S0ApyJMskiRrhoXiOhjSDIJToEdzWHNAs0dT
+I4rh0xbba1w8IrLh4yqmSxLh6yrCxNy0QpoP4e9eBG/TZeu05Dx84PPwgc9K2A9m9tJR6Q8rn/gF
+yVrpG7do33gTfONy+MXKP06VBMEt6SOT5ALo0zi+suMvt2p2Sr85FX6zYjHINfMpCVxBvz0gWYq+
+eCn65bWyv+Z2ZpFRbnj9k4eHx9dD1Ney4/hada7xk8/lay2V46cug32tCiPqa+0W7GvtFRP3tf4I
+H/a1QhgfzZXUYKzE7ImgxkkHIuOlKM5YSY2XiIY0111jp+EYko1UOZZy44yrlkRYKlHjLPVOY4vk
+mQjVaLsVeyVtkhc1RyT7Me7aj3EX04UxVxfGXIpQhP0Ye40kRUSZrikTbSN4RFRL1kgqjJoISyR7
+JKUgzzggko3DYlgcFm8TP7UQ/SO94Y2H7qHNWXFs7j3Xe98El831ENtckS92fMMvqVf28yvridpc
+AB+2udOUghhLjQ2+IXhaQesDjB16rSL4u2Xy6tM0haaOs55E82bGydvPXHnzu/L2ZzJvebI96Xe1
+J2kyb1mTyJuFT0i+js8zhsQR6pezDQFKipOPaJqNOGn+tSvNAVeaT8s037Q4zSsSomkuk2leMIk0
+B/HhNOcZt40VCbfM13wnjRbrplWC8WKFscToNA/AynPg83aaKmfTcNfE7DeaVzFG3UscVfe6bc7r
+a19p3atGK7nZzDOqjUMYYXXbPGIaFL3I4xxpHNXGZOoexcnbY8RLG1TeZPJTiJ5C3njpkEr3Ozp9
+vEzJMnmu5jumkPenu0pMbQ2Kv8DJmeH57TRoTSX6yXSiN+8jPQHM9ad4KlFXOtHMbKJfZjkhbA18
+dlsmUe8UFapCuA3YA0PIQix/i9D0PCeEe+QfB4n+E7Hcj9zMy3VC+L3Ib5CUf0IqShHr6XwnhN+C
+NiGxBmKx8XTzCpwQnku6DD7KIfoWYj02wwlhCZLzhjV2z9ClwOX6kauEfvnHlVQa/AGFl1G7iMTT
+k7XeJ6ITeBExnOkvLsBefhrL1Iwiq9hIDfQsaKQ9+Oazftet6io1+2boOTj3PiduVWYHLjIMn2lb
+tmFaL/4pIePU7sSjo6ANVEv1VEXNxHPxVdBXQN+Tq3kq5XzxQsRjkG0LQyT4DDtB3+6eu2vnr6fo
+OdyzDXfynONDs6X2oM8yWO6o/VFqgn419/9UBu5xTaGaMQXmFOGT8vpKPKpaWUIwVLn+6lmoeFSu
+PKil71MrriAqRFnM87+URaEBPLUaGcUPHhpc2Q7kQ4jELI1E7llkpolRZx3tM0yKO3HpyXjkVV9f
+wml0r+3UtGBkiF/zZYSf5gr5SMVDL6Tzc7pyJbYWuWX1Fv6eEwqn4hl/h+jXlpzh/uGdYONmmT8q
+pnA4I+ZMMm2Xa2PYthpQM+vkUbNchZFKa+VRLanVKm2yJlfLVStqlYYn3yThtsFZp+vJ758IPH0z
+Ua2OiV27y87Wd2u3NzU2N+5sKVi/c2ft9qqCzY1NOwqerN3e0tpUJdfjfPcpPrWicbtcE877D+rg
+B8vp88Unvz9GDTTjOBiefF2yWa5h3EErsN0Oz0O1+S1j36glBz0X91PsVnMdGs898JapRDsiNrwv
+1love5XnIuug1bpK9ofu3qsU6/XPvgnoL+SviP7YnE8sPeXSc43KePSXuPR/FTJR/W65+mo/PbCV
+hzqhjLPqlEqZXo2XQtt2bdu1bmjd0Oh7A1amfI5lLwvJ6DWEselMHXPfkR75fUmv3eOte/9O26mu
+GDJ96rhJL3WPt+V1mH+utyX6fAeqRyKapCP6eKzt4Iz429RC5dWlF6rj8Wx5iP43M+Ht40ZjNgaY
+OF5YqH5VEytOvh19sXK5gOjzu6RvYWH8+Jytkz9H+HgVhptrCtUvv67reGK3Tvyx8cQep8bov36H
+fIwl7vK+W3zXY9J1yaYvJU58Tn5e1vVo4P2Pzjy6+18jnVqTq54kxkmXk+6thWqJbEfhyPidX6q8
+r+93jidbXncSJ15HnPJhPQU0uv7EPu871cNYGas+xtbLO8lHujwmq88p5zuFx+bHaR/cW7bXdXob
+L5x0OEtIt0+WT/2CLsOn3naMp11zb51W3nD9usETTyYnfi3J9zohntwb8XEdUL7eZ9fudWI8+SrF
+l1kjX/vlmPJ3repoo1/UryarAbT6heH4+bfvdWI9+bpFTQ14z//3VCyLhBDFdH9v37oCMKM3675C
+MLMjLWUWeKCXaFrvgJEFkjoGjHudXk9+FzKMsYQtRj9cbhyG9v/0sxvra9L+4aCfSotO/YpHp7xc
+LF2Hd5B6w8G/COV3gPzOhkc0qDjyfeC/kJpq54UKPPk6RGqejH8syu+K/EL9d8hUoUZyC4QaQS8T
+6n9GnhBqpLRFqP8b2SrUyymeC+X/G+EFbKyf577yKfqvBbH7fM/2yqb6qoaCusqm5saGONe49zmN
+6xqb6ivrovevrWyqLXiitq22obq5BTE498zX9/Cyl7jvyjk/rnKV+4+l/zW/IZD7L733Bu+bukzd
+Wz+Nnkn2xBNPPPHEE0888cQTTzzxxJPJyN3G/8Yvzv3ilQdz0zp/gvF/2Y3XePz/v6TG6BxeQ2pc
+vpvUeP8vSI33u0i9I3gF8H898nsBXn7OPyjhsTT/GIPH72+QWknwc1Lj/Xd13L+ikeN6njXdUFNV
+8FhjFYbfBcsb63dXNjw3cqwcO2ZOLQqqf7DSuuNt89Nc/2mblKaU5utMbKhtqauKRO2JJ5544okn
+nnjiiSeeeOKJJ99o+T8Qn5NCAAAAAAAAAAAAAAAAAABmAAB4nO2ca3BUR3bHT9/HaEajN1johSwE
+RkISDovBCEztYoMBgRecNS+7kgoChCSsB6sXOLuV1dqAXd58EEiwScqVFSBXpZItIwNfUrFBsrdS
+SWxAIt7UbhmMXLWuVMUYxo6zGwxo8j/dfWeuRgN62Gvi2numfnMffW+f7r59uk/f7pmBC+lDR1/P
++ZBi5Ntk0nA4QD7XOaGRkkaUqY+Hw+GwczrsyTdKboMsPDcTWMAG/MwTgB8EQCIIgiSQDFJAqqoC
+lA4ywBQwFdyn64ObHJzLBXlgOsgH94MCMENfPxPbWeABMBsUgWIwR4eXYlsG5oIHwR+BeeBbOtyT
+ycn3qBGfFjyLx6kB2yZ6LrYpuKtkosY4cRlcbwKGPN+ngle6r+37YceRQzPfEdOi4Xh+G6iStlEd
+VU1IryMpZAh3fsZzD6dwx2y1L2g58l9Pu2k9UrFrwvozoJ/bQLad8epnadRbU+utQOnvjJydmP7J
+5N9p1w8YUxGHoFdg0VbkCivufZ548vuScqJln6IFKZe9jBIfrYNFNME6K9E+qHqbRn+2Wlj1qwNW
+M2gBo+NaQY/SZ+Gj2CZF3JVMHFXBwiqpFXFxe/ck9ptAtfzeTTU4txL6uBVk2US19N/hU9gm2U4s
+Sa7WqiAmdQW0ZFOQpv0WPemC//CRsJ2dRLOOKvm0IXvRYnqWPg/3c+8WiTdBxlVAT0Bns9Rv6HJo
+oeHUT8OfYRstFwv62gD3fWWwW98skfzPKWy03fay4BB3y5S+r0Zk7OD8T+lZSFN7OmgrzjxAC/0/
+fsT/4+VrMmn9GpP+GHB51vhpRJE2SK2GaIijdT5xL51Gd1E5ted/pDqS+r5dIsbSt1fqyxB7XfoS
+Ivpmy6fCfX46mbPMcea1cpYJL2Mszbuk5kKxK05OH5I5zRhXTgs5p2MoU6U6P26pLpC6pnylpcrC
+/ltQuWqyf5J9VQHvC1q26e1IOgKjrIjrKrv3HXDL2pYYkXN/xTvz1DUR8wqNvO+lDucK1zXz9CG6
+noBfV36973Pts+cJ7zJUJy/3hdg7NfzK+hMpOgphPfeTCLFXOJ8SQuw9mta6VVuDL/99mnl4f/2C
+rVvyjobphLYyp3dcRvmfpsljdb69vZ1+xyWUSkbo37J5zx+KuL4WJ8YM1WTz1goVS+WBUNqo4uIE
+Jsr7+PnZpK6fZUfPm5bKwb9TMPQ59h8TG5Dl5eJNfK8QHPh4/xPI5cr+Dfj+EdwKQWcFp6dPluEv
+5Pc74r0uonNy/7z8DossyqJOfELI0mFx23jT12uds89aZ+zL1gnJTavbTrQPSrIlz9vFmh32Rkmz
+vVLyvGQRrmKKJd2SbPtEhET7DGI9J7lqXZJctj6WnNectb6Q9FoB31HNIUmW7wVNi1XkqwKbJA/7
+5liP+4KaW6biE/CB5oK5wdeneV1zDHSCVrATbAarce1iUKLJBUmaawbzsO8KGAD94KRR5DsOuiRZ
+vjZQDbYYAV8FWGJ8YZeCPONjOxkMi0v2dTAkOWcPgrfEGfsU6BHd9h5x0K4Rz9tPi2a7TOywp4uN
+dopYZIeo2P6Qsu2LlGifppvWq3TVOkLnrRep16qlQ9Yz1GKtpSprKW0C5dZcmmPlUw64ZabSJ+AD
+cAH0oUt5HRwDnWAf2AxWg8WgBOTiumtGKl0BA0Y+9YPjxlzaD9qMpVQNthhrqQLkGc9QslFLw2iG
+uR4ViWJhsL38HNXMw+NLQ+1ozULc0iXIFjNd7gvdVr5rRttKy9VWvmJyW8k1fLnIsaJtZbfgtvLv
+xMTbyhp8uK28iH5rqSRMcylFzKUykS95BKyRpNLToEazBxwAhwVJesApzVtgEGHXNcmwtTxQCltj
+KmBrFdLelM1VgzbYXBtsrsvYKzluvEgnjSPgVdgqcxp2+zbsl7kIW/4QhOi2JAz7LhMl5tNisVkj
+WW3uAQfEZrMHnBI7zbc0g6LVvA6GJfvMZGOfmQdKwRJQAbZIOs1q0IV95jg4qemXtJpXNNckO83b
+miRzs5lrrjZLwGL94SM+y/AVfGUr2Ic79yGWTskA6DeOQcsxc0g+5Ys0SO+R1/78fydq0744Nr0j
+ELVp22XTCwJs0wsT2KZvuPyfOottusWauE3nilzBNj0I/+cGvIft6N2rrFtmnxm0XpfkaOZYx8xy
+F6usTskmTZWmRbJP8oLmEDiq6UW4m7Muzkc4Zl7WXIVuh5tWnyTRZi5Isu0PNJ+YxfYtySI7aCly
+rIP20Qjd8KmYE/CzHNjbG8nVCOdGcDPCJfhxzMfw6ZgvJMUjCPgcFo1iYcIha1pCleWP4YbPzaYI
+/xWH9yWrJO+OoDzCmxHmjOI1X04MQcnP4DsqPjE7NA/DN3wYvmGRZLEkC/6hQwB+YgA+4hc2c9tg
+Pravaa4YlzTn7AEX/cYZFyfsk5JucNA+LnkeNNtdkh0uNmpWSvYbi0Cxi2yQqLlqdWn2GzcjtCGs
+WrMF1zMVuHcJKAV5kkWSZM2wUFwHQ5pBcAr0aA5rDmj2aGpEMXzaYnuNi0dENnxcxXRJInxdRZiY
+m1ZI8yH83YvgbbpsnZachw98Hj7wWQn7wcxeOir9YeUTvyBZK33jFu0bb4JvXA6/WPnHqZIguCV9
+ZJJcAH0ax1d2/OVWzU7pN6fCb1YsBrlmPiWBK+i3ByRL0RcvRb+8VvbX3M4sMsoNr3/y8PD4eoj6
+WnYcX6vONX7yuXytpXL81GWwr1VhRH2t3YJ9rb1i4r7Wn+DDvlYI46O5khqMlZg9EdQ46UBkvBTF
+GSup8RLRkOa6a+w0HEOykSrHUm6ccdWSCEslapyl3mlskTwToRptt2KvpE3youaIZD/GXfsx7mK6
+MObqwphLEYqwH2OvkaSIKNM1ZaJtBI+IaskaSYVRE2GJZI+kFOQZB0SycVgMi8PibeKnFqJ/pDe8
+8dA9tDkrjs2953rvm+CyuR5imyvyxY5v+CX1yn5+ZT1RmwvgwzZ3mlIQY6mxwTcETytofYCxQ69V
+BH+3TF59mqbQ1HHWk2jezDh5+7krb35X3n4o85Yn25N+V3uSJvOWNYm8WfiE5Ov4PGNIHKF+OdsQ
+oKQ4+Yim2YiT5t+40hxwpfm0TPNNi9O8IiGa5jKZ5gWTSHMQH05znnHbWJFwy3zNd9JosW5aJRgv
+VhhLjE7zAKw8Bz5vp6lyNg13Tcx+o3kVY9S9xFF1r9vmvL72lda9arSSm808o9o4hBFWt80jpkHR
+izzOkcZRbUym7lGcvD1GvLRB5U0mP4XoKeSNlw6pdL+j08fLlCyT52q+Ywp5f7qrxNTWoPgLnJwZ
+nt9Ng9ZUop9OJ3rzPtITwFx/iqcSdaUTzcwm+lWWE8LWwGe3ZRL1TlGhKoTbgD0whCzE8rcITc9z
+QrhH/kmQ6D8Ry/3IzbxcJ4Tfi/wWSfknpKIUsZ7Od0L4LWgTEmsgFhtPN6/ACeG5pMvgoxyibyHW
+YzOcEJYgOW9YY/cMXQpcrh+5SuhXf1pJpcEfUHgZtYtIPD1Z630iOoEXEcOZ/uIC7OWnsUzNKLKK
+jdRAz4JG2oNvPut33aquUrNvhp6Dc+9z4lZlduAiw/CZtmUbpvXinxMyTu1OPDoK2kC1VE9V1Ew8
+F18FfQX0Pbmap1LOFy9EPAbZtjBEgs+wE/Tt7rm7dv56ip7DPdtwJ885PjRbag/6LIPljtofpSbo
+V3P/T2XgHtcUqhlTYE4RPimvr8SjqpUlBEOV66+ehYpH5cqDWvo+teIKokKUxTz/S1kUGsBTq5FR
+/OChwZXtQD6ESMzSSOSeRWaaGHXW0T7DpLgTl56MR1719SWcRvfaTk0LRob4NV9G+GmukI9UPPRC
+Oj+nK1dia5FbVm/h7zmhcCqe8XeIfmPJGe4f3Qk2bpb5o2IKhzNiziTTdrk2hm2rATWzTh41y1UY
+qbRWHtWSWq3SJmtytVy1olZpePJNEm4bnHW6nvzhicDTNxPV6pjYtbvsbH23dntTY3PjzpaC9Tt3
+1m6vKtjc2LSj4Mna7S2tTVVyPc53n+JTKxq3yzXhvP+gDn6wnD5ffPL7Y9RAM46D4cnXJZvlGsYd
+tALb7fA8VJvfMvaNWnLQc3E/xW4116Hx3ANvmUq0I2LD+2Kt9bJXeS6yDlqtq2R/6O69SrFe/+yb
+gP5C/oroj835xNJTLj3XqIxHf4lL/1chE9Xvlquv9tMDW3moE8o4q06plOnVeCm0bde2XeuG1g2N
+vjdgZcrnWPaykIxeQxibztQx9x3pkd+X9No93rr377Sd6ooh06eOm/RS93hbXof5F3pbos93oHok
+okk6oo/H2g7OiL9NLVReXXqhOh7PlofofzMT3j5uNGZjgInjhYXqVzWx4uTb0RcrlwuIPr9L+hYW
+xo/P2Tr5c4SPV2G4uaZQ/fLruo4nduvEHxtP7HFqjP7rd8jHWOIu77vFdz0mXZds+lLixOfk52Vd
+jwbe/+jMo7v/NdKpNbnqSWKcdDnp3lqolsh2FI6M3/mlyvv6fud4suV1J3HidcQpH9ZTQKPrT+zz
+vlM9jJWx6mNsvbyTfKTLY7L6nHK+U3hsfpz2wb1le12nt/HCSYezhHT7ZPnUL+gyfOptx3jaNffW
+aeUN168bPPFkcuLXknyvE+LJvREf1wHl63127V4nxpOvUnyZNfK1X44pf9eqjjb6Rf1qshpAq18Y
+jp9/+14n1pOvW9TUgPf8/0DFskgIUUz39/atKwAzerPuKwQzO9JSZoEHeomm9Q4YWSCpY8C41+n1
+5PchwxhL2GL0w+XGYWj/zz67sb4m7R8O+qm06NSveXTKy8XSdXgHqTcc/ItQfgfI72x4RIOKI98H
+/gupqXZeqMCTr0Ok5sn4x6L8rsgv1H+HTBVqJLdAqBH0MqH+Z+QJoUZKW4T6v5GtQr2c4rlQ/r8R
+XsDG+nnuK5+i/1oQu8/3bK9sqq9qKKirbGpubIhzjXuf07iusam+si56/9rKptqCJ2rbahuqm1sQ
+g3PPfH0PL3uJ+66c8+MqV7n/WPpf8xsCuf/Se2/wvqnL1L310+iZZE888cQTTzzxxBNPPPHEE088
+mYzcbfxv/PLcL195MDet86cY/5fdeI3H//9LaozO4TWkxuW7SY33/5LUeL+L1DuCVwD/1yO/F+Dl
+5/yDEh5L848xePz+BqmVBL8gNd5/V8f9axo5rudZ0w01VQWPNVZh+F2wvLF+d2XDcyPHyrFj5tSi
+oPoHK6073jY/zfWftklpSmm+zsSG2pa6qkjUnnjiiSeeeOKJJ5544oknnnjyjZb/A+grk7UAAQAA
+AMwSHAAWAAAACgAAAAQAAAADAAAABAAAAAIAAADJEgAAuPp8UQoAAAAEAAAABQAAAAAAAAACAAAA
+yhIAALj6YFEKAAAAAAAAAAAAAAABAAAAAQAAAMsSAAC4+kRRCgAAAAQAAAABAAAAAAAAAAEAAADN
+EgAAuPooUQoAAAAEAAAAAwAAAAQAAAACAAAAzhIAALj6DFEKAAAABAAAAAUAAAAAAAAAAgAAAM8S
+AAC4+vBQCgAAAAQAAAADAAAABAAAAAIAAADQEgAAuPrUUAoAAAAEAAAABQAAAAAAAAACAAAA0RIA
+ALj6uFAKAAAABAAAAAMAAAAEAAAAAgAAANISAAC4+pxQCgAAAA==
+</w:binData></w:docOleData><w:shapeDefaults><o:shapedefaults v:ext="edit" spidmax="15362"/><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="1"/></o:shapelayout></w:shapeDefaults><w:docPr><w:view w:val="print"/><w:zoom w:percent="100"/><w:doNotEmbedSystemFonts/><w:mirrorMargins/><w:attachedTemplate w:val="\\sw\mes\SE-RQMT_DB\SLATE_Templates\ExportTemplateBlockIII_PRF_LRIP.dot"/><w:defaultTabStop w:val="720"/><w:evenAndOddHeaders/><w:displayHorizontalDrawingGridEvery w:val="0"/><w:displayVerticalDrawingGridEvery w:val="0"/><w:useMarginsForDrawingGridOrigin/><w:characterSpacingControl w:val="DontCompress"/><w:optimizeForBrowser/><w:validateAgainstSchema/><w:saveInvalidXML w:val="off"/><w:ignoreMixedContent w:val="off"/><w:alwaysShowPlaceholderText w:val="off"/><w:hdrShapeDefaults><o:shapedefaults v:ext="edit" spidmax="15362"/><o:shapelayout v:ext="edit"><o:idmap v:ext="edit" data="2"/></o:shapelayout></w:hdrShapeDefaults><w:footnotePr><w:footnote w:type="separator"><w:p wsp:rsidR="00D5100D" wsp:rsidRDefault="00D5100D" wsp:rsidP="00414030"><w:r><w:separator/></w:r></w:p></w:footnote><w:footnote w:type="continuation-separator"><w:p wsp:rsidR="00D5100D" wsp:rsidRDefault="00D5100D" wsp:rsidP="00414030"><w:r><w:continuationSeparator/></w:r></w:p></w:footnote></w:footnotePr><w:endnotePr><w:endnote w:type="separator"><w:p wsp:rsidR="00D5100D" wsp:rsidRDefault="00D5100D" wsp:rsidP="00414030"><w:r><w:separator/></w:r></w:p></w:endnote><w:endnote w:type="continuation-separator"><w:p wsp:rsidR="00D5100D" wsp:rsidRDefault="00D5100D" wsp:rsidP="00414030"><w:r><w:continuationSeparator/></w:r></w:p></w:endnote></w:endnotePr><w:compat><w:ww6BorderRules/><w:footnoteLayoutLikeWW8/><w:shapeLayoutLikeWW8/><w:alignTablesRowByRow/><w:forgetLastTabAlignment/><w:doNotUseHTMLParagraphAutoSpacing/><w:layoutRawTableWidth/><w:layoutTableRowsApart/><w:useWord97LineBreakingRules/><w:dontAllowFieldEndSelect/><w:useWord2002TableStyleRules/></w:compat><w:docVars><w:docVar w:name="Agency Code" w:val=" "/><w:docVar w:name="Assigned To" w:val="None"/><w:docVar w:name="Auto-Generate" w:val="None"/><w:docVar w:name="Classification Dictionary" w:val="Unclassified"/><w:docVar w:name="Contract #" w:val=" "/><w:docVar w:name="Date" w:val="TBD"/><w:docVar w:name="Description" w:val=" "/><w:docVar w:name="Document Classification" w:val="None"/><w:docVar w:name="Document Status" w:val="Released"/><w:docVar w:name="FSC Code" w:val=" "/><w:docVar w:name="ImportedFromFile" w:val=" "/><w:docVar w:name="Left Page Foot" w:val=" "/><w:docVar w:name="Left Page Head" w:val=" "/><w:docVar w:name="MacroArg" w:val=" "/><w:docVar w:name="MacroArg1" w:val=" "/><w:docVar w:name="MacroArg2" w:val=" "/><w:docVar w:name="MacroArg3" w:val=" "/><w:docVar w:name="MacroArg4" w:val=" "/><w:docVar w:name="MacroArg5" w:val=" "/><w:docVar w:name="MacroArg6" w:val=" "/><w:docVar w:name="MacroArg7" w:val=" "/><w:docVar w:name="Manufacturer Code" w:val=" "/><w:docVar w:name="MS Word Export To" w:val=" "/><w:docVar w:name="Part Identification" w:val=" "/><w:docVar w:name="ReturnValue" w:val=" "/><w:docVar w:name="ReuseDoc" w:val="1"/><w:docVar w:name="Revision" w:val="AVNS-PRF-10844"/><w:docVar w:name="Right Page Foot" w:val=" "/><w:docVar w:name="Right Page Head" w:val=" "/><w:docVar w:name="Security Marking" w:val="Unclassified"/><w:docVar w:name="Series Label" w:val="A:"/><w:docVar w:name="Specification Number" w:val=" "/><w:docVar w:name="Style Catalog" w:val="1Level;2Level;3Level;4Level;5Level;6Level;7Level;8Level;9Level;"/><w:docVar w:name="Style Sheet ID" w:val="\\sw\mes\SE-RQMT_DB\SLATE_Templates\ExportTemplateBlockIII_PRF_LRIP.dot"/><w:docVar w:name="Subsystem Owner" w:val=" "/><w:docVar w:name="Supersedes" w:val=" "/><w:docVar w:name="Title" w:val=" "/><w:docVar w:name="Title Page" w:val="&#xA; &lt;PARA DocTitle&gt;[ sl8getValue . TITLE false false ] &#xA; &#xA;&#xA;&#xA;&#xA;&#xA;&#xA; &lt;PARA DocDate&gt; Date: [sl8getAttribute . Date ] &#xA; &lt;PARA Prepared By&gt; Author: [sl8getAttribute . {Prepared By} ] &#xA; &lt;PARA Prepared For&gt; Prepared for: [sl8getAttribute . {Prepared For} ] &#xA; &#xA;&#xA; &lt;PARA Normal&gt; &lt;BREAK SECTION&gt; &#xA; \[\$TOC:\$\] &#xA;&lt;PARA Normal&gt; &lt;BREAK&gt;&#xA; \[\$ListOfFigures:\$\] &#xA;&lt;PARA Normal&gt; &lt;BREAK&gt;&#xA; \[\$ListOfTables:\$\] &#xA;&lt;PARA Normal&gt; &lt;BREAK&gt;&#xA; "/></w:docVars><wsp:rsids><wsp:rsidRoot wsp:val="00BF241C"/><wsp:rsid wsp:val="00022832"/><wsp:rsid wsp:val="00074C93"/><wsp:rsid wsp:val="00096EFC"/><wsp:rsid wsp:val="000A7603"/><wsp:rsid wsp:val="00132F18"/><wsp:rsid wsp:val="00135E87"/><wsp:rsid wsp:val="001910EC"/><wsp:rsid wsp:val="001B2430"/><wsp:rsid wsp:val="001D271D"/><wsp:rsid wsp:val="00205EEF"/><wsp:rsid wsp:val="002136BF"/><wsp:rsid wsp:val="002273B0"/><wsp:rsid wsp:val="002662B7"/><wsp:rsid wsp:val="00302DB7"/><wsp:rsid wsp:val="003376E9"/><wsp:rsid wsp:val="00337D5E"/><wsp:rsid wsp:val="00357167"/><wsp:rsid wsp:val="00361BE0"/><wsp:rsid wsp:val="0039042B"/><wsp:rsid wsp:val="00391A93"/><wsp:rsid wsp:val="00414030"/><wsp:rsid wsp:val="00454DFC"/><wsp:rsid wsp:val="00493C76"/><wsp:rsid wsp:val="00507710"/><wsp:rsid wsp:val="005573D5"/><wsp:rsid wsp:val="00593849"/><wsp:rsid wsp:val="005A6041"/><wsp:rsid wsp:val="006524C2"/><wsp:rsid wsp:val="00672228"/><wsp:rsid wsp:val="00681E6D"/><wsp:rsid wsp:val="00690498"/><wsp:rsid wsp:val="006A5D9A"/><wsp:rsid wsp:val="006E6156"/><wsp:rsid wsp:val="006F0805"/><wsp:rsid wsp:val="00730380"/><wsp:rsid wsp:val="00757E56"/><wsp:rsid wsp:val="007822E0"/><wsp:rsid wsp:val="00856929"/><wsp:rsid wsp:val="00864C5A"/><wsp:rsid wsp:val="00895A5D"/><wsp:rsid wsp:val="008A2A6F"/><wsp:rsid wsp:val="008C33E2"/><wsp:rsid wsp:val="009703F8"/><wsp:rsid wsp:val="009F4258"/><wsp:rsid wsp:val="00A86EC4"/><wsp:rsid wsp:val="00AE0151"/><wsp:rsid wsp:val="00AE30F8"/><wsp:rsid wsp:val="00AE6046"/><wsp:rsid wsp:val="00B045FC"/><wsp:rsid wsp:val="00B04F53"/><wsp:rsid wsp:val="00B5221E"/><wsp:rsid wsp:val="00B9210B"/><wsp:rsid wsp:val="00BC2CF0"/><wsp:rsid wsp:val="00BE60C1"/><wsp:rsid wsp:val="00BF241C"/><wsp:rsid wsp:val="00C3594C"/><wsp:rsid wsp:val="00C67E7B"/><wsp:rsid wsp:val="00D20CA9"/><wsp:rsid wsp:val="00D2648D"/><wsp:rsid wsp:val="00D5100D"/><wsp:rsid wsp:val="00D735A0"/><wsp:rsid wsp:val="00DB2340"/><wsp:rsid wsp:val="00DC79EA"/><wsp:rsid wsp:val="00DD78E2"/><wsp:rsid wsp:val="00E0512A"/><wsp:rsid wsp:val="00E0600B"/><wsp:rsid wsp:val="00E92161"/><wsp:rsid wsp:val="00FA3F8D"/><wsp:rsid wsp:val="00FC1D2F"/></wsp:rsids></w:docPr><w:body><wx:sect><aml:annotation aml:id="0" w:type="Word.Bookmark.Start" w:name="_Toc257290251"/><wx:sub-section><w:p wsp:rsidR="00BF241C" wsp:rsidRDefault="00BF241C" wsp:rsidP="00BF241C"><w:pPr><w:pStyle w:val="Heading1"/><w:listPr><wx:t wx:val="1.0 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Test test</w:t></w:r><aml:annotation aml:id="0" w:type="Word.Bookmark.End"/></w:p><aml:annotation aml:id="1" w:type="Word.Bookmark.Start" w:name="_Toc257290252"/><wx:sub-section><w:p wsp:rsidR="00BF241C" wsp:rsidRDefault="00BF241C" wsp:rsidP="00BF241C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="1.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Test test</w:t></w:r><aml:annotation aml:id="1" w:type="Word.Bookmark.End"/></w:p><w:p wsp:rsidR="00BF241C" wsp:rsidRDefault="00E0512A" wsp:rsidP="00414030"><w:pPr><w:rPr><w:sz-cs w:val="22"/></w:rPr></w:pPr><w:r><w:rPr><w:sz-cs w:val="22"/></w:rPr><w:t>2</w:t></w:r><w:r wsp:rsidR="00B5221E"><w:rPr><w:sz-cs w:val="22"/></w:rPr><w:t>.0</w:t></w:r><w:r wsp:rsidR="00E92161"><w:rPr><w:sz-cs w:val="22"/></w:rPr><w:t> Meters and 5.4 Meters</w:t></w:r></w:p><aml:annotation aml:id="2" w:type="Word.Bookmark.Start" w:name="_Toc257290255"/></wx:sub-section></wx:sub-section><wx:sub-section><w:p wsp:rsidR="00BF241C" wsp:rsidRDefault="00BF241C" wsp:rsidP="00BF241C"><w:pPr><w:pStyle w:val="Heading1"/><w:listPr><wx:t wx:val="2.0 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Test test</w:t></w:r><aml:annotation aml:id="2" w:type="Word.Bookmark.End"/></w:p><aml:annotation aml:id="3" w:type="Word.Bookmark.Start" w:name="_Toc257290256"/><wx:sub-section><w:p wsp:rsidR="00BF241C" wsp:rsidRDefault="00BF241C" wsp:rsidP="00BF241C"><w:pPr><w:pStyle w:val="Heading2"/><w:listPr><wx:t wx:val="2.1 "/><wx:font wx:val="Times New Roman"/></w:listPr></w:pPr><w:r><w:t>Test test</w:t></w:r><aml:annotation aml:id="3" w:type="Word.Bookmark.End"/></w:p><w:p wsp:rsidR="00BF241C" wsp:rsidRDefault="00BF241C" wsp:rsidP="00414030"><w:pPr><w:rPr><w:sz-cs w:val="22"/></w:rPr></w:pPr><w:r><w:rPr><w:sz-cs w:val="22"/></w:rPr><w:t>Test test</w:t></w:r></w:p><w:sectPr wsp:rsidR="00BF241C" wsp:rsidSect="00672228"><w:hdr w:type="even"><w:p wsp:rsidR="001910EC" wsp:rsidRDefault="002662B7" wsp:rsidP="002136BF"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:r><w:rPr><w:noProof/></w:rPr><w:pict><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"/><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"/><v:f eqn="sum @0 1 0"/><v:f eqn="sum 0 0 @1"/><v:f eqn="prod @2 1 2"/><v:f eqn="prod @3 21600 pixelWidth"/><v:f eqn="prod @3 21600 pixelHeight"/><v:f eqn="sum @0 0 1"/><v:f eqn="prod @6 1 2"/><v:f eqn="prod @7 21600 pixelWidth"/><v:f eqn="sum @8 21600 0"/><v:f eqn="prod @7 21600 pixelHeight"/><v:f eqn="sum @10 21600 0"/></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/><o:lock v:ext="edit" aspectratio="t"/></v:shapetype><w:binData w:name="wordml://08000001.wmz">H4sIAAAAAAACC83Zf1hUVRoH8PNekACNiIgmwmEYB5cUhmFEZXmsB8mINYJxBvkxwwzDiAhKrGts
+EY+RoamRqRESEioiS4pIaGauy5qxLktEpkhGLpGRa0amZGVmBPs9h2vRH+7+sT6r8zwf751z7z3n
+Pe95z+iMH77XWsnEyyhNd7KIs9AkYm6MOalvY8yFdbjxNv7nRJfb2No7kh+JeYDEfcRCPxs5MpZ7
+x0gv/Cjej7wV545xjN3uwX5+PRXF2MOpjKkefCSG38GfWYp2J/br1xUvxi4oGDuCcw/69bWsCU6s
+zN+Z+eAc3TPcxtzBc9Q9bvL7GZiH4k7GAuV7EcoyL/mcd2uExTRyvmt4eHj0OOvlcZ2jmFciy2GP
+svnsMaZi8Tg+gaOR/R5tGSyP3Zyvj0LddPw4Vrxr1PnoRt4/5MNnJkkuTmOcx0hOzqsKMRnkxVV+
+blie9+g5s2vMeWqIm87wbqOOTbmTXV0m5yNe7OJeScePcfGv6fxwzHycie4DR+VeIZ/jJSWK8X6p
+Gw3Y5PPy3auixqatiuLXHpbb4vg4o+Z6dZ0NOFfhCT4OCowFgR+f86zfPSDxusLDQUjIm3g4QK7L
+AODBOUbFppHhdf+oYX4+532lQ4R8HiG3R/x8A7G2a6zL1RxIo87HIP/JvGbReBkBTJRj5HvnKbTr
+Pc/agnwVizv9L+c6q1pzs1VluR0qR+6QSperC+CGFjlgkjp7UZp62qK1gvOiQ0LnwotC9ULNBC5v
+YdKEGQtXC+4LDwjdOeeEOsjPUWq46ByDxhN6s4s1DVCYvVcTCz7ZZzTLFigC/aA/SxG4H1ZCYtbs
+QDUMzJ8deBDWQBBcypwdeBhKMxWBdtDC4DxFYDtkzTujCQcJjjrOaDY79mpyIdJRrDmRUayphSUZ
+Bk0UeGQoNT12pabefm5CAcTYD0zwhr701ROaoCg9aUIc+KZfVK+wHVIbbWvVKluausQ6SZ1ivRww
+0VoW0JLmCFifpguwpQ2prlg6VG2WSlW5ZZoq09Lpzyx5/kfM7v5V5m7lQnMdRCsjzJ5KF3PveBdz
+4fiu1FjwgdN+Xal7/GpSl0E8+EH/PTWpiaCGAd+a1IOwxrcr9dLdXamHofRuF7MdBhUR5grIUiw0
+h4OkqDIfvavKHHnXEbPrXcxywkdv4et9tTZuQW0E/rJXlo2qzZmjymrm6NoMGlVjavkcH2/DfE94
+y/XO94TTNfbJNvyxBTUYiRp8+tabb5/wz+ytuLBJjjEPMc5Fe8Gd3vYKhcrWrjhvHQT73c3WUjgs
+lFgvQZBvidUMa+Cgb4p1ANT3pFgTYeU9JdZ+iPdrti6DPX7nrT7jVbZYwWgrhIbxK2CfzVN51hat
+9E3PV8ZBUXqd0JTerexLd/fnvO0z/GOgwJ4n1Ns7/aMynFUnMqapXB3ZqkjIdVSqjoI0r0MVDlnz
+hlTtMDhPF6DN1AXYoRQOwyUImu8IMMPAfJ2gztIFJMLKrCFVP/gt6FDFw7IFlao9C7JVp8Ene5oQ
+m+2sKszu9Ocasqshz78XPHNmgLt/dE63MjqnTpmfkw/773FexPN5I+vQF2t7An+Zx2DwL8bdfHXY
+gEYFYvwAMU5FjN24WIt2XYBm7sTJiVn1Wntmy6Rma4G23FKvzbT0gEeo3hIFS0KZpRZOgKuOO2KO
+hFzYDEfRJoUxS7igt2RBRVimpT2s3DIotFm0+isQnGbX29JK9euhJe3glBW2gSn7bOpw3/TE8Dgo
+Sl8pNKXvD+9L7w/3tvtN5WLs8UKBfdpvjbbOiGZrNeQJJdYZ4C6kWLuncxOtdcK3afnTW2B9WvR0
+GwSnecLpqRHm01NdzHuErtRlU/HZOHUx3J/qJ4xL7Q8/mdIfvj1lP6wMfxxmpSSCOtwrZWCKV8rB
+KaeS14B5SmNyEFzSNyYfFpYml4IdtDAYtjS5IqwRlia3C7PRpoAzSVo9tzfJri8GAyiTSoVzc0v1
+B2A1JIEGDiWW6tdCGkyCy6ZSfavJri8DB+hMWv2QUavvMA6GVUK2sT1sGjgbK8I651SEVc/JCsub
+Ex42A9znSEK34aiOqzNs1uUbcoVoQ6TgaXAVehNqQ7mGhKjQwgQP6NHGJtRDAXhrfRL6QnwSmqAI
+4sAX9gX7JKwAY3BsggrOT45NKJlcmJACLZMaEtYLvQk2CJ7kaci8N9/Aa/FG7uEW7A8T/oF+AZtm
+ydibbw+fgrcRoxExDqAxAzGGoe3xicqklkllpomTHaYUQWcqgWZQBQ8ZjbAC9sHZYJ3JN0RnioOi
+EIepKaTM1Ce0mry13GVTjDApsUCbBmsT64VDcDGxR6uZ26NNmusRegDOgTKpR2uAYtgLZ5LqBUVy
+gTA72VvbmNwXwp1KboKiEK+UuJBZKb7A7q0y8/hv5Lq/74JvHbhpHT4bj9+E686/UBxBjM0IqBAx
+vjV25Htj77TaWEdkiVVxf6ZFed/s5JRZOlP9Q+fm2h9uNbVGxsXw6zcyr/zvwocQaBJurHS/+fIa
+DA8ixgcR40wEtcp95LtaWWTF7KqZ3YbVM1pN/PxG5jDVdeTv6wrEVnAT5jAWUlxH8sjzt8B95Ht8
+8ANVM9WPdBjzDd2GoLjc37WaVA86G/XRFbOLYqJiy6O7DXvv80koi+T33cj8XsDaB2FvLcGDIW43
+594/j7giXEZ+o/Jzk/d+gi6yeo7hvjNJukjf9CWxmx1FMQvNMyKK0uOnNlu1en79/5XX0b9ZecjX
+mfy7lrf8+4cTufI5sbG8Q3E2TpruZJT4NS0pxJr8KEnybzPN4i6SJLXpycfy5z967d+O+PMhNHKU
+iOR+vhke/cuY+F0s59H5j6ni5z+hMv7+0Yy8a/RDIjI3PrrEv0zq3ceK9R/5BcckTXNSMRfxG6BS
+ZOCK9MuvOyM9SDzbbFCiX7U6sSGeJ6enWAI7QsuYWnqF3SFVMS9pM7tdqmae0lZ2m1QjeEjb4FVk
+ajtzl3YIblK9bKfgKjUIt0i7mIvUKIyRXhOcZU4gSU0CSbsxo91smPawIfiJXmeD8CPtZZfpDXYJ
+vpN9C9/QPnYRvoYBuABfwTn4EvpxzxdwFj6HM3AafX0GfbJP0f8p+ATjfQw98E/azU7CR9TEuuFD
+eo2dgA+gC45TI+uEY7SLHYX3aSd7j+pZB+1g79J21kavsn9QHWulWnaYtrG/UQ1roa3sEFWzt2gL
+O0ib2F/pFfYXqmQHqAJeZn+mcihj++kl9iaVwnq2j9bBWngB1rA36HkogedgNTwrWwHLoRj3PQ1F
+8BT6WAqF6LMAnkD/j8MfMV4+/EH4Cy1mzcTX+2ql/LrWnOVKEfvq59Yx4jiAOuLH39Dw8H+utqv1
+1Sjqay7LQR4LkKsnWTvia0ec7yDedxA314Y5tKH+2ugZKIblyOcKeFa2Em2roQT3Pw9r0Mda9LdO
+6EDuOuhFrMmLmNdLUIY12oC12oA1Kxc6kfPjyD3XRRuxthuxxpXCh1ibk1SFetjEemkzamMzamQL
+6oWrRv1Uo462op62oq5qUF81qLMa1FsN6q4G9VeDOtzGzsPXOOcuwjfwLZ75Di6hj+/hMvr8Af1f
+gR8xHjeIsX9CDNwQ4uGGgUkboQL75GUox57ZAKuw13g+r67X/7ZCccRXqJbVsC10HBGfxsyOIcOf
+oWpPo2r/BWdQMZ/DWVTPF9APXwoH6Bx8JTuPtgswIDTT13ARz3+Dvr4V3qLvsCu+Y2/TJeyQ77FT
+vseO+QkrN4RVG8aqMToKx4iETpLoOHSRk/ABOQsn6C7qIB96h+4Eb6GN7gAv4R90u9BKnsLf6TY6
+DH8jD2qBt+lWuIX2w5vkIuyjMfQG+t4Lr2Msbg/G3g1NAtFr0Ij4GhHrLsS8C7E30CD8yHbSFfgB
+Lgv1mFs95lmP+dZj7vXIxU6oRz64HWjbDq/iOleHe7k/QS2e5bZBDWyFatgCm6AKXoFK2AgVeOZl
+KIcN6KsMXkLfXCnGehHWY+x1sBbr8gLWZw08j/XiSrB23HNYx9WyVVhbbiXWmXsWa8+tQC0sR00s
+R20Uo0aKUSvF9Cl7hk7BJ9ALH0MPnISPhGLqhg/hAzzbBcfQ11HhWXofjmCcdozNa/H6VHeW+PwJ
+Y83I5jFk6Dgy1CVsQBQb6AR0I1sfyU7CP9HWAx9DL+79BM+dEiowS24j9QmVmPkrUIUscJtgM7Ky
+BaqRoRrYBrV4/yeok72K+7jteJbbgT53on+uAeM1YNxdGL8RcTRSG3YWj//6ZMRHZMSNjSMHjcde
+CaW/0mTaQfG0gWy0jRZTBflTMvHr12fEcWJEZ6akRTSTSigII/Dz69O7r+h9LIulKHqSXqLnMEI+
+ZdFGmkMv0gOUSymUQbPoeQqhYsyY33d9M7mS/Ggdcrgdx2MYqw8jHsBnUCc+R9qxD/n1/zbi1X8v
+jvw/7r8BaKOikloeAAA=
+</w:binData><v:shape id="_x0000_s2060" type="#_x0000_t75" style="position:absolute;left:0;text-align:left;margin-left:8.55pt;margin-top:-79.55pt;width:476.9pt;height:660.3pt;z-index:1;visibility:visible;mso-wrap-edited:f;mso-position-horizontal-relative:margin;mso-position-vertical-relative:margin"><v:imagedata src="wordml://08000001.wmz" o:title="" gain="19661f" blacklevel="22938f"/><w10:wrap anchorx="margin" anchory="margin"/></v:shape><o:OLEObject Type="Embed" ProgID="Word.Picture.8" ShapeID="_x0000_s2060" DrawAspect="Content" ObjectID="_1340619037"/></w:pict></w:r><w:fldSimple w:instr=" DOCPROPERTY Revision \* MERGEFORMAT "><w:r wsp:rsidR="001910EC" wsp:rsidRPr="00672228"><w:rPr><w:b/><w:b-cs/></w:rPr><w:t>Test test</w:t></w:r></w:fldSimple></w:p><w:p wsp:rsidR="001910EC" wsp:rsidRPr="002136BF" wsp:rsidRDefault="002662B7" wsp:rsidP="002136BF"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:fldSimple w:instr=" DOCPROPERTY Date \* MERGEFORMAT "><w:r wsp:rsidR="001910EC" wsp:rsidRPr="00672228"><w:rPr><w:b/><w:b-cs/></w:rPr><w:t>Test test</w:t></w:r></w:fldSimple></w:p></w:hdr><w:hdr w:type="odd"><w:p wsp:rsidR="001910EC" wsp:rsidRDefault="002662B7" wsp:rsidP="002136BF"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:r><w:rPr><w:noProof/></w:rPr><w:pict><v:shapetype id="_x0000_t75" coordsize="21600,21600" o:spt="75" o:preferrelative="t" path="m@4@5l@4@11@9@11@9@5xe" filled="f" stroked="f"><v:stroke joinstyle="miter"/><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"/><v:f eqn="sum @0 1 0"/><v:f eqn="sum 0 0 @1"/><v:f eqn="prod @2 1 2"/><v:f eqn="prod @3 21600 pixelWidth"/><v:f eqn="prod @3 21600 pixelHeight"/><v:f eqn="sum @0 0 1"/><v:f eqn="prod @6 1 2"/><v:f eqn="prod @7 21600 pixelWidth"/><v:f eqn="sum @8 21600 0"/><v:f eqn="prod @7 21600 pixelHeight"/><v:f eqn="sum @10 21600 0"/></v:formulas><v:path o:extrusionok="f" gradientshapeok="t" o:connecttype="rect"/><o:lock v:ext="edit" aspectratio="t"/></v:shapetype><v:shape id="_x0000_s2061" type="#_x0000_t75" style="position:absolute;left:0;text-align:left;margin-left:-15.45pt;margin-top:-67.55pt;width:476.9pt;height:660.3pt;z-index:2;visibility:visible;mso-wrap-edited:f;mso-position-horizontal-relative:margin;mso-position-vertical-relative:margin"><v:imagedata src="wordml://08000001.wmz" o:title="" gain="19661f" blacklevel="22938f"/><w10:wrap anchorx="margin" anchory="margin"/></v:shape><o:OLEObject Type="Embed" ProgID="Word.Picture.8" ShapeID="_x0000_s2061" DrawAspect="Content" ObjectID="_1340619038"/></w:pict></w:r><w:fldSimple w:instr=" DOCPROPERTY Revision \* MERGEFORMAT "><w:r wsp:rsidR="001910EC" wsp:rsidRPr="00672228"><w:rPr><w:b/><w:b-cs/></w:rPr><w:t>Test test</w:t></w:r></w:fldSimple></w:p><w:p wsp:rsidR="001910EC" wsp:rsidRPr="002136BF" wsp:rsidRDefault="002662B7" wsp:rsidP="002136BF"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:fldSimple w:instr=" DOCPROPERTY Date \* MERGEFORMAT "><w:r wsp:rsidR="001910EC" wsp:rsidRPr="00672228"><w:rPr><w:b/><w:b-cs/></w:rPr><w:t>Test test</w:t></w:r></w:fldSimple></w:p><w:p wsp:rsidR="001910EC" wsp:rsidRPr="002136BF" wsp:rsidRDefault="001910EC" wsp:rsidP="002136BF"><w:pPr><w:pStyle w:val="Header"/></w:pPr></w:p></w:hdr><w:ftr w:type="even"><w:p wsp:rsidR="001910EC" wsp:rsidRDefault="001910EC" wsp:rsidP="00864C5A"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:r><w:t>Test test</w:t></w:r><w:r wsp:rsidR="002662B7"><w:fldChar w:fldCharType="begin"/></w:r><w:r><w:instrText>PAGE</w:instrText></w:r><w:r wsp:rsidR="002662B7"><w:fldChar w:fldCharType="separate"/></w:r><w:r wsp:rsidR="00C67E7B"><w:rPr><w:noProof/></w:rPr><w:t>18</w:t></w:r><w:r wsp:rsidR="002662B7"><w:fldChar w:fldCharType="end"/></w:r><w:r><w:t>Test test</w:t></w:r></w:p></w:ftr><w:ftr w:type="odd"><w:p wsp:rsidR="001910EC" wsp:rsidRDefault="002662B7" wsp:rsidP="00414030"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:r><w:fldChar w:fldCharType="begin"/></w:r><w:r wsp:rsidR="001910EC"><w:instrText>PAGE</w:instrText></w:r><w:r><w:fldChar w:fldCharType="separate"/></w:r><w:r wsp:rsidR="00C67E7B"><w:rPr><w:noProof/></w:rPr><w:t>1</w:t></w:r><w:r><w:fldChar w:fldCharType="end"/></w:r></w:p></w:ftr><w:hdr w:type="first"><w:p wsp:rsidR="001910EC" wsp:rsidRDefault="001910EC" wsp:rsidP="00864C5A"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:r><w:t>Test test</w:t></w:r></w:p><w:p wsp:rsidR="001910EC" wsp:rsidRPr="002F38E4" wsp:rsidRDefault="001910EC" wsp:rsidP="00864C5A"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:r><w:t>Test test</w:t></w:r></w:p><w:p wsp:rsidR="001910EC" wsp:rsidRPr="00690498" wsp:rsidRDefault="001910EC" wsp:rsidP="00414030"><w:pPr><w:pStyle w:val="Header"/></w:pPr><w:r><w:t>Test test</w:t></w:r></w:p></w:hdr><w:pgSz w:w="12240" w:h="15840" w:code="1"/><w:pgMar w:top="1685" w:right="1080" w:bottom="1195" w:left="1800" w:header="720" w:footer="720" w:gutter="0"/><w:pgNumType w:start="1"/><w:cols w:space="720"/></w:sectPr></wx:sub-section></wx:sub-section></wx:sect></w:body></w:wordDocument> \ No newline at end of file
diff --git a/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/tableOfContentsHyperlinkTest.xml b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/tableOfContentsHyperlinkTest.xml
new file mode 100644
index 00000000000..ce5a4fcb9be
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core.test/src/org/eclipse/osee/framework/skynet/core/test/importing/parsers/tableOfContentsHyperlinkTest.xml
@@ -0,0 +1,73 @@
+<w:p wsp:rsidR="00BF241C" wsp:rsidRDefault="00FA3583">
+ <w:pPr>
+ <w:pStyle w:val="TOC2"/>
+ <w:tabs>
+ <w:tab w:val="right" w:leader="dot" w:pos="9350"/>
+ </w:tabs>
+ <w:rPr>
+ <w:noProof/>
+ <w:sz w:val="24"/>
+ <w:sz-cs w:val="24"/>
+ </w:rPr>
+ </w:pPr>
+ <w:hlink w:bookmark="_s7290252">
+ <w:r wsp:rsidR="00BF241C" wsp:rsidRPr="00373B6F">
+ <w:rPr>
+ <w:rStyle w:val="Hyperlink"/>
+ <w:noProof/>
+ </w:rPr>
+ <w:t>1.1 Identification</w:t>
+ </w:r>
+ <w:r wsp:rsidR="00BF241C">
+ <w:rPr>
+ <w:noProof/>
+ <w:webHidden/>
+ </w:rPr>
+ <w:tab wx:wTab="105" wx:tlc="dot" wx:cTlc="1"/>
+ </w:r>
+ <w:r>
+ <w:rPr>
+ <w:noProof/>
+ <w:webHidden/>
+ </w:rPr>
+ <w:fldChar w:fldCharType="begin">
+ <w:fldData>CNDJ6nn5us4RjIIAqgBLqQsCAAAACAAAAA4AAABfAFQAbwBjADIANQA3ADIAOQAwADIANQAyAAAA
+</w:fldData>
+ </w:fldChar>
+ </w:r>
+ <w:r wsp:rsidR="00BF241C">
+ <w:rPr>
+ <w:noProof/>
+ <w:webHidden/>
+ </w:rPr>
+ <w:instrText> PAGEREF _Toc257290252 \h </w:instrText>
+ </w:r>
+ <w:r wsp:rsidR="00D10692">
+ <w:rPr>
+ <w:noProof/>
+ </w:rPr>
+ </w:r>
+ <w:r>
+ <w:rPr>
+ <w:noProof/>
+ <w:webHidden/>
+ </w:rPr>
+ <w:fldChar w:fldCharType="separate"/>
+ </w:r>
+ <w:r wsp:rsidR="00AE30F8">
+ <w:rPr>
+ <w:noProof/>
+ <w:webHidden/>
+ </w:rPr>
+ <w:t>1</w:t>
+ </w:r>
+ <w:r>
+ <w:rPr>
+ <w:noProof/>
+ <w:webHidden/>
+ </w:rPr>
+ <w:fldChar w:fldCharType="end"/>
+ </w:r>
+ </w:hlink>
+</w:p>
+
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/OutlineResolution.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/OutlineResolution.java
new file mode 100644
index 00000000000..9eb77013d99
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/OutlineResolution.java
@@ -0,0 +1,107 @@
+/*******************************************************************************
+ * Copyright (c) 2004, 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.skynet.core.importing.parsers;
+
+import org.eclipse.osee.framework.jdk.core.util.Strings;
+
+public final class OutlineResolution {
+
+ private static final String OUTLINE_NUMBER_DELIMITER = "\\.";
+
+ public final boolean isInvalidOutlineNumber(String currentOutlineNumber, String lastOutlineNumber) {
+ if (Strings.isValid(currentOutlineNumber) && Strings.isValid(lastOutlineNumber) && (currentOutlineNumber.length() >= 1) && (lastOutlineNumber.length() >= 1)) {
+
+ String[] lastOutlineNumberArray = lastOutlineNumber.split(OUTLINE_NUMBER_DELIMITER);
+ String[] currentOutlineNumberArray = currentOutlineNumber.split(OUTLINE_NUMBER_DELIMITER);
+
+ int minLength = currentOutlineNumberArray.length;
+ if (minLength > lastOutlineNumberArray.length) {
+ minLength = lastOutlineNumberArray.length;
+ }
+
+ //should I show GUI to resolve conflict?
+ return decideNextPossibleOutlineNumber(currentOutlineNumberArray, lastOutlineNumberArray, minLength) ? false : true;
+
+ } else {
+ return false;
+ }
+ }
+
+ /**
+ * Determines if the incoming number follows a logical next based on the previous outline number found.
+ */
+ private boolean decideNextPossibleOutlineNumber(String[] currentOutlineNumberArray, String[] lastOutlineNumberArray, int minLength) {
+ boolean detectedAtLeastOnePositive = false; // set to true moment a delta of 1 is found.
+ boolean finalDecisionIfNumberFollowsPattern = false; // decision that gets returned to calling method, whether the paragraph follows the right pattern
+ int zeroDeltaCounter = 0; // counts amount of time delta is 0
+ for (int nextNumberIndex = 0; nextNumberIndex < minLength; nextNumberIndex++) {
+ int currentDigit = extractDigitsSafely(currentOutlineNumberArray[nextNumberIndex]);
+ int lastDigit = extractDigitsSafely(lastOutlineNumberArray[nextNumberIndex]);
+
+ int delta = currentDigit - lastDigit;
+
+ if (delta == 1) {
+ if (detectedAtLeastOnePositive) {
+ detectedAtLeastOnePositive = false;
+ break;
+ } else {
+ detectedAtLeastOnePositive = true;
+ }
+ } else if (delta == 0) {
+ //made to track difference between previous and next is 0
+ //i.e. last=2.1.1.1 current=2.1.1.1.1
+ zeroDeltaCounter++;
+ } else if (delta < 0) {
+ //negative delta, therefore number
+ //does not follow pattern
+ //invalidate previous findings.
+ if (currentDigit == 0) {
+ //current if zero will disqualify a valid outline number
+ //example: last: 3.1 current: 4.0
+ break;
+ } else {
+ detectedAtLeastOnePositive = false;
+ break;
+ }
+ }
+
+ //check for last=2.1.1.1 current=2.1.1.1.1, indented paragraphs
+ if ((nextNumberIndex == minLength - 1) && (zeroDeltaCounter == minLength) && (currentOutlineNumberArray.length > lastOutlineNumberArray.length)) {
+ if (Strings.isValid(currentOutlineNumberArray[currentOutlineNumberArray.length - 1])) {
+ if (currentOutlineNumberArray[currentOutlineNumberArray.length - 1].compareTo("1") == 0) {
+ detectedAtLeastOnePositive = true;
+ } else {
+ detectedAtLeastOnePositive = false;
+ }
+ break;
+ }
+ }
+ }
+
+ if (detectedAtLeastOnePositive) {
+ finalDecisionIfNumberFollowsPattern = true;
+ }
+
+ return finalDecisionIfNumberFollowsPattern;
+ }
+
+ private int extractDigitsSafely(String stringContainingDigit) {
+ int returnValue = -1;
+ try {
+ returnValue = Integer.parseInt(stringContainingDigit);
+ } catch (NumberFormatException ex) {
+ //apparently what was passed in is not a valid number
+ //System.out.println("OutlineResolution.java: Last string had an invalid digit. Ignoring...");
+ returnValue = -1;
+ }
+ return returnValue;
+ }
+}
diff --git a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/WordOutlineExtractorDelegate.java b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/WordOutlineExtractorDelegate.java
index 83a73860017..8e2cf313345 100644
--- a/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/WordOutlineExtractorDelegate.java
+++ b/plugins/org.eclipse.osee.framework.skynet.core/src/org/eclipse/osee/framework/skynet/core/importing/parsers/WordOutlineExtractorDelegate.java
@@ -10,121 +10,394 @@
*******************************************************************************/
package org.eclipse.osee.framework.skynet.core.importing.parsers;
+import java.util.ArrayList;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
+import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.DebugPlugin;
+import org.eclipse.debug.core.IStatusHandler;
import org.eclipse.osee.framework.core.enums.CoreAttributeTypes;
import org.eclipse.osee.framework.core.exception.OseeCoreException;
+import org.eclipse.osee.framework.core.exception.OseeExceptions;
import org.eclipse.osee.framework.core.exception.OseeStateException;
+import org.eclipse.osee.framework.jdk.core.util.Strings;
import org.eclipse.osee.framework.skynet.core.importing.RoughArtifact;
import org.eclipse.osee.framework.skynet.core.importing.RoughArtifactKind;
import org.eclipse.osee.framework.skynet.core.importing.operations.RoughArtifactCollector;
+import org.eclipse.osee.framework.skynet.core.internal.Activator;
import org.eclipse.osee.framework.skynet.core.word.WordUtil;
/**
- * @author Robert A. Fisher
+ * @author Karol M. Wilk
*/
public class WordOutlineExtractorDelegate implements IArtifactExtractorDelegate {
+ private static final String WORD_OUTLINE_PARSER_NAME = "Word Outline";
+ // Node: <w:t>1.1.1 or Text</w:t>
+ private static final Pattern WT_ELEMENT_REGEX = Pattern.compile("<w:t>(.*?)</w:t>");
+ // Node: <wx:t wx:val="1.1.1 "/>
+ private static final Pattern LIST_ITEM_REGEX = Pattern.compile("<wx:t wx:val=\"(.*?)\".*/>");
+ private static final Pattern OUTLINE_NUMBER = Pattern.compile("((?>\\d+\\.)+\\d*)\\s*");
+ private static final Pattern HYPERLINK_PATTERN = Pattern.compile("<w:hlink .*>.*?</w:hlink>", Pattern.DOTALL);
- private static final String WORD_OUTLINE_PARSER_NAME = "Word Outline";
- private static final Pattern listPrKiller =
- Pattern.compile("<((\\w+:)?listPr)(\\s+.*?)((/>)|(>(.*?)</\\1>))",
- Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);
- private Map<String, RoughArtifact> duplicateCatcher;
-
- private RoughArtifact previousNamedArtifact;
- private RoughArtifact roughArtifact;
- private StringBuilder wordFormattedContent;
- private String lastHeaderNumber;
-
- public WordOutlineExtractorDelegate() {
- super();
- }
-
- @Override
- public boolean isApplicable(IArtifactExtractor parser) {
- return parser != null && WORD_OUTLINE_PARSER_NAME.equals(parser.getName());
- }
-
- /**
- * Subclasses may extend this method to allocate resources
- */
- @Override
- public void initialize() {
- duplicateCatcher = new HashMap<String, RoughArtifact>();
- lastHeaderNumber = null;
- previousNamedArtifact = null;
- roughArtifact = null;
- wordFormattedContent = new StringBuilder();
- }
-
- /**
- * Sublcasses may extend this method to dispose resources.
- */
- @Override
- public void dispose() {
- duplicateCatcher = null;
- lastHeaderNumber = null;
- previousNamedArtifact = null;
- roughArtifact = null;
- }
-
- public final void processContent(RoughArtifactCollector collector, boolean forceBody, boolean forcePrimaryType, String headerNumber, String listIdentifier, String paragraphStyle, String content, boolean isParagraph) throws OseeCoreException {
- if (!headerNumber.equals("")) {
- lastHeaderNumber = headerNumber;
- }
-
- if (!headerNumber.equals("") && WordUtil.isHeadingStyle(paragraphStyle) && !WordUtil.textOnly(content).equals("")) {
- setContent();
- roughArtifact = setUpNewArtifact(collector, headerNumber);
- previousNamedArtifact = roughArtifact;
- processHeadingText(roughArtifact, WordUtil.textOnly(content));
- } else if (!listIdentifier.equals("") && !forceBody) {
- String proNumber = lastHeaderNumber + "." + listIdentifier;
- content = listPrKiller.matcher(content).replaceAll("");
- wordFormattedContent.append(content);
- roughArtifact.addAttribute("Name", proNumber);
- } else if (roughArtifact != null) {
- wordFormattedContent.append(content);
- }
- }
-
- private void setContent() {
- if (roughArtifact != null) {
- roughArtifact.addAttribute(CoreAttributeTypes.WORD_TEMPLATE_CONTENT, wordFormattedContent.toString());
- wordFormattedContent.setLength(0);
- }
- }
-
- public void finish() {
- setContent();
- }
-
- public void processHeadingText(RoughArtifact roughArtifact, String headingText) {
- roughArtifact.addAttribute("Name", headingText.trim());
- }
-
- private RoughArtifact setUpNewArtifact(RoughArtifactCollector collector, String parNumber) throws OseeCoreException {
- RoughArtifact duplicateArtifact = duplicateCatcher.get(parNumber);
- if (duplicateArtifact == null) {
- RoughArtifact roughArtifact = new RoughArtifact(RoughArtifactKind.PRIMARY);
- duplicateCatcher.put(parNumber, roughArtifact);
-
- collector.addRoughArtifact(roughArtifact);
- roughArtifact.setSectionNumber(parNumber);
-
- roughArtifact.addAttribute(CoreAttributeTypes.PARAGRAPH_NUMBER, parNumber);
-
- return roughArtifact;
- } else {
- throw new OseeStateException(String.format(
- "Paragraph %s found more than once following \"%s\" which is a duplicate of %s", parNumber,
- previousNamedArtifact.getName(), duplicateArtifact.getName()));
- }
- }
-
- @Override
- public String getName() {
- return "General Outline Documents";
- }
+ public enum ContentType {
+ CONTENT,
+ OUTLINE_TITLE
+ };
+ /**
+ * Keeps state whether on what user decided last
+ */
+ private ContentType lastDeterminedContentType = ContentType.OUTLINE_TITLE;
+ /**
+ * Keeps state whether user was asked for help.
+ */
+ private boolean userAskedForHelp = false;
+
+ private Map<String, RoughArtifact> duplicateCatcher;
+
+ private RoughArtifact previousNamedArtifact;
+ private RoughArtifact roughArtifact;
+ private StringBuilder wordFormattedContent;
+
+ private StringBuffer lastHeaderNumber;
+ private StringBuffer lastHeaderName;
+ private StringBuffer lastContent;
+
+ private boolean initalized = false;
+
+ private final OutlineResolution outlineResolution = new OutlineResolution();
+ private IConflictResolvingGui conflictResolvingGui = null;
+
+ public WordOutlineExtractorDelegate() {
+ this(new IConflictResolvingGui() {
+ @Override
+ public ContentType determineContentType(Collection<String> paramList) throws OseeCoreException {
+ Status status = new Status(IStatus.WARNING, Activator.PLUGIN_ID, 258, "", null);
+ IStatusHandler handler = DebugPlugin.getDefault().getStatusHandler(status);
+ Object object = null;
+ try {
+ object = handler.handleStatus(status, paramList);
+ } catch (CoreException ex) {
+ OseeExceptions.wrapAndThrow(ex);
+ }
+ return (ContentType) object;
+ }
+ });
+ }
+
+ public WordOutlineExtractorDelegate(IConflictResolvingGui gui) {
+ super();
+ this.conflictResolvingGui = gui;
+ }
+
+ public IConflictResolvingGui getOutlineResolvingUi() {
+ return conflictResolvingGui;
+ }
+
+ public interface IConflictResolvingGui {
+ ContentType determineContentType(Collection<String> paramList) throws OseeCoreException;
+ }
+
+ @Override
+ public boolean isApplicable(IArtifactExtractor parser) {
+ return parser != null && WORD_OUTLINE_PARSER_NAME.equals(parser.getName());
+ }
+
+ /**
+ * Subclasses may extend this method to allocate resources
+ */
+ @Override
+ public void initialize() {
+ duplicateCatcher = new HashMap<String, RoughArtifact>();
+ lastHeaderNumber = new StringBuffer();
+ lastHeaderName = new StringBuffer();
+ lastContent = new StringBuffer();
+ previousNamedArtifact = null;
+ roughArtifact = null;
+ wordFormattedContent = new StringBuilder();
+ initalized = true;
+
+ }
+
+ /**
+ * Sublcasses may extend this method to dispose resources.
+ */
+ @Override
+ public void dispose() {
+ duplicateCatcher = null;
+ previousNamedArtifact = null;
+ roughArtifact = null;
+ lastHeaderNumber = null;
+ lastHeaderName = null;
+ lastContent = null;
+ initalized = false;
+ }
+
+ @Override
+ public final void processContent(RoughArtifactCollector collector, boolean forceBody,
+ boolean forcePrimaryType, String headerNumber, String listIdentifier,
+ String paragraphStyle, String content, boolean isParagraph) throws OseeCoreException {
+
+ if (Strings.isValid(content) && initalized && !HYPERLINK_PATTERN.matcher(content).find()) {
+ StringBuilder outlineNumber = new StringBuilder(); //Number i.e. 1.1
+ StringBuilder outlineName = new StringBuilder(); //Title i.e. Scope
+ StringBuilder outlineContent = null; // Content, text, table content, etc.
+
+ boolean newOutlineNumber = processOutlineNumberAndName(content, outlineNumber, outlineName);
+
+ //outline number detection failed, try content
+ if (!newOutlineNumber) {
+ processContentOfParagraph(content, outlineContent);
+ }
+
+ if (collector != null && newOutlineNumber) {
+ setContent();
+ roughArtifact = setUpNewArtifact(collector, outlineNumber.toString());
+ previousNamedArtifact = roughArtifact;
+ processHeadingText(roughArtifact, WordUtil.textOnly(outlineName.toString()));
+ } else if (roughArtifact != null) {
+ wordFormattedContent.append(content);
+ }
+ } else {
+ throw new OseeCoreException(String.format(
+ "%s::processContent() Either passed in content is invalid or *Delegate hasn't been initialized...",
+ this.toString()));
+ }
+
+ }
+
+ /**
+ * Given content (a <w:p> paragraph), fill outlineContent with extracted content information from
+ * grabNameAndTemplateContent()
+ *
+ * @param content a <w:p> paragraph.
+ * @param outlineContent data structure to fill as new content gets extracted.
+ * @return if found any new content or not...
+ */
+ private boolean processContentOfParagraph(String content, StringBuilder outlineContent) {
+ outlineContent = new StringBuilder(300); //average content is larger than 16 chars
+ grabNameAndTemplateContent(content, outlineContent);
+
+ boolean newOutlineContent = false;
+ newOutlineContent = outlineContent.length() != 0;
+
+ if (newOutlineContent) {
+ resetLastContent();
+ setLastContent(outlineContent.toString());
+ }
+
+ return newOutlineContent;
+ }
+
+ /**
+ * Gets content and attempts to extract outline number and title, if it fails with regular regex, it tries
+ * specializedOutlineNumberTitleExtract()
+ *
+ * @param content
+ * @param outlineNumber
+ * @param outlineName
+ * @return
+ * @throws OseeCoreException
+ */
+ private boolean processOutlineNumberAndName(String content, StringBuilder outlineNumber, StringBuilder outlineName) throws OseeCoreException {
+ Matcher listItemMatcher = LIST_ITEM_REGEX.matcher(content);
+ if (listItemMatcher.find()) { // wx:val grab
+ //does duplicate catcher contain this number already?
+ String number = listItemMatcher.group(1).trim();
+ if (duplicateCatcher.get(number) == null) {
+ outlineNumber.append(number);
+ }
+ } else {
+ specializedOutlineNumberTitleExtract(content, outlineNumber, outlineName);
+ }
+
+ boolean outlineNumberDetected = outlineNumber.length() != 0;
+ if (outlineNumberDetected) {
+ resetLastHeaderNumber();
+ setLastHeaderNumber(outlineNumber.toString());
+ grabNameAndTemplateContent(content, outlineName);
+
+ if (outlineName.length() != 0) {
+ resetLastHeaderName();
+ setLastHeaderName(outlineName.toString());
+ }
+ }
+ return outlineNumberDetected;
+ }
+
+ /**
+ * Grabs outline text or content. Stores results in outLineStorage.
+ *
+ * @param paragraph
+ * @param outLineStorage
+ */
+ private void grabNameAndTemplateContent(String paragraph, StringBuilder outLineStorage) {
+ if (outLineStorage.length() == 0) {
+ Matcher wtElementMatcher = WT_ELEMENT_REGEX.matcher(paragraph);
+ while (wtElementMatcher.find()) {
+ Matcher checkingForOutlineNumber = OUTLINE_NUMBER.matcher(wtElementMatcher.group(1));
+ if (!checkingForOutlineNumber.matches()) {
+ outLineStorage.append(wtElementMatcher.group(1));
+ }
+ }
+ }
+ }
+
+ /**
+ * Specializes in extraction of "1. scope" type of outline number and names. Outline name can also be spread out over
+ * multiple <w:t>s
+ *
+ * @param paragraph
+ * @param outlineNumberStorage
+ * @param outlineTitleStorage
+ * @throws OseeCoreException
+ */
+ private void specializedOutlineNumberTitleExtract(String paragraph, StringBuilder outlineNumberStorage, StringBuilder outlineTitleStorage) throws OseeCoreException {
+ StringBuilder wtStorage = new StringBuilder(paragraph.length());
+ Matcher wtElementMatcher = WT_ELEMENT_REGEX.matcher(paragraph);
+ while (wtElementMatcher.find()) {
+ wtStorage.append(wtElementMatcher.group(1));
+ }
+
+ int indexOfFirstSpace = wtStorage.toString().indexOf(" ");
+ if (indexOfFirstSpace != -1) {
+ CharSequence title = wtStorage.subSequence(0, indexOfFirstSpace);
+ Matcher outlineNumberMatcher = OUTLINE_NUMBER.matcher(title);
+ if (outlineNumberMatcher.matches()) {
+ processSpecializedOutlineNumberAndTitle(outlineNumberMatcher.group(),
+ (String) wtStorage.subSequence(indexOfFirstSpace, wtStorage.length()), outlineNumberStorage,
+ outlineTitleStorage);
+ } else {
+ outlineTitleStorage = wtStorage;
+ }
+ } else {
+ //must be just content
+ outlineTitleStorage = wtStorage;
+ }
+
+ }
+
+ private void processSpecializedOutlineNumberAndTitle(String currentOutlineNumber, String formOfOutlineTitle, StringBuilder outlineNumberStorage, StringBuilder outlineTitleStorage) throws OseeCoreException {
+ String lastOutlineNumber = getLastHeaderNumber();
+
+ lastDeterminedContentType = ContentType.OUTLINE_TITLE;
+
+ if (outlineResolution.isInvalidOutlineNumber(currentOutlineNumber, lastOutlineNumber)) {
+ if (duplicateCatcher.get(currentOutlineNumber) == null) {
+ userAskedForHelp = true;
+ Collection<String> paramList = new ArrayList<String>();
+ paramList.add(lastOutlineNumber);
+ paramList.add(currentOutlineNumber);
+ lastDeterminedContentType = conflictResolvingGui.determineContentType(paramList);
+ } else {
+ lastDeterminedContentType = ContentType.CONTENT;
+ }
+ } else {
+ userAskedForHelp = false;
+ }
+
+ switch (lastDeterminedContentType) {
+ case CONTENT:
+ // do nothing because when method exits it will be processed as content
+ break;
+ case OUTLINE_TITLE:
+ default:
+ outlineNumberStorage.append(currentOutlineNumber);
+ if (Strings.isValid(formOfOutlineTitle)) {
+ outlineTitleStorage.append(formOfOutlineTitle);
+ }
+ break;
+ }
+ }
+
+ public boolean userAskedForHelp() {
+ return userAskedForHelp;
+ }
+
+ private void setContent() {
+ if (roughArtifact != null) {
+ roughArtifact.addAttribute(CoreAttributeTypes.WORD_TEMPLATE_CONTENT, wordFormattedContent.toString());
+ wordFormattedContent.setLength(0);
+ }
+ }
+
+ @Override
+ public void finish() {
+ setContent();
+ }
+
+ public void processHeadingText(RoughArtifact roughArtifact, String headingText) {
+ roughArtifact.addAttribute("Name", headingText.trim());
+ }
+
+ /**
+ * Checks if another artifact with the same outlineNumber was created
+ */
+ private RoughArtifact setUpNewArtifact(RoughArtifactCollector collector, String outlineNumber) throws OseeCoreException {
+ RoughArtifact duplicateArtifact = duplicateCatcher.get(outlineNumber);
+ if (duplicateArtifact == null) {
+ RoughArtifact roughArtifact = new RoughArtifact(RoughArtifactKind.PRIMARY);
+ duplicateCatcher.put(outlineNumber, roughArtifact);
+
+ collector.addRoughArtifact(roughArtifact);
+ roughArtifact.setSectionNumber(outlineNumber);
+
+ roughArtifact.addAttribute(CoreAttributeTypes.PARAGRAPH_NUMBER, outlineNumber);
+
+ return roughArtifact;
+ } else {
+ throw new OseeStateException(String.format(
+ "Paragraph %s found more than once following \"%s\" which is a duplicate of %s", outlineNumber,
+ previousNamedArtifact.getName(), duplicateArtifact.getName()));
+ }
+ }
+
+ @Override
+ public String getName() {
+ return "QuickSilver ICDs and General Outline Documents";
+ }
+
+ public String getLastHeaderNumber() {
+ return getBufferString(lastHeaderNumber);
+ }
+
+ private void setLastHeaderNumber(String lastHeaderNumber) {
+ this.lastHeaderNumber.append(lastHeaderNumber);
+ }
+
+ public String getLastHeaderName() {
+ return getBufferString(lastHeaderName);
+ }
+
+ private void setLastHeaderName(String lastHeaderName) {
+ this.lastHeaderName.append(lastHeaderName);
+ }
+
+ public String getLastContent() {
+ return getBufferString(lastContent);
+ }
+
+ private void setLastContent(String lastContent) {
+ this.lastContent.append(lastContent);
+ }
+
+ private String getBufferString(StringBuffer builder) {
+ return builder != null ? builder.toString() : null;
+ }
+
+ private void resetLastHeaderNumber() {
+ this.lastHeaderNumber.setLength(0);
+ }
+
+ private void resetLastHeaderName() {
+ this.lastHeaderName.setLength(0);
+ }
+
+ private void resetLastContent() {
+ this.lastContent.setLength(0);
+ }
}
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF
index 49ae98ab50a..7def5d21df8 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/META-INF/MANIFEST.MF
@@ -36,6 +36,7 @@ Bundle-ActivationPolicy: lazy
Bundle-Vendor: Eclipse Open System Engineering Environment
Import-Package: com.lowagie.text;version="2.1.7",
org.apache.commons.lang;version="2.4.0",
+ org.apache.commons.lang.mutable;version="2.4.0",
org.apache.xml.serialize;version="2.9.0",
org.eclipse.core.resources,
org.eclipse.nebula.widgets.calendarcombo,
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml b/plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml
index 208f06235a1..9fcc71caec7 100644
--- a/plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/plugin.xml
@@ -1682,6 +1682,12 @@
id="org.eclipse.osee.framework.ui.skynet.ArtifactChangeHandler"
plugin="org.eclipse.osee.framework.skynet.core">
</statusHandler>
+ <statusHandler
+ class="org.eclipse.osee.framework.ui.skynet.handler.UIOutlineResolutionHandler"
+ code="258"
+ id="org.eclipse.osee.framework.ui.skynet.handler.UIOutlineResolutionHandler"
+ plugin="org.eclipse.osee.framework.skynet.core">
+ </statusHandler>
</extension>
<extension
point="org.eclipse.osee.framework.ui.skynet.DatabaseHealthOperation">
diff --git a/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/handler/UIOutlineResolutionHandler.java b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/handler/UIOutlineResolutionHandler.java
new file mode 100644
index 00000000000..6ac36d3f65e
--- /dev/null
+++ b/plugins/org.eclipse.osee.framework.ui.skynet/src/org/eclipse/osee/framework/ui/skynet/handler/UIOutlineResolutionHandler.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright (c) 2010 Boeing.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Boeing - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osee.framework.ui.skynet.handler;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang.mutable.MutableBoolean;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.debug.core.IStatusHandler;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.osee.framework.skynet.core.importing.parsers.WordOutlineExtractorDelegate.ContentType;
+import org.eclipse.osee.framework.ui.skynet.SkynetGuiPlugin;
+import org.eclipse.osee.framework.ui.swt.Displays;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author Roberto Escobar
+ * @author Karol M. Wilk
+ */
+
+public class UIOutlineResolutionHandler implements IStatusHandler {
+
+ @Override
+ public Object handleStatus(IStatus status, Object source) throws CoreException {
+ if (source instanceof ArrayList<?>) {
+ final List<String> list = (ArrayList<String>) source;
+ // Preferences get the last should ask?
+ // Use the last preference ?
+ final MutableBoolean mutableBoolean = new MutableBoolean(false);
+ Runnable runnable = new Runnable() {
+ @Override
+ public void run() {
+ String message =
+ String.format(
+ "Previous valid outline number was \"%s\", is \"%s\" the next outline number? If not, I will treat it as content.",
+ list.get(0), list.get(1));
+ mutableBoolean.setValue(MessageDialog.openQuestion(
+ PlatformUI.getWorkbench().getDisplay().getActiveShell(), "Help me decide...", message));
+ }
+ };
+ Displays.ensureInDisplayThread(runnable, true);
+ return mutableBoolean.booleanValue() ? ContentType.OUTLINE_TITLE : ContentType.CONTENT;
+ }
+
+ throw new CoreException(new Status(IStatus.ERROR, SkynetGuiPlugin.PLUGIN_ID,
+ "Invalid source object in UIOutlineResolutionHandler"));
+ }
+}

Back to the top